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.core;
025    
026    import microsoft.exchange.webservices.data.core.response.IGetObjectInstanceDelegate;
027    import microsoft.exchange.webservices.data.core.service.ServiceObject;
028    import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
029    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
030    import microsoft.exchange.webservices.data.util.DateTimeUtils;
031    
032    import java.io.InputStream;
033    import java.text.DateFormat;
034    import java.text.SimpleDateFormat;
035    import java.util.ArrayList;
036    import java.util.Date;
037    import java.util.List;
038    import java.util.TimeZone;
039    
040    /**
041     * XML reader.
042     */
043    public class EwsServiceXmlReader extends EwsXmlReader {
044    
045      /**
046       * The service.
047       */
048      private ExchangeService service;
049    
050      /**
051       * Initializes a new instance of the EwsXmlReader class.
052       *
053       * @param stream the stream
054       * @param service the service
055       * @throws Exception on error
056       */
057      public EwsServiceXmlReader(InputStream stream, ExchangeService service)
058          throws Exception {
059        super(stream);
060        this.service = service;
061      }
062    
063      /**
064       * Reads the element value as date time.
065       *
066       * @return Element value
067       * @throws Exception the exception
068       */
069      public Date readElementValueAsDateTime() throws Exception {
070        return DateTimeUtils.convertDateTimeStringToDate(readElementValue());
071      }
072    
073      /**
074       * Reads the element value as unspecified date.
075       *
076       * @return element value
077       * @throws Exception on error
078       */
079      public Date readElementValueAsUnspecifiedDate() throws Exception {
080        return DateTimeUtils.convertDateStringToDate(readElementValue());
081      }
082    
083      /**
084       * Reads the element value as date time, assuming it is unbiased (e.g.
085       * 2009/01/01T08:00) and scoped to service's time zone.
086       *
087       * @return Date
088       * @throws Exception the exception
089       */
090      public Date readElementValueAsUnbiasedDateTimeScopedToServiceTimeZone()
091          throws Exception {
092        // Convert the element's value to a DateTime with no adjustment.
093        String date = this.readElementValue();
094    
095        try {
096          DateFormat formatter =
097              new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
098          formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
099          return formatter.parse(date);
100        } catch (Exception e) {
101          DateFormat formatter = new SimpleDateFormat(
102              "yyyy-MM-dd'T'HH:mm:ss.SSS");
103          formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
104          return formatter.parse(date);
105        }
106      }
107    
108      /**
109       * Reads the element value as date time.
110       *
111       * @param xmlNamespace the xml namespace
112       * @param localName    the local name
113       * @return the date
114       * @throws Exception the exception
115       */
116      public Date readElementValueAsDateTime(XmlNamespace xmlNamespace, String localName) throws Exception {
117        return DateTimeUtils.convertDateTimeStringToDate(readElementValue(xmlNamespace, localName));
118      }
119    
120      /**
121       * Reads the service objects collection from XML.
122       *
123       * @param <TServiceObject>          the generic type
124       * @param collectionXmlElementName  the collection xml element name
125       * @param getObjectInstanceDelegate the get object instance delegate
126       * @param clearPropertyBag          the clear property bag
127       * @param requestedPropertySet      the requested property set
128       * @param summaryPropertiesOnly     the summary property only
129       * @return the list
130       * @throws Exception the exception
131       */
132      public <TServiceObject extends ServiceObject> List<TServiceObject>
133      readServiceObjectsCollectionFromXml(
134          String collectionXmlElementName,
135          IGetObjectInstanceDelegate<ServiceObject>
136              getObjectInstanceDelegate,
137          boolean clearPropertyBag, PropertySet requestedPropertySet,
138          boolean summaryPropertiesOnly) throws Exception {
139    
140        List<TServiceObject> serviceObjects = new ArrayList<TServiceObject>();
141        TServiceObject serviceObject;
142    
143        this.readStartElement(XmlNamespace.Messages, collectionXmlElementName);
144    
145        if (!this.isEmptyElement()) {
146          do {
147            this.read();
148    
149            if (this.isStartElement()) {
150              serviceObject = (TServiceObject) getObjectInstanceDelegate
151                  .getObjectInstanceDelegate(this.getService(), this
152                      .getLocalName());
153              if (serviceObject == null) {
154                this.skipCurrentElement();
155              } else {
156                if (!(this.getLocalName()).equals(serviceObject
157                    .getXmlElementName())) {
158    
159                  throw new ServiceLocalException(String
160                      .format(
161                          "The type of the " + "object in " +
162                              "the store (%s)" +
163                              " does not match that" +
164                              " of the " +
165                              "local object (%s).",
166                          this.getLocalName(), serviceObject
167                              .getXmlElementName()));
168                }
169                serviceObject.loadFromXml(this, clearPropertyBag,
170                    requestedPropertySet, summaryPropertiesOnly);
171    
172                serviceObjects.add(serviceObject);
173              }
174            }
175          } while (!this.isEndElement(XmlNamespace.Messages,
176              collectionXmlElementName));
177        } else {
178          // For empty elements read End Element tag
179          // i.e. position cursor on End Element
180          this.read();
181        }
182    
183        return serviceObjects;
184    
185      }
186    
187      /**
188       * Gets the service.
189       *
190       * @return the service
191       */
192      public ExchangeService getService() {
193        return service;
194      }
195    
196      /**
197       * Sets the service.
198       *
199       * @param service the new service
200       */
201      public void setService(ExchangeService service) {
202        this.service = service;
203      }
204    
205    }