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