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 }