View Javadoc

1   /* This file is part of COPAL (COntext Provisioning for All).
2    *
3    * COPAL is a part of SM4All (Smart hoMes for All) project.
4    *
5    * COPAL is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * COPAL is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with COPAL. If not, see <http://www.gnu.org/licenses/>.
17   */
18  package at.ac.tuwien.infosys.sm4all.copal.api.xml;
19  
20  import java.text.DateFormat;
21  import java.text.MessageFormat;
22  import java.text.ParseException;
23  import java.text.SimpleDateFormat;
24  import java.util.Date;
25  import java.util.TimeZone;
26  import org.w3c.dom.Element;
27  import at.ac.tuwien.infosys.sm4all.copal.api.util.InvalidFieldValueException;
28  import at.ac.tuwien.infosys.sm4all.copal.api.util.Marshaller;
29  import at.ac.tuwien.infosys.sm4all.copal.api.util.Unmarshaller;
30  
31  /**
32   * Unmarshals and marshals a {@link Date} value of an attribute from/to an
33   * {@link Element}.
34   * 
35   * @author sanjin
36   */
37  public class DateAttribute extends Attribute<Date> {
38  
39      private static final String XML_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
40      private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
41  
42      private final String name;
43  
44      /**
45       * Creates instance of an attribute {@link Unmarshaller} and
46       * {@link Marshaller} which uses specified {@link Element} to unmarshal
47       * and/or marshal the {@link Date} value of the attribute with specified
48       * name.
49       * 
50       * @param name the name of the attribute in the {@link Element} used for
51       *        unmarshalling and marshalling.
52       * @param element the {@link Element} used for unmarshalling and
53       *        marshalling.
54       * @throws NullPointerException if specified {@link Element} or name is
55       *         <code>null</code>.
56       * @throws IllegalArgumentException if specified name is an empty or blank
57       *         string.
58       */
59      public DateAttribute(final String name, final Element element) {
60          super(name, element);
61  
62          this.name = name;
63      }
64  
65      @Override
66      protected String toString(final Date date) {
67          final DateFormat xmlDateTimeFormat = createXMLDateTimeFormat();
68  
69          return xmlDateTimeFormat.format(date);
70      }
71  
72      @Override
73      protected Date valueOf(final String str) throws InvalidFieldValueException {
74          final DateFormat xmlDateTimeFormat = createXMLDateTimeFormat();
75          final Date result;
76  
77          try {
78              result = xmlDateTimeFormat.parse(str);
79          } catch (final ParseException ex) {
80              throw new InvalidFieldValueException(MessageFormat.format(
81                      "{0} is not a date", this.name), ex);
82          }
83  
84          return result;
85      }
86  
87      private static DateFormat createXMLDateTimeFormat() {
88          final DateFormat result = new SimpleDateFormat(XML_DATETIME_FORMAT);
89  
90          // when formatting dates convert them from/to UTC time zone
91          result.setTimeZone(UTC_TIME_ZONE);
92          result.setLenient(false);
93  
94          return result;
95      }
96  
97      /**
98       * Builder of {@link DateAttribute}.
99       * 
100      * @author sanjin
101      */
102     public static class Builder extends Attribute.Builder<Date> {
103 
104         /**
105          * Create an uninitialized instance of {@link DateAttribute.Builder}.
106          */
107         public Builder() {
108             super();
109         }
110 
111         /**
112          * Clone-constructor.
113          * 
114          * @param builder the cloned {@link DateAttribute.Builder}.
115          */
116         private Builder(final Builder builder) {
117             super(builder);
118         }
119 
120         /**
121          * Create instance of {@link DateAttribute}.
122          * 
123          * @return a {@link DateAttribute}.
124          */
125         @Override
126         public DateAttribute build() {
127             return new DateAttribute(getName(), getElement());
128         }
129 
130         @Override
131         protected Builder copy() {
132             return new Builder(this);
133         }
134     }
135 }