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.service.ServiceObject;
031    import microsoft.exchange.webservices.data.core.service.item.Item;
032    import microsoft.exchange.webservices.data.core.enumeration.property.BodyType;
033    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
034    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceValidationException;
035    import microsoft.exchange.webservices.data.property.definition.PropertyDefinitionBase;
036    import org.apache.commons.logging.Log;
037    import org.apache.commons.logging.LogFactory;
038    
039    import java.util.Arrays;
040    
041    /**
042     * Represents an item attachment.
043     */
044    public 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    }