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.core.EwsServiceXmlReader; 027import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter; 028import microsoft.exchange.webservices.data.core.EwsUtilities; 029import microsoft.exchange.webservices.data.core.XmlElementNames; 030import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace; 031import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException; 032import microsoft.exchange.webservices.data.misc.MapiTypeConverter; 033import microsoft.exchange.webservices.data.property.definition.ExtendedPropertyDefinition; 034import org.apache.commons.lang3.StringUtils; 035 036import javax.xml.stream.XMLStreamException; 037 038import java.util.ArrayList; 039 040/** 041 * Represents an extended property. 042 */ 043public final class ExtendedProperty extends ComplexProperty { 044 045 /** 046 * The property definition. 047 */ 048 private ExtendedPropertyDefinition propertyDefinition; 049 050 /** 051 * The value. 052 */ 053 private Object value; 054 055 /** 056 * Initializes a new instance. 057 */ 058 protected ExtendedProperty() { 059 } 060 061 /** 062 * Initializes a new instance. 063 * 064 * @param propertyDefinition The definition of the extended property. 065 * @throws Exception the exception 066 */ 067 protected ExtendedProperty(ExtendedPropertyDefinition propertyDefinition) 068 throws Exception { 069 this(); 070 EwsUtilities.validateParam(propertyDefinition, "propertyDefinition"); 071 this.propertyDefinition = propertyDefinition; 072 } 073 074 /** 075 * Tries to read element from XML. 076 * 077 * @param reader The reader. 078 * @return true, if successful 079 * @throws Exception the exception 080 */ 081 @Override 082 public boolean tryReadElementFromXml(EwsServiceXmlReader reader) 083 throws Exception { 084 085 if (reader.getLocalName().equals(XmlElementNames.ExtendedFieldURI)) { 086 this.propertyDefinition = new ExtendedPropertyDefinition(); 087 this.propertyDefinition.loadFromXml(reader); 088 return true; 089 } else if (reader.getLocalName().equals(XmlElementNames.Value)) { 090 EwsUtilities.ewsAssert(this.getPropertyDefinition() != null, "ExtendedProperty.TryReadElementFromXml", 091 "PropertyDefintion is missing"); 092 String stringValue = reader.readElementValue(); 093 this.value = MapiTypeConverter.convertToValue(this.getPropertyDefinition().getMapiType(), stringValue); 094 return true; 095 } else if (reader.getLocalName().equals(XmlElementNames.Values)) { 096 EwsUtilities.ewsAssert(this.getPropertyDefinition() != null, "ExtendedProperty.TryReadElementFromXml", 097 "PropertyDefintion is missing"); 098 099 StringList stringList = new StringList(XmlElementNames.Value); 100 stringList.loadFromXml(reader, reader.getLocalName()); 101 this.value = MapiTypeConverter.convertToValue(this 102 .getPropertyDefinition().getMapiType(), stringList 103 .iterator()); 104 return true; 105 } else { 106 return false; 107 } 108 } 109 110 /** 111 * Writes elements to XML. 112 * 113 * @param writer the writer 114 * @throws ServiceXmlSerializationException the service xml serialization exception 115 * @throws XMLStreamException the XML stream exception 116 */ 117 @Override 118 public void writeElementsToXml(EwsServiceXmlWriter writer) 119 throws ServiceXmlSerializationException, XMLStreamException { 120 this.getPropertyDefinition().writeToXml(writer); 121 122 if (MapiTypeConverter.isArrayType(this.getPropertyDefinition() 123 .getMapiType())) { 124 ArrayList<?> array = (ArrayList<?>) this.getValue(); 125 writer 126 .writeStartElement(XmlNamespace.Types, 127 XmlElementNames.Values); 128 for (int index = 0; index < array.size(); index++) { 129 writer.writeElementValue(XmlNamespace.Types, 130 XmlElementNames.Value, MapiTypeConverter 131 .convertToString(this.getPropertyDefinition() 132 .getMapiType(), array.get(index))); 133 } 134 writer.writeEndElement(); 135 } else { 136 writer.writeElementValue(XmlNamespace.Types, XmlElementNames.Value, 137 MapiTypeConverter.convertToString(this 138 .getPropertyDefinition().getMapiType(), this 139 .getValue())); 140 } 141 } 142 143 /** 144 * Gets the definition of the extended property. 145 * 146 * @return The definition of the extended property. 147 */ 148 public ExtendedPropertyDefinition getPropertyDefinition() { 149 return this.propertyDefinition; 150 } 151 152 /** 153 * Gets the value of the extended property. 154 * 155 * @return the value 156 */ 157 public Object getValue() { 158 return this.value; 159 } 160 161 /** 162 * Sets the value of the extended property. 163 * 164 * @param val value of the extended property 165 * @throws Exception the exception 166 */ 167 public void setValue(Object val) throws Exception { 168 EwsUtilities.validateParam(val, "value"); 169 if (this.canSetFieldValue(this.value, MapiTypeConverter.changeType(this 170 .getPropertyDefinition().getMapiType(), val))) { 171 this.value = MapiTypeConverter.changeType(this 172 .getPropertyDefinition().getMapiType(), val); 173 this.changed(); 174 } 175 } 176 177 /** 178 * Gets the string value. 179 * 180 * @return String 181 */ 182 private String getStringValue() { 183 if (MapiTypeConverter.isArrayType(this.getPropertyDefinition() 184 .getMapiType())) { 185 ArrayList<?> array = (ArrayList<?>) this.getValue(); 186 if (array == null) { 187 return null; 188 } else { 189 StringBuilder sb = new StringBuilder(); 190 sb.append("["); 191 for (int index = 0; index < array.size(); index++) { 192 sb.append(MapiTypeConverter.convertToString(this 193 .getPropertyDefinition().getMapiType(), array 194 .get(index))); 195 sb.append(","); 196 } 197 sb.append("]"); 198 199 return sb.toString(); 200 } 201 } else { 202 return MapiTypeConverter.convertToString(this 203 .getPropertyDefinition().getMapiType(), this.getValue()); 204 } 205 } 206 207 /** 208 * Determines whether the specified <see cref="T:System.Object"/> is equal 209 * to the current <see cref="T:System.Object"/> true if the specified <see 210 * cref="T:System.Object"/> is equal to the current <see 211 * cref="T:System.Object"/> 212 * 213 * @param obj the obj 214 * @return boolean 215 */ 216 @Override 217 public boolean equals(final Object obj) { 218 if (obj instanceof ExtendedProperty) { 219 final ExtendedProperty other = (ExtendedProperty) obj; 220 return other.getPropertyDefinition().equals(this.getPropertyDefinition()) 221 && StringUtils.equals(this.getStringValue(), other.getStringValue()); 222 } 223 return false; 224 } 225 226 /** 227 * Serves as a hash function for a particular type. 228 * 229 * @return int 230 */ 231 @Override 232 public int hashCode() { 233 String printableName = this.getPropertyDefinition() != null ? this 234 .getPropertyDefinition().getPrintableName() : ""; 235 String stringVal = this.getStringValue(); 236 return (printableName + stringVal).hashCode(); 237 } 238}