[loom] properties in configuration
Ryan Hoegg <[email protected]>
| Newsgroups | gmane.comp.java.jcontainer.interest |
|---|---|
| Message-ID | <[email protected]> |
Hi, OK here's a patch and some new classes. I did it by subclassing org.jcontainer.dna.impl.SAXConfigurationHandler. Going forward the test case will probably end up looking a lot different, I just wanted pdonald to see the code so he could stew on how best to allow reuse of some of the DNA test logic. The idea is just to make sure the LoomSAXConfigurationHandler behaves as any SAXConfigurationHandler should, while also testing that it performs its extra functionality correctly. -- Ryan Hoegg ISIS Networks http://www.isisnetworks.net
loom-config-properties.patch
(text/plain, 7.6 KB)
Index: project.xml
===================================================================
RCS file: /cvsroot/jcontainer/jcontainer/loom/engine/project.xml,v
retrieving revision 1.30
diff -u -r1.30 project.xml
--- project.xml 3 Nov 2003 04:32:59 -0000 1.30
+++ project.xml 18 Nov 2003 09:55:13 -0000
@@ -33,7 +33,7 @@
<dependency>
<groupId>dna</groupId>
<artifactId>dna-impl</artifactId>
- <version>20031005.014103</version>
+ <version>SNAPSHOT</version>
</dependency>
<dependency>
<id>logkit</id>
@@ -161,6 +161,8 @@
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
+ <exclude>**/Mock*.java</exclude>
+ <exclude>org/jcontainer/dna/impl/SAXConfigurationHandlerTestCase.java</exclude>
</excludes>
<resources>
<resource>
Index: src/java/org/jcontainer/loom/components/deployer/DefaultDeployer.java
===================================================================
RCS file: /cvsroot/jcontainer/jcontainer/loom/engine/src/java/org/jcontainer/loom/components/deployer/DefaultDeployer.java,v
retrieving revision 1.23
diff -u -r1.23 DefaultDeployer.java
--- src/java/org/jcontainer/loom/components/deployer/DefaultDeployer.java 3 Nov 2003 06:43:15 -0000 1.23
+++ src/java/org/jcontainer/loom/components/deployer/DefaultDeployer.java 18 Nov 2003 09:55:14 -0000
@@ -87,11 +87,14 @@
package org.jcontainer.loom.components.deployer;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import org.apache.avalon.phoenix.BlockContext;
import org.jcomponent.loggerstore.LoggerStore;
@@ -333,16 +336,7 @@
{
//m_baseWorkDirectory
installation = m_installer.install( name, location );
-
- final Configuration config =
- getConfigurationFor( installation, ContainerConstants.INSTALL_CONFIG, null );
- final Configuration environment =
- getConfigurationFor( installation, ContainerConstants.INSTALL_ENVIRONMENT, null );
- final Configuration assembly =
- getConfigurationFor( installation,
- ContainerConstants.INSTALL_ASSEMBLY,
- ConfigurationBuilder.ASSEMBLY_SCHEMA );
-
+
final File homeDirectory =
(File)installation.get( ContainerConstants.INSTALL_HOME );
final File workDirectory =
@@ -351,6 +345,30 @@
final Map data = new HashMap();
data.put( BlockContext.APP_NAME, name );
data.put( BlockContext.APP_HOME_DIR, homeDirectory );
+
+ Properties configProperties = new Properties();
+ try
+ {
+ configProperties.load(
+ new FileInputStream(new File(homeDirectory, "config.properties")));
+ }
+ catch (FileNotFoundException npe)
+ {
+ // swallow it
+ }
+
+ configProperties.put("app.name", name);
+ configProperties.put("app.home", homeDirectory);
+
+ final Configuration config =
+ getConfigurationFor( installation, ContainerConstants.INSTALL_CONFIG, configProperties, null );
+ final Configuration environment =
+ getConfigurationFor( installation, ContainerConstants.INSTALL_ENVIRONMENT, null, null );
+ final Configuration assembly =
+ getConfigurationFor( installation,
+ ContainerConstants.INSTALL_ASSEMBLY,
+ null,
+ ConfigurationBuilder.ASSEMBLY_SCHEMA );
final Configuration logs = environment.getChild( "logs", false );
//Load hierarchy before classloader placed in context as
@@ -431,16 +449,25 @@
*
* @param install the install data
* @param key the key under which config data is stored in install data
+ * @param properties properties to replace in the configuration
+ * @param schema the schema against which to validate the configuration xml
* @return the Configuration
* @throws LoomException if an error occurs
*/
- private Configuration getConfigurationFor( final Map install, final String key, final String schema )
+ private Configuration getConfigurationFor( final Map install,
+ final String key,
+ final Map properties,
+ final String schema )
throws LoomException
{
final String location = (String)install.get( key );
try
{
- return ConfigurationBuilder.build( new InputSource( location ), schema, getLogger() );
+ return ConfigurationBuilder.build(
+ new InputSource( location ),
+ properties,
+ schema,
+ getLogger() );
}
catch( final Exception e )
{
Index: src/java/org/jcontainer/loom/components/util/ConfigurationBuilder.java
===================================================================
RCS file: /cvsroot/jcontainer/jcontainer/loom/engine/src/java/org/jcontainer/loom/components/util/ConfigurationBuilder.java,v
retrieving revision 1.2
diff -u -r1.2 ConfigurationBuilder.java
--- src/java/org/jcontainer/loom/components/util/ConfigurationBuilder.java 16 Oct 2003 14:45:46 -0000 1.2
+++ src/java/org/jcontainer/loom/components/util/ConfigurationBuilder.java 18 Nov 2003 09:55:14 -0000
@@ -8,13 +8,14 @@
package org.jcontainer.loom.components.util;
import java.io.IOException;
+import java.util.Map;
+
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.framework.CascadingException;
import org.jcontainer.dna.Configuration;
import org.jcontainer.dna.Logger;
-import org.jcontainer.dna.impl.SAXConfigurationHandler;
import org.realityforge.configkit.ConfigValidator;
import org.realityforge.configkit.ConfigValidatorFactory;
import org.realityforge.configkit.ResolverFactory;
@@ -52,8 +53,26 @@
final Logger logger )
throws Exception
{
+ return ConfigurationBuilder.build(input, null, publicId, logger);
+ }
+
+ /**
+ * Build a configuration object using an XML InputSource object, and
+ * optionally validate the xml against the DTD. Replace properties
+ * using <code>${property.key}</code> syntax with their values from
+ * the Map.
+ *
+ * @param properties the properties replace in the configuration values
+ */
+ public static Configuration build( final InputSource input,
+ final Map properties,
+ final String publicId,
+ final Logger logger )
+ throws Exception
+ {
setupResolver();
- final SAXConfigurationHandler handler = new SAXConfigurationHandler();
+ final LoomSAXConfigurationHandler handler = new LoomSAXConfigurationHandler();
+ handler.setProperties(properties);
if( null == publicId )
{
final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
LoomSAXConfigurationHandler.java
(text/plain, 2.3 KB)
/* * Copyright (C) The JContainer Group. All rights reserved. * * This software is published under the terms of the JContainer * Software License version 1.1, a copy of which has been included * with this distribution in the LICENSE.txt file. */ package org.jcontainer.loom.components.util; import java.util.Map; import org.jcontainer.dna.Configuration; import org.jcontainer.dna.impl.SAXConfigurationHandler; import org.realityforge.configkit.PropertyExpander; /** * Extension of the SAXConfigurationHandler that expands property values. * * @see org.realityforge.configkit.PropertyExpander * * @author <a href="mailto:[email protected]">Ryan Hoegg</a> * @version $Revision$ $Date$ */ public class LoomSAXConfigurationHandler extends SAXConfigurationHandler { private Map m_properties; public void setProperties(final Map properties) { m_properties = properties; } /** * Replaces properties with their values in each text node of the * Configuration. Properties are delimited by ${...}. * * @see org.jcontainer.dna.impl.SAXConfigurationHandler#processValueText(org.jcontainer.dna.Configuration, java.lang.String) */ protected String processValueText( Configuration configuration, String value) { return expandProperties( super.processValueText(configuration, value), m_properties); } /** * Replaces properties with their values in each attribute of the * Configuration. Properties are delimited by ${...}. */ protected String processAttributeText( Configuration configuration, String name, String value) { return expandProperties( super.processAttributeText(configuration, name, value), m_properties); } private String expandProperties(String unprocessed, Map properties) { if ( null != properties ) { PropertyExpander expander = new PropertyExpander(); try { return expander.expandValues(unprocessed, properties); } catch ( Exception e ) { /* TODO: swallowed for now, should eventually inform * some monitor class for logging or whatever. */ } } return unprocessed; } }
LoomSAXConfigurationHandlerTestCase.java
(text/plain, 4.1 KB)
/* * Copyright (C) The JContainer Group. All rights reserved. * * This software is published under the terms of the JContainer * Software License version 1.1, a copy of which has been included * with this distribution in the LICENSE.txt file. */ package org.jcontainer.loom.components.util; import java.util.HashMap; import java.util.Map; import org.jcontainer.dna.Configuration; import org.jcontainer.dna.impl.SAXConfigurationHandler; import org.jcontainer.dna.impl.SAXConfigurationHandlerTestCase; import org.xml.sax.helpers.AttributesImpl; /** * Ensures that the LoomSAXConfigurationHandlerTestCase does everything * the SAXConfigurationHandlerTestCase does, as well as replaces properties * given to it using the setProperties method. * * @author <a href="mailto:[email protected]">Ryan Hoegg</a> * @version $Revision$ $Date$ */ public class LoomSAXConfigurationHandlerTestCase extends SAXConfigurationHandlerTestCase { private final Map props = new HashMap(); private final String testProperty = "test.property"; private final String testValue = "REPLACED PROPERTY VALUE"; public LoomSAXConfigurationHandlerTestCase() { super(); props.put(testProperty, testValue); } /** * This would override a method in the parent class that * is used whenever it wants to test a conformant handler * * @return SAXConfigurationHandler of the subtype that is being tested */ protected SAXConfigurationHandler createHandler() { return new LoomSAXConfigurationHandler(); } /** * Tests creating a configuration while replacing properties with * their values in text values */ public void testCreateConfigurationWithValueThatIsIntercepted() throws Exception { final LoomSAXConfigurationHandler loomHandler = new LoomSAXConfigurationHandler(); loomHandler.setProperties(props); final SAXConfigurationHandler handler = loomHandler; final String qName = "myElement"; final String value = "value is ${" + testProperty + "}"; handler.startElement( "", "", qName, new AttributesImpl() ); handler.characters( value.toCharArray(), 0, value.length() ); handler.endElement( "", "", qName ); final Configuration configuration = handler.getConfiguration(); assertEquals( "configuration.name", qName, configuration.getName() ); assertEquals( "configuration.location", "", configuration.getLocation() ); assertEquals( "configuration.path", "", configuration.getPath() ); assertEquals( "configuration.value", "value is " + testValue, configuration.getValue() ); } /** * Tests creating a configuration while replacing properties with * their values in attribute values */ public void testCreateConfigurationWithAttributesWithInterception() throws Exception { final LoomSAXConfigurationHandler loomHandler = new LoomSAXConfigurationHandler(); loomHandler.setProperties(props); SAXConfigurationHandler handler = loomHandler; final String qName = "myElement"; final AttributesImpl attributes = new AttributesImpl(); attributes.addAttribute( "", "", testProperty, "CDATA", "${" + testProperty + "} is now the value." ); handler.startElement( "", "", qName, attributes ); handler.endElement( "", "", qName ); final Configuration configuration = handler.getConfiguration(); assertEquals( "configuration.name", qName, configuration.getName() ); assertEquals( "configuration.location", "", configuration.getLocation() ); assertEquals( "configuration.path", "", configuration.getPath() ); final String[] names = configuration.getAttributeNames(); assertEquals( "names.length", 1, names.length ); assertEquals( "names[0]", testProperty, names[ 0 ] ); assertEquals( "configuration.getAttribute( names[ 0 ] )", testValue + " is now the value.", configuration.getAttribute( names[ 0 ] ) ); } }