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;
19  
20  import java.text.MessageFormat;
21  import javax.xml.xpath.XPathConstants;
22  import javax.xml.xpath.XPathExpressionException;
23  import org.w3c.dom.Document;
24  import org.w3c.dom.Element;
25  import org.w3c.dom.Node;
26  import at.ac.tuwien.infosys.sm4all.copal.api.event.ContextEvent;
27  import at.ac.tuwien.infosys.sm4all.copal.api.util.Constants;
28  import at.ac.tuwien.infosys.sm4all.copal.api.util.FailedUnmarshallingException;
29  import at.ac.tuwien.infosys.sm4all.copal.api.util.MissingFieldException;
30  
31  /**
32   * The abstract class for concrete COPAL elements i.e. elements that are
33   * injected and can be retrieved from a XML DOM document generated by the
34   * {@link XMLContextEvent#getDocument()} method.
35   * 
36   * @param <T> the type of element's value.
37   * @author sanjin
38   */
39  public abstract class ConcreteElement<T> extends XMLElement<T> {
40  
41      /**
42       * @param type the XML type of this COPAL element returned by the xPath.
43       */
44      protected ConcreteElement(final Class<?> type) {
45          super(type);
46      }
47  
48      @Override
49      public String getXPath() {
50          return "//" + getQualifiedName();
51      }
52  
53      /**
54       * Retrieve the value of this element from specified {@link Element}.
55       * 
56       * @param element the {@link Element}.
57       * @return the value of this property.
58       * @throws FailedUnmarshallingException if retrieving was not successful.
59       */
60      protected abstract T retrieve(Element element)
61              throws FailedUnmarshallingException;
62  
63      /**
64       * Update specified {@link Element} with value retrieved from specified
65       * {@link ContextEvent}.
66       * 
67       * @param element the {@link Element} to update.
68       * @param event the {@link ContextEvent}.
69       */
70      public abstract void update(Element element, ContextEvent event);
71  
72      /**
73       * Creates a {@link Element} with namespace URI set to
74       * {@link Constants#COPAL_NAMESPACE} and qualified name set to
75       * {@link #getQualifiedName()} and updated using the
76       * {@link #update(Element, ContextEvent)} method.
77       * 
78       * @param document the {@link Document} used to create the {@link Element}.
79       * @param event the {@link ContextEvent} to use for updating the
80       *        {@link Element}.
81       * @return the {@link Element}.
82       */
83      public Element createElement(final Document document,
84              final ContextEvent event) {
85          if (document == null)
86              throw new NullPointerException("XML DOM document cannot be null.");
87          if (event == null)
88              throw new NullPointerException("Context event cannot be null.");
89  
90          final Element result = document.createElementNS(
91                  Constants.COPAL_NAMESPACE, getQualifiedName());
92  
93          update(result, event);
94  
95          return result;
96      }
97  
98      @Override
99      public T retrieve(final Document document)
100             throws FailedUnmarshallingException {
101         if (document == null)
102             throw new NullPointerException("XML DOM document cannot be null.");
103 
104         final Element element = getElement(document);
105         if (element == null)
106             throw new MissingFieldException(MessageFormat.format(
107                     "''{0}'' XML DOM element", getQualifiedName()));
108 
109         return retrieve(element);
110     }
111 
112     /**
113      * Get the {@link Element} of this COPAL element in specified
114      * {@link Document}.
115      * 
116      * @param document the {@link Document}.
117      * @return the first {@link Element} that matches or <code>null</code>.
118      */
119     public Element getElement(final Document document) {
120         if (document == null)
121             throw new NullPointerException("XML DOM document cannot be null.");
122 
123         Element result = null;
124 
125         try {
126             final Node node = (Node) getExpression().evaluate(document,
127                     XPathConstants.NODE);
128             if ((node != null) && (node.getNodeType() == Node.ELEMENT_NODE))
129                 result = (Element) node;
130         } catch (final XPathExpressionException ignored) {
131             /* ignore and return null */
132         }
133 
134         return result;
135     }
136 }