/*
* ConfigurationFileLoader.java
*
* Created on 28. April 2002, 14:45
*/
package org.jconfig.handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jconfig.Configuration;
import org.jconfig.ConfigurationManagerException;
import org.jconfig.URLFileWatcher;
import org.jconfig.error.ErrorReporter;
import org.jconfig.event.FileListener;
import org.jconfig.event.FileListenerEvent;
import org.jconfig.parser.ConfigurationParser;
import org.jconfig.parser.ConfigurationParserFactory;
import org.jconfig.utils.ConfigErrorHandler;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.jconfig.utils.ConfigurationUtils;
/**
* This class will read the content from an URL and generate the
* properties. If you have the need to use a proxy server, create
* jconfig.properties file and place it inside your system path.
* <BR />
* jconfig.properties example:<BR />
* # jconfig.properties file<BR />
* http.proxyHost=proxy.server.url<BR />
* http.proxyPort=3128
*
* @author Andreas Mecky andreas.mecky@xcom.de
* @author Terry Dye terry.dye@xcom.de
*/
public class URLHandler implements ConfigurationHandler, FileListener {
private boolean validate = false;
private String url;
//Steve Braun - addition
private URLFileWatcher watcher = null;
public URLHandler() {
}
public void setURL( String url ) {
this.url = url;
}
/**
* This defines if the file will be vaidated using a DTD. The default
* is false.
*
* @param validate defines the validation
*/
public void setValidation(boolean validate) {
this.validate = validate;
}
/**
* @throws ConfigurationManagerException */
public synchronized Configuration load() throws ConfigurationManagerException {
Configuration c = load( url );
addFileListener(this);
return ( c );
}
public void fileChanged(FileListenerEvent event) {
try {
// TODO: we need the configname here! tdye: why?
load();
} catch (ConfigurationManagerException e) {
ErrorReporter.getErrorHandler().reportError("Error while reloading",e);
// technically we shouldn't get this, if we're already registered as a listener
}
}
/**
*
*
*@param theURL Description of the Parameter
*@throws ConfigurationManagerException if the file cannot be processed
*/
public synchronized Configuration load(String configName) throws ConfigurationManagerException {
ConfigurationParser parser = ConfigurationParserFactory.getParser(configName);
return load(getURL(), configName,parser);
}
public synchronized Configuration load(String configName,ConfigurationParser parser) throws ConfigurationManagerException {
return load(getURL(), configName,parser);
}
protected Configuration load(String theURL,String configName) throws ConfigurationManagerException {
ConfigurationParser parser = ConfigurationParserFactory.getParser(configName);
return load(getURL(), configName,parser);
}
protected Configuration load(String theURL,String configName,ConfigurationParser parser) throws ConfigurationManagerException {
java.net.URL jcfURL = null;
InputStream is = null;
try {
// get a jconfig.properties in classpath, if it exists
ClassLoader cl = this.getClass().getClassLoader();
InputStream jcf = cl.getResourceAsStream( "jconfig.properties" );
// it is possible that the jconfig.properties does not exist, we get null
if ( jcf != null ) {
Properties jcfProperties = new Properties();
jcfProperties.load( jcf );
// load what is set in system
Properties prop = System.getProperties();
// if we see http.proxyHost and/or http.proxyPort inside
// the jconfig.properties, we can set the System.properties
// for use by the URLConnection object
if ( jcfProperties.getProperty( "http.proxyHost" ) != null )
prop.put( "http.proxyHost", jcfProperties.getProperty( "http.proxyHost" ) );
if ( jcfProperties.getProperty( "http.proxyPort" ) != null )
prop.put( "http.proxyPort", jcfProperties.getProperty( "http.proxyPort" ) );
}
// prepare URL, open the connection and grab stream for parsing
jcfURL = new java.net.URL( theURL );
java.net.URLConnection con = jcfURL.openConnection();
is = con.getInputStream();
}
catch ( Exception e ) {
ErrorReporter.getErrorHandler().reportError("Problem with URL handling/connection/validating",e);
throw new ConfigurationManagerException( "Problem with URL handling/connection/validating: "
+ e.getMessage() );
}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(validate);
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
ErrorReporter.getErrorHandler().reportError("The parser cannot create a new document builder",pce);
throw new ConfigurationManagerException("The parser cannot create a new document builder: " + pce.getMessage());
}
// if we have to validate then we need to define an error handler here
if (validate) {
try {
// Set an ErrorHandler before parsing
OutputStreamWriter errorWriter =
new OutputStreamWriter(System.err, "UTF-8");
db.setErrorHandler(
new ConfigErrorHandler(new PrintWriter(errorWriter, true)));
} catch (Exception e) {
ErrorReporter.getErrorHandler().reportError("The parser cannot set up the error handler",e);
throw new ConfigurationManagerException("The parser cannot set up the error handler");
}
}
Document doc = null;
try {
doc = db.parse(is);
} catch (SAXException se) {
ErrorReporter.getErrorHandler().reportError("The parser cannot parse the XML",se);
throw new ConfigurationManagerException("The parser cannot parse the XML: " + se.getMessage());
} catch (IOException ioe) {
ErrorReporter.getErrorHandler().reportError("The parser cannot open the file",ioe);
throw new ConfigurationManagerException("The parser cannot open the file: " + ioe.getMessage());
}
Configuration config = parser.parse(doc, configName);
config.resetCreated();
return config;
}
/** This method should store all categories and properties.
* @throws ConfigurationManagerException
*/
public void store(Configuration configuration) throws ConfigurationManagerException {
}
//Steve Braun - addition
public void addFileListener( FileListener fileListener ) {
try {
String val = ConfigurationUtils.getConfigProperty("jconfig.filewatcher","true");
if ( val.equalsIgnoreCase("true") ) {
watcher = new URLFileWatcher( getURL() );
watcher.addFileListener( fileListener );
watcher.start();
}
}
catch ( Exception e ) {
ErrorReporter.getErrorHandler().reportError("Problem while setting up the watcher",e);
}
}
public String getURL() {
return ( url );
}
}