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.query.xml;
19  
20  import org.w3c.dom.Element;
21  import at.ac.tuwien.infosys.sm4all.copal.api.event.ContextEventType;
22  import at.ac.tuwien.infosys.sm4all.copal.api.query.ContextQuery;
23  import at.ac.tuwien.infosys.sm4all.copal.api.util.FailedUnmarshallingException;
24  import at.ac.tuwien.infosys.sm4all.copal.api.util.Marshaller;
25  import at.ac.tuwien.infosys.sm4all.copal.api.util.MissingFieldException;
26  import at.ac.tuwien.infosys.sm4all.copal.api.util.Unmarshaller;
27  import at.ac.tuwien.infosys.sm4all.copal.api.xml.BaseMarshallerBuilder;
28  import at.ac.tuwien.infosys.sm4all.copal.api.xml.ListMarshaller;
29  import at.ac.tuwien.infosys.sm4all.copal.api.xml.Optional;
30  import at.ac.tuwien.infosys.sm4all.copal.api.xml.StringAttribute;
31  
32  /**
33   * Marshals a {@link ContextQuery} into an {@link Element}.
34   * 
35   * @author sanjin
36   */
37  public class ContextQueryMarshaller implements Marshaller<ContextQuery> {
38  
39      /**
40       * The local name of child {@link Element}s used in the
41       * {@link ListMarshaller.Builder} that is returned by the
42       * {@link #getListBuilder()}.
43       */
44      public static final String QUERY_ELEMENT = "Query";
45      /**
46       * The name of attribute that holds marshaled name.
47       */
48      public static final String NAME_ATTRIBUTE = "name";
49      /**
50       * The name of attribute that holds marshaled listened
51       * {@link ContextEventType}.
52       */
53      public static final String LISTENED_TYPE_ATTRIBUTE = "event";
54      /**
55       * The name of attribute that holds marshaled criteria.
56       */
57      public static final String CRITERIA_ATTRIBUTE = "criteria";
58  
59      private static final ListMarshaller.Builder<ContextQuery> LIST_BUILDER = new ListMarshaller.Builder<ContextQuery>().withChildName(
60              QUERY_ELEMENT).withBuilder(new Builder());
61  
62      private final Element element;
63      private final Unmarshaller<String> name;
64      private final Unmarshaller<String> listenedType;
65      private final Unmarshaller<String> criteria;
66  
67      /**
68       * Creates instance of {@link ContextQuery} {@link Marshaller} which uses
69       * specified {@link Element} for marshalling.
70       * 
71       * @param element the {@link Element} used for marshalling.
72       * @throws NullPointerException if specified {@link Element} is
73       *         <code>null</code>.
74       */
75      public ContextQueryMarshaller(final Element element) {
76          super();
77  
78          if (null == element) {
79              throw new NullPointerException("XML DOM element cannot be null.");
80          }
81  
82          this.element = element;
83          this.name = new StringAttribute(NAME_ATTRIBUTE, element);
84          this.listenedType = new StringAttribute(LISTENED_TYPE_ATTRIBUTE,
85                  element);
86          this.criteria = new Optional<String>(new StringAttribute(
87                  CRITERIA_ATTRIBUTE, element));
88      }
89  
90      /**
91       * Returns the {@link Element} used for marshalling.
92       * 
93       * @return the {@link Element} used for marshalling.
94       */
95      public Element getElement() {
96          return this.element;
97      }
98  
99      /**
100      * Unmarshals name of {@link ContextQuery} from the {@link Element}.
101      * 
102      * @return the name of marshaled {@link ContextQuery}.
103      * @throws FailedUnmarshallingException if unmarshalling was unsuccessful.
104      */
105     public String unmarshalName() throws FailedUnmarshallingException {
106         final String result;
107 
108         try {
109             result = this.name.unmarshal();
110         } catch (final MissingFieldException ex) {
111             throw new MissingFieldException("Query name", ex);
112         }
113 
114         return result;
115     }
116 
117     /**
118      * Unmarshals name of listened {@link ContextEventType} of
119      * {@link ContextQuery} from the {@link Element}.
120      * 
121      * @return the name of listened {@link ContextEventType} of marshaled
122      *         {@link ContextQuery}.
123      * @throws FailedUnmarshallingException if unmarshalling was unsuccessful.
124      */
125     public String unmarshalListenedType() throws FailedUnmarshallingException {
126         final String result;
127 
128         try {
129             result = this.listenedType.unmarshal();
130         } catch (final MissingFieldException ex) {
131             throw new MissingFieldException("Query listened type", ex);
132         }
133 
134         return result;
135     }
136 
137     /**
138      * Unmarshals criteria of {@link ContextQuery} from the {@link Element}.
139      * 
140      * @return the criteria of marshaled {@link ContextQuery}.
141      * @throws FailedUnmarshallingException if unmarshalling was unsuccessful.
142      */
143     public String unmarshalCriteria() throws FailedUnmarshallingException {
144         return this.criteria.unmarshal();
145     }
146 
147     /**
148      * Marshals specified {@link ContextQuery} into the {@link Element}.
149      * 
150      * @param query the {@link ContextQuery}.
151      * @throws NullPointerException if specified {@link ContextQuery} is
152      *         <code>null</code>.
153      */
154     @Override
155     public void marshal(final ContextQuery query) {
156         if (null == query) {
157             throw new NullPointerException("Query cannot be null.");
158         }
159 
160         this.name.marshal(query.getName());
161         this.listenedType.marshal(query.getListenedType());
162         if (query.hasCriteria()) {
163             this.criteria.marshal(query.getCriteria());
164         } else {
165             this.criteria.remove();
166         }
167     }
168 
169     /**
170      * Removes any marshaled {@link ContextQuery} from the {@link Element}.
171      */
172     @Override
173     public void remove() {
174         this.name.remove();
175         this.listenedType.remove();
176         this.criteria.remove();
177     }
178 
179     /**
180      * Creates instance of {@link ListMarshaller.Builder} for
181      * {@link ContextQuery}s. The returned {@link ListMarshaller.Builder} does
182      * not have the parent {@link Element} set and caller should set it before
183      * building the {@link ListMarshaller} for {@link ContextQuery}s. The name
184      * for child {@link Element}s is set to {@link #QUERY_ELEMENT}.
185      * 
186      * @return the {@link ListMarshaller.Builder} for {@link ContextQuery}s.
187      */
188     public static ListMarshaller.Builder<ContextQuery> getListBuilder() {
189         return LIST_BUILDER;
190     }
191 
192     /**
193      * Builder of {@link ContextQueryMarshaller}.
194      * 
195      * @author sanjin
196      */
197     public static class Builder extends BaseMarshallerBuilder<ContextQuery> {
198 
199         /**
200          * Create uninitialized instance of
201          * {@link ContextQueryMarshaller.Builder}.
202          */
203         public Builder() {
204             super();
205         }
206 
207         /**
208          * Clone-constructor.
209          * 
210          * @param builder the cloned {@link ContextQueryMarshaller.Builder}.
211          */
212         protected Builder(final Builder builder) {
213             super(builder);
214         }
215 
216         /**
217          * Create instance of {@link ContextQueryMarshaller}.
218          * 
219          * @return a {@link ContextQueryMarshaller}.
220          */
221         @Override
222         public ContextQueryMarshaller build() {
223             return new ContextQueryMarshaller(getElement());
224         }
225 
226         @Override
227         protected Builder copy() {
228             return new Builder(this);
229         }
230     }
231 }