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.XmlAttributeNames;
030import microsoft.exchange.webservices.data.core.XmlElementNames;
031import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
032import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
033import microsoft.exchange.webservices.data.misc.Time;
034import microsoft.exchange.webservices.data.misc.TimeSpan;
035
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038
039import java.util.Calendar;
040import java.util.Date;
041import java.util.TimeZone;
042
043import javax.xml.bind.DatatypeConverter;
044
045/**
046 * Represents a change of time for a time zone.
047 */
048public final class TimeChange extends ComplexProperty {
049
050  private static final Log LOG = LogFactory.getLog(TimeChange.class);
051
052  /**
053   * The time zone name.
054   */
055  private String timeZoneName;
056
057  /**
058   * The offset.
059   */
060  private TimeSpan offset;
061
062  /**
063   * The time.
064   */
065  private Time time;
066
067  /**
068   * The absolute date.
069   */
070  private Date absoluteDate;
071
072  /**
073   * The recurrence.
074   */
075  private TimeChangeRecurrence recurrence;
076
077  /**
078   * Initializes a new instance of the "TimeChange" class.
079   */
080  public TimeChange() {
081    super();
082  }
083
084  /**
085   * Initializes a new instance of the <see cref="TimeChange"/> class.
086   *
087   * @param offset The offset since the beginning of the year when the change
088   *               occurs.
089   */
090  public TimeChange(TimeSpan offset) {
091    this();
092    this.offset = offset;
093  }
094
095  /**
096   * Initializes a new instance of the "TimeChange" class.
097   *
098   * @param offset The offset since the beginning of the year when the change
099   *               occurs.
100   * @param time   The time at which the change occurs.
101   */
102  public TimeChange(TimeSpan offset, Time time) {
103    this(offset);
104    this.time = time;
105  }
106
107  /**
108   * Gets the name of the associated time zone.
109   *
110   * @return the timeZoneName
111   */
112  public String getTimeZoneName() {
113    return timeZoneName;
114  }
115
116  /**
117   * Sets the name of the associated time zone.
118   *
119   * @param timeZoneName the timeZoneName to set
120   */
121  public void setTimeZoneName(String timeZoneName) {
122    this.timeZoneName = timeZoneName;
123  }
124
125  /**
126   * Gets the offset since the beginning of the year when the change occurs.
127   *
128   * @return the offset
129   */
130  public TimeSpan getOffset() {
131    return offset;
132  }
133
134  /**
135   * Sets the offset since the beginning of the year when the change occurs.
136   *
137   * @param offset the offset to set
138   */
139  public void setOffset(TimeSpan offset) {
140    this.offset = offset;
141  }
142
143  /**
144   * Gets the time.
145   *
146   * @return the time
147   */
148  public Time getTime() {
149    return time;
150  }
151
152  /**
153   * Sets the time.
154   *
155   * @param time the time to set
156   */
157  public void setTime(Time time) {
158    this.time = time;
159  }
160
161  /**
162   * Gets the absolute date.
163   *
164   * @return the absoluteDate
165   */
166  public Date getAbsoluteDate() {
167    return absoluteDate;
168  }
169
170  /**
171   * Sets the absolute date.
172   *
173   * @param absoluteDate the absoluteDate to set
174   */
175  public void setAbsoluteDate(Date absoluteDate) {
176    this.absoluteDate = absoluteDate;
177    if (absoluteDate != null) {
178      this.recurrence = null;
179    }
180  }
181
182  /**
183   * Gets the recurrence.
184   *
185   * @return the recurrence
186   */
187  public TimeChangeRecurrence getRecurrence() {
188    return recurrence;
189  }
190
191  /**
192   * Sets the recurrence.
193   *
194   * @param recurrence the recurrence to set
195   */
196  public void setRecurrence(TimeChangeRecurrence recurrence) {
197    this.recurrence = recurrence;
198    if (this.recurrence != null) {
199      this.absoluteDate = null;
200    }
201  }
202
203  /**
204   * Tries to read element from XML.
205   *
206   * @param reader accepts EwsServiceXmlReader
207   * @return True if element was read
208   * @throws Exception throws Exception
209   */
210  @Override
211  public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
212      throws Exception {
213
214    if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.Offset)) {
215      this.offset = EwsUtilities.getXSDurationToTimeSpan(reader.readElementValue());
216      return true;
217    } else if (reader.getLocalName().equalsIgnoreCase(
218        XmlElementNames.RelativeYearlyRecurrence)) {
219      this.recurrence = new TimeChangeRecurrence();
220      this.recurrence.loadFromXml(reader, reader.getLocalName());
221      return true;
222    } else if (reader.getLocalName().equalsIgnoreCase(
223        XmlElementNames.AbsoluteDate)) {
224      Calendar cal = DatatypeConverter.parseDate(reader.readElementValue());
225      cal.setTimeZone(TimeZone.getTimeZone("UTC"));
226      this.absoluteDate = cal.getTime();
227      return true;
228    } else if (reader.getLocalName().equalsIgnoreCase(XmlElementNames.Time)) {
229      Calendar cal = DatatypeConverter.parseTime(reader.readElementValue());
230      this.time = new Time(cal.getTime());
231      return true;
232    } else {
233      return false;
234    }
235  }
236
237  /**
238   * Reads the attribute from XML.
239   *
240   * @param reader accepts EwsServiceXmlReader
241   * @throws Exception throws Exception
242   */
243  @Override
244  public void readAttributesFromXml(EwsServiceXmlReader reader)
245      throws Exception {
246    this.timeZoneName = reader
247        .readAttributeValue(XmlAttributeNames.TimeZoneName);
248  }
249
250  /**
251   * Writes the attribute to XML.
252   *
253   * @param writer accepts EwsServiceXmlWriter
254   */
255  @Override
256  public void writeAttributesToXml(EwsServiceXmlWriter writer) {
257    try {
258      writer.writeAttributeValue(XmlAttributeNames.TimeZoneName,
259          this.timeZoneName);
260    } catch (ServiceXmlSerializationException e) {
261      LOG.error(e);
262    }
263  }
264
265  /**
266   * Writes elements to XML.
267   *
268   * @param writer accepts EwsServiceXmlWriter
269   * @throws Exception throws Exception
270   */
271  @Override
272  public void writeElementsToXml(EwsServiceXmlWriter writer)
273      throws Exception {
274    if (this.offset != null) {
275      writer.writeElementValue(XmlNamespace.Types,
276          XmlElementNames.Offset, EwsUtilities
277              .getTimeSpanToXSDuration(this.getOffset()));
278    }
279
280    if (this.recurrence != null) {
281      this.recurrence.writeToXml(writer,
282          XmlElementNames.RelativeYearlyRecurrence);
283    }
284
285    if (this.absoluteDate != null) {
286      writer.writeElementValue(XmlNamespace.Types,
287          XmlElementNames.AbsoluteDate, EwsUtilities
288              .dateTimeToXSDate(this.getAbsoluteDate()));
289    }
290
291    if (this.time != null) {
292      writer.writeElementValue(XmlNamespace.Types, XmlElementNames.Time,
293          this.getTime().toXSTime());
294    }
295  }
296
297}