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