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.time;
025    
026    import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
027    import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
028    import microsoft.exchange.webservices.data.core.XmlAttributeNames;
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.ServiceLocalException;
032    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
033    import microsoft.exchange.webservices.data.property.complex.ComplexProperty;
034    
035    import javax.xml.stream.XMLStreamException;
036    
037    /**
038     * Represents the base class for all time zone transitions.
039     */
040    public class TimeZoneTransition extends ComplexProperty {
041    
042      /**
043       * The Period target.
044       */
045      private final String PeriodTarget = "Period";
046    
047      /**
048       * The Group target.
049       */
050      private final String GroupTarget = "Group";
051    
052      /**
053       * The time zone definition.
054       */
055      private TimeZoneDefinition timeZoneDefinition;
056    
057      /**
058       * The target period.
059       */
060      private TimeZonePeriod targetPeriod;
061    
062      /**
063       * The target group.
064       */
065      private TimeZoneTransitionGroup targetGroup;
066    
067      /**
068       * Creates a time zone period transition of the appropriate type given an
069       * XML element name.
070       *
071       * @param timeZoneDefinition the time zone definition
072       * @param xmlElementName     the xml element name
073       * @return A TimeZonePeriodTransition instance.
074       * @throws ServiceLocalException the service local exception
075       */
076      public static TimeZoneTransition create(TimeZoneDefinition timeZoneDefinition, String xmlElementName)
077          throws ServiceLocalException {
078        if (xmlElementName.equals(XmlElementNames.AbsoluteDateTransition)) {
079          return new AbsoluteDateTransition(timeZoneDefinition);
080        } else if (xmlElementName
081            .equals(XmlElementNames.AbsoluteDateTransition)) {
082          return new AbsoluteDateTransition(timeZoneDefinition);
083        } else if (xmlElementName
084            .equals(XmlElementNames.RecurringDayTransition)) {
085          return new RelativeDayOfMonthTransition(timeZoneDefinition);
086        } else if (xmlElementName
087            .equals(XmlElementNames.RecurringDateTransition)) {
088          return new AbsoluteDayOfMonthTransition(timeZoneDefinition);
089        } else if (xmlElementName.equals(XmlElementNames.Transition)) {
090          return new TimeZoneTransition(timeZoneDefinition);
091        } else {
092          throw new ServiceLocalException(String
093              .format("Unknown time zone transition type: %s",
094                  xmlElementName));
095        }
096      }
097    
098      /**
099       * Gets the XML element name associated with the transition.
100       *
101       * @return The XML element name associated with the transition.
102       */
103      protected String getXmlElementName() {
104        return XmlElementNames.Transition;
105      }
106    
107      /**
108       * Tries to read element from XML.The reader.
109       *
110       * @param reader The
111       *               reader.
112       * @return True if element was read.
113       * @throws Exception the exception
114       */
115      @Override
116      public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
117          throws Exception {
118        if (reader.getLocalName().equals(XmlElementNames.To)) {
119          String targetKind = reader
120              .readAttributeValue(XmlAttributeNames.Kind);
121          String targetId = reader.readElementValue();
122          if (targetKind.equals(PeriodTarget)) {
123            if (!this.timeZoneDefinition.getPeriods().containsKey(targetId)) {
124             
125              throw new ServiceLocalException(String.format(
126                  "Invalid transition. A period with the specified Id couldn't be found: %s", targetId));
127            } else {
128                     this.targetPeriod = this.timeZoneDefinition.getPeriods()
129                         .get(targetId);
130            }
131          } else if (targetKind.equals(GroupTarget)) {
132            if (!this.timeZoneDefinition.getTransitionGroups().containsKey(
133                targetId)) {
134             
135              throw new ServiceLocalException(String.format(
136                  "Invalid transition. A transition group with the specified ID couldn't be found: %s", targetId));
137            } else {
138                     this.targetGroup = this.timeZoneDefinition
139                         .getTransitionGroups().get(targetId);
140            }
141          } else {
142            throw new ServiceLocalException("The time zone transition target isn't supported.");
143          }
144    
145          return true;
146        } else {
147          return false;
148        }
149      }
150    
151      /**
152       * Writes elements to XML.
153       *
154       * @param writer the writer
155       * @throws ServiceXmlSerializationException the service xml serialization exception
156       * @throws XMLStreamException the XML stream exception
157       */
158      @Override
159      public void writeElementsToXml(EwsServiceXmlWriter writer)
160          throws ServiceXmlSerializationException, XMLStreamException {
161        writer.writeStartElement(XmlNamespace.Types, XmlElementNames.To);
162    
163        if (this.targetPeriod != null) {
164          writer.writeAttributeValue(XmlAttributeNames.Kind, PeriodTarget);
165          writer.writeValue(this.targetPeriod.getId(), XmlElementNames.To);
166        } else if (this.targetGroup != null) {
167          writer.writeAttributeValue(XmlAttributeNames.Kind, GroupTarget);
168          writer.writeValue(this.targetGroup.getId(), XmlElementNames.To);
169        }
170    
171        writer.writeEndElement(); // To
172      }
173    
174      /**
175       * Loads from XML.
176       *
177       * @param reader the reader
178       * @throws Exception the exception
179       */
180      public void loadFromXml(EwsServiceXmlReader reader) throws Exception {
181        this.loadFromXml(reader, this.getXmlElementName());
182      }
183    
184      /**
185       * Writes to XML.
186       *
187       * @param writer the writer
188       * @throws Exception the exception
189       */
190      public void writeToXml(EwsServiceXmlWriter writer) throws Exception {
191        this.writeToXml(writer, this.getXmlElementName());
192      }
193    
194      /**
195       * Initializes a new instance of the class.
196       *
197       * @param timeZoneDefinition the time zone definition
198       */
199      protected TimeZoneTransition(TimeZoneDefinition timeZoneDefinition) {
200        super();
201        this.timeZoneDefinition = timeZoneDefinition;
202      }
203    
204      /**
205       * Initializes a new instance of the class.
206       *
207       * @param timeZoneDefinition the time zone definition
208       * @param targetGroup        the target group
209       */
210      protected TimeZoneTransition(TimeZoneDefinition timeZoneDefinition,
211          TimeZoneTransitionGroup targetGroup) {
212        this(timeZoneDefinition);
213        this.targetGroup = targetGroup;
214      }
215    
216      /**
217       * Initializes a new instance of the class.
218       *
219       * @param timeZoneDefinition the time zone definition
220       * @param targetPeriod       the target period
221       */
222      public TimeZoneTransition(TimeZoneDefinition timeZoneDefinition, TimeZonePeriod targetPeriod) {
223        this(timeZoneDefinition);
224        this.targetPeriod = targetPeriod;
225      }
226    
227      /**
228       * Gets the target period of the transition.
229       *
230       * @return the target period
231       */
232      protected TimeZonePeriod getTargetPeriod() {
233        return this.targetPeriod;
234      }
235    
236      /**
237       * Gets the target transition group of the transition.
238       *
239       * @return the target group
240       */
241      public TimeZoneTransitionGroup getTargetGroup() {
242        return this.targetGroup;
243      }
244    
245    }