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.service.ServiceObject;
031import microsoft.exchange.webservices.data.core.service.item.Item;
032import microsoft.exchange.webservices.data.core.enumeration.property.BodyType;
033import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
034import microsoft.exchange.webservices.data.core.exception.service.local.ServiceValidationException;
035import microsoft.exchange.webservices.data.property.definition.PropertyDefinitionBase;
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038
039import java.util.Arrays;
040
041/**
042 * Represents an item attachment.
043 */
044public class ItemAttachment extends Attachment implements IServiceObjectChangedDelegate {
045
046  private static final Log LOG = LogFactory.getLog(ItemAttachment.class);
047
048  /**
049   * The item.
050   */
051  private Item item;
052
053  /**
054   * Initializes a new instance of the class.
055   *
056   * @param owner The owner of the attachment
057   */
058  protected ItemAttachment(Item owner) {
059    super(owner);
060  }
061
062  /**
063   * Gets the item associated with the attachment.
064   *
065   * @return the item
066   */
067  public Item getItem() {
068    return this.item;
069  }
070
071  /**
072   * Sets the item associated with the attachment.
073   *
074   * @param item the new item
075   */
076  protected void setItem(Item item) {
077    this.throwIfThisIsNotNew();
078
079    if (this.item != null) {
080
081      this.item.removeServiceObjectChangedEvent(this);
082    }
083    this.item = item;
084    if (this.item != null) {
085      this.item.addServiceObjectChangedEvent(this);
086    }
087  }
088
089  /**
090   * Implements the OnChange event handler for the item associated with the
091   * attachment.
092   *
093   * @param serviceObject ,The service object that triggered the OnChange event.
094   */
095  private void itemChanged(ServiceObject serviceObject) {
096    this.item.getPropertyBag().changed();
097  }
098
099  /**
100   * Obtains EWS XML element name for this object.
101   *
102   * @return The XML element name.
103   */
104  @Override public String getXmlElementName() {
105    return XmlElementNames.ItemAttachment;
106  }
107
108  /**
109   * Tries to read the element at the current position of the reader.
110   *
111   * @param reader the reader
112   * @return True if the element was read, false otherwise.
113   * @throws Exception the exception
114   */
115  @Override
116  public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
117      throws Exception {
118    boolean result = super.tryReadElementFromXml(reader);
119
120    if (!result) {
121      this.item = EwsUtilities.createItemFromXmlElementName(this, reader.getLocalName());
122
123      if (this.item != null) {
124        try {
125          this.item.loadFromXml(reader, true /* clearPropertyBag */);
126        } catch (Exception e) {
127          LOG.error(e);
128
129        }
130      }
131    }
132
133    return result;
134  }
135
136  /**
137   * For ItemAttachment, AttachmentId and Item should be patched.
138   *
139   * @param reader The reader.
140   *               <p/>
141   *               True if element was read.
142   */
143  public boolean tryReadElementFromXmlToPatch(EwsServiceXmlReader reader) throws Exception {
144    // update the attachment id.
145    super.tryReadElementFromXml(reader);
146
147    reader.read();
148
149    String localName = reader.getLocalName();
150    Class<?> itemClass = EwsUtilities.getItemTypeFromXmlElementName(localName);
151
152    if (itemClass != null) {
153      if (item == null || item.getClass() != itemClass) {
154        throw new ServiceLocalException(
155            "Attachment item type mismatch.");
156      }
157
158      this.item.loadFromXml(reader, false /* clearPropertyBag */);
159      return true;
160    }
161
162    return false;
163  }
164
165
166  /**
167   * Writes the property of this object as XML elements.
168   *
169   * @param writer ,The writer to write the elements to.
170   * @throws Exception the exception
171   */
172  @Override
173  public void writeElementsToXml(EwsServiceXmlWriter writer)
174      throws Exception {
175    super.writeElementsToXml(writer);
176    try {
177      this.item.writeToXml(writer);
178    } catch (Exception e) {
179      LOG.error(e);
180
181    }
182  }
183
184  /**
185   * {@inheritDoc}
186   */
187  @Override
188  protected void validate(int attachmentIndex) throws Exception {
189    if (this.getName() == null || this.getName().isEmpty()) {
190      throw new ServiceValidationException(String.format(
191          "The name of the item attachment at index %d must be set.", attachmentIndex));
192    }
193
194    // Recurse through any item attached to item attachment.
195    this.validate();
196  }
197
198  /**
199   * Loads this attachment.
200   *
201   * @param additionalProperties the additional property
202   * @throws Exception the exception
203   */
204  public void load(PropertyDefinitionBase... additionalProperties)
205      throws Exception {
206    internalLoad(null /* bodyType */, Arrays.asList(additionalProperties));
207  }
208
209  /**
210   * Loads this attachment.
211   *
212   * @param additionalProperties the additional property
213   * @throws Exception the exception
214   */
215  public void load(Iterable<PropertyDefinitionBase> additionalProperties)
216      throws Exception {
217    this.internalLoad(null, additionalProperties);
218  }
219
220  /**
221   * Loads this attachment.
222   *
223   * @param bodyType             the body type
224   * @param additionalProperties the additional property
225   * @throws Exception the exception
226   */
227  public void load(BodyType bodyType,
228      PropertyDefinitionBase... additionalProperties) throws Exception {
229    internalLoad(bodyType, Arrays.asList(additionalProperties));
230  }
231
232  /**
233   * Loads this attachment.
234   *
235   * @param bodyType             the body type
236   * @param additionalProperties the additional property
237   * @throws Exception the exception
238   */
239  public void load(BodyType bodyType,
240      Iterable<PropertyDefinitionBase> additionalProperties)
241      throws Exception {
242    this.internalLoad(bodyType, additionalProperties);
243  }
244
245  /**
246   * Service object changed.
247   *
248   * @param serviceObject accepts ServiceObject
249   */
250  @Override
251  public void serviceObjectChanged(ServiceObject serviceObject) {
252    this.itemChanged(serviceObject);
253  }
254
255}