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.core.EwsServiceXmlReader;
027 import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
028 import microsoft.exchange.webservices.data.core.EwsUtilities;
029 import microsoft.exchange.webservices.data.core.XmlElementNames;
030 import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
031 import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
032 import microsoft.exchange.webservices.data.misc.MapiTypeConverter;
033 import microsoft.exchange.webservices.data.property.definition.ExtendedPropertyDefinition;
034 import org.apache.commons.lang3.StringUtils;
035
036 import javax.xml.stream.XMLStreamException;
037
038 import java.util.ArrayList;
039
040 /**
041 * Represents an extended property.
042 */
043 public 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 }