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 024package microsoft.exchange.webservices.data.property.complex; 025 026import microsoft.exchange.webservices.data.attribute.EditorBrowsable; 027import microsoft.exchange.webservices.data.core.EwsServiceXmlReader; 028import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter; 029import microsoft.exchange.webservices.data.core.EwsUtilities; 030import microsoft.exchange.webservices.data.core.ICustomXmlUpdateSerializer; 031import microsoft.exchange.webservices.data.core.XmlElementNames; 032import microsoft.exchange.webservices.data.core.service.ServiceObject; 033import microsoft.exchange.webservices.data.core.enumeration.attribute.EditorBrowsableState; 034import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace; 035import microsoft.exchange.webservices.data.core.exception.misc.ArgumentException; 036import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException; 037import microsoft.exchange.webservices.data.misc.OutParam; 038import microsoft.exchange.webservices.data.property.definition.ExtendedPropertyDefinition; 039import microsoft.exchange.webservices.data.property.definition.PropertyDefinition; 040 041import javax.xml.stream.XMLStreamException; 042 043import java.util.ArrayList; 044import java.util.List; 045 046/** 047 * Represents a collection of extended property. 048 */ 049@EditorBrowsable(state = EditorBrowsableState.Never) 050public 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}