All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.logicalcobwebs.proxool.configuration.XMLConfigurator Maven / Gradle / Ivy

The newest version!
/*
 * This software is released under a licence similar to the Apache Software Licence.
 * See org.logicalcobwebs.proxool.package.html for details.
 * The latest version is available at http://proxool.sourceforge.net
 */
package org.logicalcobwebs.proxool.configuration;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.logicalcobwebs.proxool.ProxoolConstants;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.Properties;

/**
 * 

A SAX 2 ContentHandler that can configure Proxool from an XML source.

* *

This is just a ContentHandler, so you must associate it with a SAX parser for it to actually do anything. * If you have JAXP available {@link JAXPConfigurator} will do this for you.

* *

Properties that you pass on to the delegate driver have to be treated specially. They * must be contained within a <driver-properties> element.

* *

See the Proxool properties for documentation * on the available configuration properties.

* * Example configuration: *
 * <proxool>
 *     <alias>apple</alias>
 *     <driver-url>jdbc:hsqldb:.</driver-url>
 *     <driver-class>org.hsqldb.jdbcDriver</driver-class>
 *     <driver-properties>
 *         <property name="user" value="abc" />
 *         <property name="password" value="def" />
 *     </driver-properties>
 *     <house-keeping-sleep-time>40000</house-keeping-sleep-time>
 *     <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
 *     <maximum-connection-count>10</maximum-connection-count>
 *     <minimum-connection-count>3</minimum-connection-count>
 *     <maximum-connection-lifetime>18000000</maximum-connection-lifetime> <!-- 5 hours -->
 *     <simultaneous-build-throttle>5</simultaneous-build-throttle>
 *     <recently-started-threshold>40000</recently-started-threshold>
 *     <overload-without-refusal-lifetime>50000</overload-without-refusal-lifetime>
 *     <maximum-active-time>60000</maximum-active-time>
 *     <verbose>true</verbose>
 *     <trace>true</trace>
 *     <fatal-sql-exception>ORA-1234</fatal-sql-exception>
 *     <prototype-count>2</prototype-count>
 * </proxool>
 * 
* * When the parser reaches the end of the <proxool> element the pool * is automatically registered. You can contain the <proxool> element * in any other elements as you wish. And the <proxool> element can * occur as many times as you wish. This allows you to use an XML file that * configures your whole application as the source. This configurator will * ignore everything apart from the elements contained within the <proxool> * element. *

* Validation
* A couple of additional steps are required if you want your SAX parser to validate your Proxool xml confguration: *

    *
  • * Put your proxool configuration elements inside a root proxool-config element. * The document must adhere to the Proxool dtd. *
  • *
  • * Add a DOCTYPE entry to your xml with a system id containing the absolute url to the Proxool * dtd. The Proxool jar contains a copy of the Proxool dtd in the confguration package. You can reference that with * a jar url like this:
    * <!DOCTYPE proxool-config SYSTEM "jar:file:///C:/Proxool/lib/proxool.jar!/org/logicalcobwebs/proxool/configuration/proxool.dtd">
  • *
  • * Configure your parser to be validating. In the {@link JAXPConfigurator} this is done by passing true as * the second arghument to any of the configure methods. *
  • *
*

*

This class is not thread safe.

* * @version $Revision: 1.18 $, $Date: 2006/01/18 14:39:58 $ * @author billhorsman * @author $Author: billhorsman $ (current maintainer) */ public class XMLConfigurator extends DefaultHandler { private static final Log LOG = LogFactory.getLog(XMLConfigurator.class); private StringBuffer content = new StringBuffer(); private String poolName; private String driverClass; private String driverUrl; private Properties properties = new Properties(); private static final String PROXOOL = "proxool"; private static final String DRIVER_PROPERTIES = "driver-properties"; private static final String PROPERTY = "property"; private static final String NAME = "name"; private static final String VALUE = "value"; private boolean insideDelegateProperties; private boolean insideProxool; /** * @see org.xml.sax.ContentHandler#startElement */ public void startElement(String uri, String lname, String qname, Attributes attributes) throws SAXException { content.setLength(0); if (!namespaceOk(uri)) { return; } final String elementName = getElementName(uri, lname, qname); if (elementName.equals(PROXOOL)) { if (insideProxool) { throw new SAXException("A <" + PROXOOL + "> element can't contain another <" + PROXOOL + "> element."); } insideProxool = true; properties.clear(); driverClass = null; driverUrl = null; } if (insideProxool) { if (elementName.equals(DRIVER_PROPERTIES)) { insideDelegateProperties = true; } else if (insideDelegateProperties) { if (elementName.equals(PROPERTY)) { setDriverProperty(attributes); } } } } /** * @see org.xml.sax.ContentHandler#characters */ public void characters(char[] chars, int start, int length) throws SAXException { if (insideProxool) { content.append(chars, start, length); } } /** * @see org.xml.sax.ContentHandler#endElement */ public void endElement(String uri, String lname, String qname) throws SAXException { if (!namespaceOk(uri)) { return; } final String elementName = getElementName(uri, lname, qname); // Are we ending a proxool configuration section? if (elementName.equals(PROXOOL)) { // Check that we have defined the minimum information if (driverClass == null || driverUrl == null) { throw new SAXException("You must define the " + ProxoolConstants.DRIVER_CLASS + " and the " + ProxoolConstants.DRIVER_URL + "."); } // Build the URL; optinally defining a name StringBuffer url = new StringBuffer(); url.append("proxool"); if (poolName != null) { url.append(ProxoolConstants.ALIAS_DELIMITER); url.append(poolName); } url.append(ProxoolConstants.URL_DELIMITER); url.append(driverClass); url.append(ProxoolConstants.URL_DELIMITER); url.append(driverUrl); if (LOG.isDebugEnabled()) { LOG.debug("Created url: " + url); } // Register the pool try { ProxoolFacade.registerConnectionPool(url.toString(), properties); } catch (ProxoolException e) { throw new SAXException(e); } // This ensures we ignore remaining XML until we come across another // element. insideProxool = false; } if (insideProxool && !elementName.equals(PROXOOL)) { if (elementName.equals(DRIVER_PROPERTIES)) { insideDelegateProperties = false; } else if (!insideDelegateProperties) { setProxoolProperty(elementName, content.toString().trim()); } } } private void setProxoolProperty(String localName, String value) { if (localName.equals(ProxoolConstants.ALIAS)) { poolName = value; } else if (localName.equals(ProxoolConstants.DRIVER_CLASS)) { driverClass = value; } else if (localName.equals(ProxoolConstants.DRIVER_URL)) { driverUrl = value; } else { if (LOG.isDebugEnabled()) { LOG.debug("Setting property '" + ProxoolConstants.PROPERTY_PREFIX + localName + "' to value '" + value + "'."); } properties.put(ProxoolConstants.PROPERTY_PREFIX + localName, value); } } private void setDriverProperty(Attributes attributes) throws SAXException { final String name = attributes.getValue(NAME); final String value = attributes.getValue(VALUE); if (name == null || name.length() < 1 || value == null) { throw new SAXException("Name or value attribute missing from property element." + "Name: '" + name + "' Value: '" + value + "'."); } if (LOG.isDebugEnabled()) { if (name.toLowerCase().indexOf("password") > -1) { LOG.debug("Adding driver property: " + name + "=" + "*******"); } else { LOG.debug("Adding driver property: " + name + "=" + value); } } properties.put(name, value); } /** * @see org.xml.sax.ErrorHandler#warning(SAXParseException) */ public void warning(SAXParseException e) throws SAXException { // Just debug-log the warning. We'll probably survive. LOG.debug("The saxparser reported a warning.", e); } /** * @see org.xml.sax.ErrorHandler#error(SAXParseException) */ public void error(SAXParseException e) throws SAXException { // On error we rethrow the exception. // This should cause the parser stop and an exeption be thrown back to the client. throw e; } /** * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException) */ public void fatalError(SAXParseException e) throws SAXException { // On fatal error we rethrow the exception. // This should cause the parser stop and an exeption be thrown back to the client. throw e; } // If no namespace use qname, else use lname. private String getElementName(String uri, String lname, String qname) { if (uri == null || "".equals(uri)) { return qname; } else { return lname; } } private boolean namespaceOk(String uri) { return uri == null || uri.length() == 0 || uri.equals(ProxoolConstants.PROXOOL_XML_NAMESPACE_URI); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy