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.conf;
19  
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.net.URL;
23  import java.text.MessageFormat;
24  import javax.xml.XMLConstants;
25  import javax.xml.parsers.DocumentBuilderFactory;
26  import javax.xml.parsers.ParserConfigurationException;
27  import javax.xml.validation.Schema;
28  import javax.xml.validation.SchemaFactory;
29  import org.apache.log4j.Level;
30  import org.apache.log4j.Logger;
31  import org.w3c.dom.Document;
32  import org.xml.sax.SAXException;
33  import at.ac.tuwien.infosys.sm4all.copal.api.osgi.GenericActivator;
34  
35  /**
36   * Configuration helper class that finds the XML configuration in classpath.
37   * 
38   * @param <T> type of defined {@link Object}s.
39   * @author sanjin
40   */
41  public abstract class BaseConfiguration<T> extends GenericActivator implements
42          Configuration<T> {
43  
44      private static final Logger LOGGER = Logger.getLogger(BaseConfiguration.class);
45      private static final Schema CONTEXT_SCHEMA;
46  
47      static {
48          Schema schema = null;
49          try {
50              final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
51              final URL configurationSchemaURL = EventTypesConfiguration.class.getClassLoader().getResource(
52                      "Configuration.xsd");
53              if (null == configurationSchemaURL) {
54                  if (LOGGER.isEnabledFor(Level.WARN)) {
55                      LOGGER.warn("Could not find Configuration.xsd! Ignoring.");
56                  }
57              } else {
58                  schema = schemaFactory.newSchema(configurationSchemaURL);
59              }
60          } catch (final SAXException ex) {
61              if (LOGGER.isEnabledFor(Level.WARN)) {
62                  LOGGER.warn("Could not parse Configuration.xsd! Ignoring.", ex);
63              }
64          }
65          CONTEXT_SCHEMA = schema;
66      }
67  
68      private final Document document;
69  
70      /**
71       * Create instance of base configuration that uses specified
72       * {@link ClassLoader} to find the XML configuration file with specified
73       * name and depends on specified OSGi services.
74       * 
75       * @param classLoader the {@link ClassLoader}.
76       * @param fileName the name of the configuration file.
77       * @param dependencies the names of dependent services.
78       */
79      protected BaseConfiguration(final ClassLoader classLoader,
80              final String fileName, final String... dependencies) {
81          super(dependencies);
82  
83          @SuppressWarnings("hiding")
84          Document document = null;
85          final DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
86          builderFactory.setNamespaceAware(true);
87          if (null != CONTEXT_SCHEMA) {
88              builderFactory.setSchema(CONTEXT_SCHEMA);
89          }
90          final URL url = classLoader.getResource(fileName);
91          if (null == url) {
92              if (LOGGER.isEnabledFor(Level.WARN)) {
93                  LOGGER.warn(MessageFormat.format(
94                          "Could not find {0}! Ignoring.", fileName));
95              }
96          } else {
97              InputStream in = null;
98              try {
99                  in = url.openStream();
100                 document = builderFactory.newDocumentBuilder().parse(in);
101             } catch (final IOException ex) {
102                 if (LOGGER.isEnabledFor(Level.WARN)) {
103                     LOGGER.warn(MessageFormat.format(
104                             "Could not read {0}! Ignoring.", fileName), ex);
105                 }
106             } catch (final SAXException ex) {
107                 if (LOGGER.isEnabledFor(Level.WARN)) {
108                     LOGGER.warn(MessageFormat.format(
109                             "Could not parse {0}! Ignoring.", fileName), ex);
110                 }
111             } catch (final ParserConfigurationException ex) {
112                 if (LOGGER.isEnabledFor(Level.WARN)) {
113                     LOGGER.warn(MessageFormat.format(
114                             "Could not find {0}! Ignoring.", fileName), ex);
115                 }
116             } finally {
117                 if (null != in) {
118                     try {
119                         in.close();
120                     } catch (final IOException ex) {
121                         if (LOGGER.isEnabledFor(Level.WARN)) {
122                             LOGGER.warn(
123                                     MessageFormat.format(
124                                             "Could not close {0}! Ignoring.",
125                                             fileName), ex);
126                         }
127                     }
128                 }
129             }
130         }
131 
132         this.document = document;
133     }
134 
135     /**
136      * Returns the configuration {@link Document}.
137      * 
138      * @return the configuration {@link Document}.
139      */
140     protected final Document getDocument() {
141         return this.document;
142     }
143 }