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.definition;
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.XmlAttributeNames;
030import microsoft.exchange.webservices.data.core.XmlElementNames;
031import microsoft.exchange.webservices.data.core.enumeration.property.DefaultExtendedPropertySet;
032import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
033import microsoft.exchange.webservices.data.core.enumeration.property.MapiPropertyType;
034import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
035import microsoft.exchange.webservices.data.misc.MapiTypeConverter;
036
037import java.util.UUID;
038
039/**
040 * Represents the definition of an extended property.
041 */
042public final class ExtendedPropertyDefinition extends PropertyDefinitionBase {
043
044  /**
045   * The property set.
046   */
047  private DefaultExtendedPropertySet propertySet;
048
049  /**
050   * The property set id.
051   */
052  private UUID propertySetId;
053
054  /**
055   * The tag.
056   */
057  private Integer tag;
058
059  /**
060   * The name.
061   */
062  private String name;
063
064  /**
065   * The id.
066   */
067  private Integer id;
068
069  /**
070   * The mapi type.
071   */
072  private MapiPropertyType mapiType;
073
074  /**
075   * The Constant FieldFormat.
076   */
077  private final static String FieldFormat = "%s: %s ";
078
079  /**
080   * The Property set field name.
081   */
082  private static final String PropertySetFieldName = "PropertySet";
083
084  /**
085   * The Property set id field name.
086   */
087  private static final String PropertySetIdFieldName = "PropertySetId";
088
089  /**
090   * The Tag field name.
091   */
092  private static final String TagFieldName = "Tag";
093
094  /**
095   * The Name field name.
096   */
097  private static final String NameFieldName = "Name";
098
099  /**
100   * The Id field name.
101   */
102  private static final String IdFieldName = "Id";
103
104  /**
105   * The Mapi type field name.
106   */
107  private static final String MapiTypeFieldName = "MapiType";
108
109  /**
110   * Initializes a new instance.
111   */
112  public ExtendedPropertyDefinition() {
113    super();
114    this.mapiType = MapiPropertyType.String;
115  }
116
117  /**
118   * Initializes a new instance.
119   *
120   * @param mapiType The MAPI type of the extended property.
121   */
122  protected ExtendedPropertyDefinition(MapiPropertyType mapiType) {
123    this();
124    this.mapiType = mapiType;
125  }
126
127  /**
128   * Initializes a new instance.
129   *
130   * @param tag      The tag of the extended property.
131   * @param mapiType The MAPI type of the extended property.
132   */
133  public ExtendedPropertyDefinition(int tag, MapiPropertyType mapiType) {
134    this(mapiType);
135    if (tag < 0) {
136      throw new IllegalArgumentException("Argument out of range : tag " + "The extended property tag value must be in the range of 0 to 65,535.");
137    }
138    this.tag = tag;
139  }
140
141  /**
142   * Initializes a new instance.
143   *
144   * @param propertySet The extended property set of the extended property.
145   * @param name        The name of the extended property.
146   * @param mapiType    The MAPI type of the extended property.
147   * @throws Exception the exception
148   */
149  public ExtendedPropertyDefinition(DefaultExtendedPropertySet propertySet,
150      String name, MapiPropertyType mapiType) throws Exception {
151    this(mapiType);
152    EwsUtilities.validateParam(name, "name");
153
154    this.propertySet = propertySet;
155    this.name = name;
156  }
157
158  /**
159   * Initializes a new instance.
160   *
161   * @param propertySet The property set of the extended property.
162   * @param id          The Id of the extended property.
163   * @param mapiType    The MAPI type of the extended property.
164   */
165  public ExtendedPropertyDefinition(DefaultExtendedPropertySet propertySet,
166      int id, MapiPropertyType mapiType) {
167    this(mapiType);
168    this.propertySet = propertySet;
169    this.id = id;
170  }
171
172  /**
173   * Initializes a new instance.
174   *
175   * @param propertySetId The property set Id of the extended property.
176   * @param name          The name of the extended property.
177   * @param mapiType      The MAPI type of the extended property.
178   * @throws Exception the exception
179   */
180  public ExtendedPropertyDefinition(UUID propertySetId, String name,
181      MapiPropertyType mapiType) throws Exception {
182    this(mapiType);
183    EwsUtilities.validateParam(name, "name");
184
185    this.propertySetId = propertySetId;
186    this.name = name;
187  }
188
189  /**
190   * Initializes a new instance.
191   *
192   * @param propertySetId The property set Id of the extended property.
193   * @param id            The Id of the extended property.
194   * @param mapiType      The MAPI type of the extended property.
195   */
196  public ExtendedPropertyDefinition(UUID propertySetId, int id,
197      MapiPropertyType mapiType) {
198    this(mapiType);
199    this.propertySetId = propertySetId;
200    this.id = id;
201  }
202
203  /**
204   * Determines whether two specified instances of ExtendedPropertyDefinition are equal.
205   *
206   * @param extPropDef1 First extended property definition.
207   * @param extPropDef2 Second extended property definition.
208   * @return True if extended property definitions are equal.
209   */
210  protected static boolean isEqualTo(ExtendedPropertyDefinition extPropDef1,
211      ExtendedPropertyDefinition extPropDef2) {
212    if (extPropDef1 == extPropDef2) {
213      return true;
214    }
215
216    if (extPropDef1 == null || extPropDef2 == null) {
217      return false;
218    }
219
220    if (extPropDef1.getId() != null) {
221      if (!extPropDef1.getId().equals(extPropDef2.getId())) {
222        return false;
223      }
224    } else if (extPropDef2.getId() != null) {
225      return false;
226    }
227
228    if (extPropDef1.getMapiType() != extPropDef2.getMapiType()) {
229      return false;
230    }
231
232    if (extPropDef1.getTag() != null) {
233      if (!extPropDef1.getTag().equals(extPropDef2.getTag())) {
234        return false;
235      }
236    } else if (extPropDef2.getTag() != null) {
237      return false;
238    }
239
240    if (extPropDef1.getName() != null) {
241      if (!extPropDef1.getName().equals(extPropDef2.getName())) {
242        return false;
243      }
244    } else if (extPropDef2.getName() != null) {
245      return false;
246    }
247
248    if (extPropDef1.getPropertySet() != extPropDef2.getPropertySet()) {
249      return false;
250    }
251
252    if (extPropDef1.propertySetId != null) {
253      if (!extPropDef1.propertySetId.equals(extPropDef2.propertySetId)) {
254        return false;
255      }
256    } else if (extPropDef2.propertySetId != null) {
257      return false;
258    }
259
260    return true;
261  }
262
263  /**
264   * Gets the name of the XML element.
265   *
266   * @return XML element name.
267   */
268  @Override
269  protected String getXmlElementName() {
270    return XmlElementNames.ExtendedFieldURI;
271  }
272
273  /**
274   * Gets the minimum Exchange version that supports this extended property.
275   *
276   * @return The version.
277   */
278  @Override
279  public ExchangeVersion getVersion() {
280    return ExchangeVersion.Exchange2007_SP1;
281  }
282
283  /**
284   * Writes the attribute to XML.
285   *
286   * @param writer The writer.
287   * @throws ServiceXmlSerializationException the service xml serialization exception
288   */
289  @Override
290  protected void writeAttributesToXml(EwsServiceXmlWriter writer)
291      throws ServiceXmlSerializationException {
292    if (this.propertySet != null) {
293      writer.writeAttributeValue(
294          XmlAttributeNames.DistinguishedPropertySetId,
295          this.propertySet);
296    }
297    if (this.propertySetId != null) {
298      writer.writeAttributeValue(XmlAttributeNames.PropertySetId,
299          this.propertySetId.toString());
300    }
301    if (this.tag != null) {
302      writer.writeAttributeValue(XmlAttributeNames.PropertyTag, this.tag);
303    }
304    if (null != this.name && !this.name.isEmpty()) {
305      writer.writeAttributeValue(XmlAttributeNames.PropertyName,
306          this.name);
307    }
308    if (this.id != null) {
309      writer.writeAttributeValue(XmlAttributeNames.PropertyId, this.id);
310    }
311    writer.writeAttributeValue(XmlAttributeNames.PropertyType,
312        this.mapiType);
313  }
314
315  /**
316   * Loads from XML.
317   *
318   * @param reader The reader.
319   * @throws Exception the exception
320   */
321  public void loadFromXml(EwsServiceXmlReader reader) throws Exception {
322    String attributeValue;
323
324    attributeValue = reader
325        .readAttributeValue(XmlAttributeNames.
326            DistinguishedPropertySetId);
327    if (null != attributeValue && !attributeValue.isEmpty()) {
328      this.propertySet = DefaultExtendedPropertySet
329          .valueOf(attributeValue);
330    }
331
332    attributeValue = reader
333        .readAttributeValue(XmlAttributeNames.PropertySetId);
334    if (null != attributeValue && !attributeValue.isEmpty()) {
335      this.propertySetId = UUID.fromString(attributeValue);
336    }
337
338    attributeValue = reader
339        .readAttributeValue(XmlAttributeNames.PropertyTag);
340    if (null != attributeValue && !attributeValue.isEmpty()) {
341
342      this.tag = Integer.decode(attributeValue);
343    }
344
345    this.name = reader.readAttributeValue(XmlAttributeNames.PropertyName);
346    attributeValue = reader
347        .readAttributeValue(XmlAttributeNames.PropertyId);
348    if (null != attributeValue && !attributeValue.isEmpty()) {
349      this.id = Integer.parseInt(attributeValue);
350    }
351
352    this.mapiType = reader.readAttributeValue(MapiPropertyType.class,
353        XmlAttributeNames.PropertyType);
354  }
355
356
357  /**
358   * Determines whether two specified instances of ExtendedPropertyDefinition
359   * are equal.
360   *
361   * @param obj the obj
362   * @return True if extended property definitions are equal.
363   */
364  @Override
365  public boolean equals(Object obj) {
366    if (this == obj) {
367      return true;
368    }
369    if (obj instanceof ExtendedPropertyDefinition) {
370      return ExtendedPropertyDefinition.isEqualTo(this,
371          (ExtendedPropertyDefinition) obj);
372    } else {
373      return false;
374    }
375  }
376
377  /*
378   * (non-Javadoc)
379   *
380   * @see java.lang.Object#hashCode()
381   */
382  @Override
383  public int hashCode() {
384    return this.getPrintableName().hashCode();
385  }
386
387  /**
388   * Gets the property definition's printable name.
389   *
390   * @return The property definition's printable name.
391   */
392  @Override public String getPrintableName() {
393    StringBuilder sb = new StringBuilder();
394    sb.append("{");
395    sb.append(formatField(NameFieldName, this.getName()));
396    sb.append(formatField(MapiTypeFieldName, this.getMapiType()));
397    sb.append(formatField(IdFieldName, this.getId()));
398    sb.append(formatField(PropertySetFieldName, this.getPropertySet()));
399    sb.append(formatField(PropertySetIdFieldName, this.getPropertySetId()));
400    sb.append(formatField(TagFieldName, this.getTag()));
401    sb.append("}");
402    return sb.toString();
403  }
404
405  /**
406   * Formats the field.
407   *
408   * @param <T>        Type of the field.
409   * @param name       The name.
410   * @param fieldValue The field value.
411   * @return the string
412   */
413  protected <T> String formatField(String name, T fieldValue) {
414    return (fieldValue != null) ? String.format(FieldFormat, name,
415        fieldValue.toString()) : "";
416  }
417
418  /**
419   * Gets the property set of the extended property.
420   *
421   * @return property set of the extended property.
422   */
423  public DefaultExtendedPropertySet getPropertySet() {
424    return this.propertySet;
425  }
426
427  /**
428   * Gets the property set Id or the extended property.
429   *
430   * @return property set Id or the extended property.
431   */
432  public UUID getPropertySetId() {
433    return this.propertySetId;
434  }
435
436  /**
437   * Gets the extended property's tag.
438   *
439   * @return The extended property's tag.
440   */
441  public Integer getTag() {
442    return this.tag;
443  }
444
445  /**
446   * Gets the name of the extended property.
447   *
448   * @return The name of the extended property.
449   */
450  public String getName() {
451    return this.name;
452  }
453
454  /**
455   * Gets the Id of the extended property.
456   *
457   * @return The Id of the extended property.
458   */
459  public Integer getId() {
460    return this.id;
461  }
462
463  /**
464   * Gets the MAPI type of the extended property.
465   *
466   * @return The MAPI type of the extended property.
467   */
468  public MapiPropertyType getMapiType() {
469    return this.mapiType;
470  }
471
472  /**
473   * Gets the property type.
474   */
475  @Override
476  public Class<?> getType() {
477    return MapiTypeConverter.getMapiTypeConverterMap().
478        get(getMapiType()).getType();
479  }
480}