001 /*
002 @license.text@
003 */
004 package biz.hammurapi.config;
005
006 import java.io.FileInputStream;
007 import java.io.FileNotFoundException;
008 import java.io.IOException;
009 import java.io.InputStream;
010 import java.net.MalformedURLException;
011 import java.net.URL;
012 import java.text.MessageFormat;
013
014 import javax.xml.parsers.DocumentBuilderFactory;
015 import javax.xml.parsers.FactoryConfigurationError;
016 import javax.xml.parsers.ParserConfigurationException;
017
018 import org.w3c.dom.Document;
019 import org.xml.sax.SAXException;
020
021 /**
022 * Helper class to read XML configuration from file, url or classloader
023 * resource.
024 *
025 * @author Pavel Vlasov
026 * @version $Revision: 1.2 $
027 */
028 public class XmlSource implements Parameterizable {
029
030 private String prefix;
031
032 private Class masterClass;
033
034 private String defaultResourceExtension;
035
036 /**
037 * Constructor
038 *
039 * @param prefix
040 * Prefix for configuration parameters. Parameter specifying
041 * configruration file would be <prefix>-file, url -
042 * <prefix>-url, resource - <prefix>-resource
043 * @param masterClass
044 * Master class' classloader will be used to load resources and
045 * default resource would be masterClass name with
046 * defaultResourceExtension. If master class is null then this
047 * class classloader will be used and no default resource will be
048 * loaded.
049 * @param defaultResourceExtension
050 * Extension for default resource. If it is null then default
051 * resource will not be loaded.
052 */
053 public XmlSource(String prefix, Class masterClass,
054 String defaultResourceExtension) {
055 this.prefix = prefix;
056 this.masterClass = masterClass;
057 this.defaultResourceExtension = defaultResourceExtension;
058 }
059
060 private static final String CONFIG_ERROR_MESSAGE = "'{0}-file', "
061 + "'{0}-resource', and '{0}-url' parameters are mutually exclusive";
062
063 private String resource;
064
065 private String url;
066
067 private String file;
068
069 private Document document;
070
071 /**
072 * @return parsed XML or null if config not found.
073 * @throws ConfigurationException
074 */
075 public Document getConfigDocument() throws ConfigurationException {
076 if (document == null) {
077 try {
078 InputStream configStream = getStream();
079
080 if (configStream!=null) {
081 document = DocumentBuilderFactory.newInstance()
082 .newDocumentBuilder().parse(configStream);
083 configStream.close();
084 }
085 } catch (IOException e) {
086 throw new ConfigurationException("Cannot load document, "
087 + e.getMessage(), e);
088 } catch (SAXException e) {
089 throw new ConfigurationException("Cannot load document, "
090 + e.getMessage(), e);
091 } catch (ParserConfigurationException e) {
092 throw new ConfigurationException("Cannot load document, "
093 + e.getMessage(), e);
094 } catch (FactoryConfigurationError e) {
095 throw new ConfigurationException("Cannot load document, "
096 + e.getMessage(), e);
097 }
098 }
099
100 return document;
101 }
102
103 /**
104 * @return Stream
105 * @throws FileNotFoundException
106 * @throws IOException
107 * @throws MalformedURLException
108 * @throws ConfigurationException
109 */
110 public InputStream getStream() throws ConfigurationException {
111 try {
112 Class clazz = masterClass==null ? getClass() : masterClass;
113 if (file != null) {
114 return new FileInputStream(file);
115 } else if (url != null) {
116 return new URL(url).openStream();
117 } else if (resource != null) {
118
119 InputStream configStream = clazz.getClassLoader().getResourceAsStream(resource);
120 if (configStream == null) {
121 throw new ConfigurationException("Resource not found: " + resource);
122 }
123
124 return configStream;
125 } else {
126 if (defaultResourceExtension==null) {
127 return null;
128 }
129
130 String className = clazz.getName();
131 int idx = className.lastIndexOf('.');
132 String rName = (idx == -1 ? className : className
133 .substring(idx + 1))
134 + defaultResourceExtension;
135 return clazz.getResourceAsStream(rName);
136 }
137 } catch (IOException e) {
138 throw new ConfigurationException("Cannot open stream, " + e.getMessage(), e);
139 }
140 }
141
142 public boolean setParameter(String name, Object value)
143 throws ConfigurationException {
144 if ((prefix+"-file").equals(name)) {
145 if (resource != null) {
146 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
147 }
148 if (url != null) {
149 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
150 }
151 file = value.toString();
152 } else if ((prefix+"-resource").equals(name)) {
153 if (file != null) {
154 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
155 }
156 if (url != null) {
157 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
158 }
159 resource = value.toString();
160 } else if ((prefix+"-url").equals(name)) {
161 if (file != null) {
162 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
163 }
164 if (resource != null) {
165 throw new ConfigurationException(MessageFormat.format(CONFIG_ERROR_MESSAGE, new Object[] {prefix}));
166 }
167 url = value.toString();
168 } else {
169 return false;
170 }
171 return true;
172 }
173 }