001 /*
002 * The MIT License
003 * Copyright (c) 2012 Microsoft Corporation
004 *
005 * Permission is hereby granted, free of charge, to any person obtaining a copy
006 * of this software and associated documentation files (the "Software"), to deal
007 * in the Software without restriction, including without limitation the rights
008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009 * copies of the Software, and to permit persons to whom the Software is
010 * furnished to do so, subject to the following conditions:
011 *
012 * The above copyright notice and this permission notice shall be included in
013 * all copies or substantial portions of the Software.
014 *
015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021 * THE SOFTWARE.
022 */
023
024 package microsoft.exchange.webservices.data.property.complex;
025
026 import microsoft.exchange.webservices.data.attribute.EditorBrowsable;
027 import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
028 import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
029 import microsoft.exchange.webservices.data.core.EwsUtilities;
030 import microsoft.exchange.webservices.data.core.ICustomXmlUpdateSerializer;
031 import microsoft.exchange.webservices.data.core.XmlElementNames;
032 import microsoft.exchange.webservices.data.core.service.ServiceObject;
033 import microsoft.exchange.webservices.data.core.enumeration.attribute.EditorBrowsableState;
034 import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
035 import microsoft.exchange.webservices.data.core.exception.misc.ArgumentException;
036 import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
037 import microsoft.exchange.webservices.data.misc.OutParam;
038 import microsoft.exchange.webservices.data.property.definition.ExtendedPropertyDefinition;
039 import microsoft.exchange.webservices.data.property.definition.PropertyDefinition;
040
041 import javax.xml.stream.XMLStreamException;
042
043 import java.util.ArrayList;
044 import java.util.List;
045
046 /**
047 * Represents a collection of extended property.
048 */
049 @EditorBrowsable(state = EditorBrowsableState.Never)
050 public final class ExtendedPropertyCollection extends ComplexPropertyCollection<ExtendedProperty> implements
051 ICustomXmlUpdateSerializer {
052
053 /**
054 * Creates the complex property.
055 *
056 * @param xmlElementName Name of the XML element.
057 * @return Complex property instance.
058 */
059 @Override
060 protected ExtendedProperty createComplexProperty(String xmlElementName) {
061 // This method is unused in this class, so just return null.
062 return null;
063 }
064
065 /**
066 * Gets the name of the collection item XML element.
067 *
068 * @param complexProperty The complex property.
069 * @return XML element name.
070 */
071 @Override
072 protected String getCollectionItemXmlElementName(
073 ExtendedProperty complexProperty) {
074 // This method is unused in this class, so just return null.
075 return null;
076 }
077
078 /**
079 * Loads from XML.
080 *
081 * @param reader The reader.
082 * @param localElementName Name of the local element.
083 * @throws Exception the exception
084 */
085 @Override public void loadFromXml(EwsServiceXmlReader reader, String localElementName) throws Exception {
086 ExtendedProperty extendedProperty = new ExtendedProperty();
087 extendedProperty.loadFromXml(reader, reader.getLocalName());
088 this.internalAdd(extendedProperty);
089 }
090
091 /**
092 * Writes to XML.
093 *
094 * @param writer The writer.
095 * @param xmlElementName Name of the XML element.
096 * @throws Exception the exception
097 */
098 @Override public void writeToXml(EwsServiceXmlWriter writer, String xmlElementName)
099 throws Exception {
100 for (ExtendedProperty extendedProperty : this) {
101 extendedProperty.writeToXml(writer,
102 XmlElementNames.ExtendedProperty);
103 }
104 }
105
106 /**
107 * Gets existing or adds new extended property.
108 *
109 * @param propertyDefinition The property definition.
110 * @return ExtendedProperty.
111 * @throws Exception the exception
112 */
113 private ExtendedProperty getOrAddExtendedProperty(
114 ExtendedPropertyDefinition propertyDefinition) throws Exception {
115 ExtendedProperty extendedProperty = null;
116 OutParam<ExtendedProperty> extendedPropertyOut =
117 new OutParam<ExtendedProperty>();
118 if (!this.tryGetProperty(propertyDefinition, extendedPropertyOut)) {
119 extendedProperty = new ExtendedProperty(propertyDefinition);
120 this.internalAdd(extendedProperty);
121 } else {
122 extendedProperty = extendedPropertyOut.getParam();
123 }
124 return extendedProperty;
125 }
126
127 /**
128 * Sets an extended property.
129 *
130 * @param propertyDefinition The property definition.
131 * @param value The value.
132 * @throws Exception the exception
133 */
134 public void setExtendedProperty(ExtendedPropertyDefinition propertyDefinition, Object value)
135 throws Exception {
136 ExtendedProperty extendedProperty = this
137 .getOrAddExtendedProperty(propertyDefinition);
138 extendedProperty.setValue(value);
139 }
140
141 /**
142 * Removes a specific extended property definition from the collection.
143 *
144 * @param propertyDefinition The definition of the extended property to remove.
145 * @return True if the property matching the extended property definition
146 * was successfully removed from the collection, false otherwise.
147 * @throws Exception the exception
148 */
149 public boolean removeExtendedProperty(ExtendedPropertyDefinition propertyDefinition) throws Exception {
150 EwsUtilities.validateParam(propertyDefinition, "propertyDefinition");
151
152 ExtendedProperty extendedProperty = null;
153 OutParam<ExtendedProperty> extendedPropertyOut =
154 new OutParam<ExtendedProperty>();
155 if (this.tryGetProperty(propertyDefinition, extendedPropertyOut)) {
156 extendedProperty = extendedPropertyOut.getParam();
157 return this.internalRemove(extendedProperty);
158 } else {
159 return false;
160 }
161 }
162
163 /**
164 * Tries to get property.
165 *
166 * @param propertyDefinition The property definition.
167 * @param extendedPropertyOut The extended property.
168 * @return True of property exists in collection.
169 */
170 private boolean tryGetProperty(
171 ExtendedPropertyDefinition propertyDefinition,
172 OutParam<ExtendedProperty> extendedPropertyOut) {
173 boolean found = false;
174 extendedPropertyOut.setParam(null);
175 for (ExtendedProperty prop : this.getItems()) {
176 if (prop.getPropertyDefinition().equals(propertyDefinition)) {
177 found = true;
178 extendedPropertyOut.setParam(prop);
179 break;
180 }
181 }
182 return found;
183 }
184
185 /**
186 * Tries to get property value.
187 *
188 * @param propertyDefinition The property definition.
189 * @param propertyValueOut The property value.
190 * @return True if property exists in collection.
191 * @throws ArgumentException
192 */
193 public <T> boolean tryGetValue(Class<T> cls, ExtendedPropertyDefinition propertyDefinition,
194 OutParam<T> propertyValueOut) throws ArgumentException {
195 ExtendedProperty extendedProperty = null;
196 OutParam<ExtendedProperty> extendedPropertyOut =
197 new OutParam<ExtendedProperty>();
198 if (this.tryGetProperty(propertyDefinition, extendedPropertyOut)) {
199 extendedProperty = extendedPropertyOut.getParam();
200 if (!cls.isAssignableFrom(propertyDefinition.getType())) {
201 String errorMessage = String.format(
202 "Property definition type '%s' and type parameter '%s' aren't compatible.",
203 propertyDefinition.getType().getSimpleName(),
204 cls.getSimpleName());
205 throw new ArgumentException(errorMessage, "propertyDefinition");
206 }
207 propertyValueOut.setParam((T) extendedProperty.getValue());
208 return true;
209 } else {
210 propertyValueOut.setParam(null);
211 return false;
212 }
213 }
214
215
216 /**
217 * Writes the update to XML.
218 *
219 * @param writer The writer.
220 * @param ewsObject The ews object.
221 * @param propertyDefinition Property definition.
222 * @return True if property generated serialization.
223 * @throws Exception the exception
224 */
225 @Override
226 public boolean writeSetUpdateToXml(EwsServiceXmlWriter writer,
227 ServiceObject ewsObject, PropertyDefinition propertyDefinition)
228 throws Exception {
229 List<ExtendedProperty> propertiesToSet =
230 new ArrayList<ExtendedProperty>();
231
232 propertiesToSet.addAll(this.getAddedItems());
233 propertiesToSet.addAll(this.getModifiedItems());
234
235 for (ExtendedProperty extendedProperty : propertiesToSet) {
236 writer.writeStartElement(XmlNamespace.Types, ewsObject
237 .getSetFieldXmlElementName());
238 extendedProperty.getPropertyDefinition().writeToXml(writer);
239
240 writer.writeStartElement(XmlNamespace.Types, ewsObject
241 .getXmlElementName());
242 extendedProperty.writeToXml(writer,
243 XmlElementNames.ExtendedProperty);
244 writer.writeEndElement();
245
246 writer.writeEndElement();
247 }
248
249 for (ExtendedProperty extendedProperty : this.getRemovedItems()) {
250 writer.writeStartElement(XmlNamespace.Types, ewsObject
251 .getDeleteFieldXmlElementName());
252 extendedProperty.getPropertyDefinition().writeToXml(writer);
253 writer.writeEndElement();
254 }
255
256 return true;
257 }
258
259 /**
260 * Writes the deletion update to XML.
261 *
262 * @param writer the writer
263 * @param ewsObject the ews object
264 * @return true if property generated serialization
265 * @throws XMLStreamException the XML stream exception
266 * @throws ServiceXmlSerializationException the service xml serialization exception
267 */
268 @Override
269 public boolean writeDeleteUpdateToXml(EwsServiceXmlWriter writer,
270 ServiceObject ewsObject) throws XMLStreamException, ServiceXmlSerializationException {
271 for (ExtendedProperty extendedProperty : this.getItems()) {
272 writer.writeStartElement(XmlNamespace.Types, ewsObject
273 .getDeleteFieldXmlElementName());
274 extendedProperty.getPropertyDefinition().writeToXml(writer);
275 writer.writeEndElement();
276 }
277
278 return true;
279 }
280 }