hlship 2003/08/04 07:21:57
Modified: hivemind/src/test/hivemind/test/config
TestExtensionPoint.java
hivemind/src/java/org/apache/commons/hivemind/schema
SchemaProcessor.java Translator.java
hivemind/src/java/org/apache/commons/hivemind/parse
DescriptorParser.java
AbstractServiceDescriptor.java
hivemind/src/test/hivemind/test HiveMindSuite.java
hivemind/src/java/org/apache/commons/hivemind/schema/rules
ReadContentRule.java BooleanTranslator.java
SetParentRule.java BaseRule.java IntTranslator.java
ReadAttributeRule.java
hivemind/src/java/org/apache/commons/hivemind
HiveMindMessages.properties HiveMind.java
hivemind/xdocs rules.xml
hivemind/src/java/org/apache/commons/hivemind/impl
RegistryBuilder.java
Added: hivemind/src/test/hivemind/test/config IntTranslator.xml
hivemind/src/java/org/apache/commons/hivemind/schema/rules
RuleUtils.java
hivemind/src/test/hivemind/test/rules
TestConvertInitializer.java
hivemind/src/test/hivemind/test/config/impl IntHolder.java
Log:
Add support for initializers for Translators. Initializers are strings used to
configure a Translator.
Revision Changes Path
1.4 +41 -0
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/config/TestExtensionPoint.java
Index: TestExtensionPoint.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/config/TestExtensionPoint.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TestExtensionPoint.java 1 Aug 2003 14:41:29 -0000 1.3
+++ TestExtensionPoint.java 4 Aug 2003 14:21:56 -0000 1.4
@@ -63,6 +63,7 @@
import hivemind.test.config.impl.Datum;
import hivemind.test.config.impl.DatumHolder;
import hivemind.test.config.impl.FrobableHolder;
+import hivemind.test.config.impl.IntHolder;
import hivemind.test.config.impl.Parent;
import java.util.List;
@@ -213,6 +214,46 @@
h = (BooleanHolder) l.get(2);
assertEquals(false, h.getValue());
+ }
+
+ public void testIntTranslator() throws Exception
+ {
+ interceptLogging();
+
+ Registry r = buildRegistry("IntTranslator.xml");
+
+ List l = r.getExtensionPointElements("hivemind.test.config.IntTranslator");
+
+ List events = getInterceptedLogEvents();
+
+ checkLoggingEvent(null, "Value 2 \\(at .*\\) is less than minimum value
5\\.", events);
+ checkLoggingEvent(null, "Value 12 \\(at .*\\) is greater than maximum value
10\\.", events);
+ checkLoggingEvent(
+ null,
+ "'fred' \\(in element int at .*\\) is not an integer value\\.",
+ events);
+
+ assertEquals(4, l.size());
+
+ IntHolder h = (IntHolder) l.get(0);
+
+ assertEquals(7, h.getValue());
+
+ h = (IntHolder) l.get(1);
+ assertEquals(5, h.getValue());
+
+ h = (IntHolder) l.get(2);
+
+ assertEquals(10, h.getValue());
+
+ h = (IntHolder)l.get(3);
+
+ assertEquals(6, h.getValue());
+
+ h = (IntHolder)l.get(3);
+
+ assertEquals(6, h.getValue());
+
}
public void testClassTranslator() throws Exception
1.1
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/config/IntTranslator.xml
Index: IntTranslator.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: IntTranslator.xml,v 1.1 2003/08/04 14:21:56 hlship Exp $ -->
<module id="hivemind.test.config" version="1.0.0">
<extension-point id="IntTranslator">
<schema>
<element name="int">
<attribute name="value" required="true"/>
<rules>
<create-object
class="hivemind.test.config.impl.IntHolder"/>
<read-attribute property="value"
attribute="value" translator="int,min=5,max=10,default=6"/>
<invoke-parent method="addElement"/>
</rules>
</element>
</schema>
</extension-point>
<extension point-id="IntTranslator">
<int value="7"/>
<int value="2"/>
<int value="12"/>
<int value="fred"/>
<int/>
</extension>
</module>
1.2 +2 -2
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/SchemaProcessor.java
Index: SchemaProcessor.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/SchemaProcessor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SchemaProcessor.java 29 Jul 2003 22:20:36 -0000 1.1
+++ SchemaProcessor.java 4 Aug 2003 14:21:56 -0000 1.2
@@ -71,7 +71,7 @@
/**
* The SchemaProcessor is always the bottom (deepest) object on the stack.
* Top level objects (contained by a schema, not another element)
- * can use an [EMAIL PROTECTED]
org.apache.commons.hivemind.schema.rules.AddToParentRule}
+ * can use an [EMAIL PROTECTED]
org.apache.commons.hivemind.schema.rules.InvokeParentRule}
* to add themselves to the list of elements for the
* [EMAIL PROTECTED] org.apache.commons.hivemind.ExtensionPoint} being
constructed.
*/
1.2 +17 -1
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/Translator.java
Index: Translator.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/Translator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Translator.java 29 Jul 2003 22:20:36 -0000 1.1
+++ Translator.java 4 Aug 2003 14:21:56 -0000 1.2
@@ -64,6 +64,22 @@
* translate attribute values (or element content) from strings into
* numbers, booleans or other constructs before assigning the final value
* to a propery. Translation occurs after symbol substitution.
+ *
+ * <p>
+ * Translator classes should have a public constructor that takes no
+ * arguments. They may optionally have a second constructor
+ * that takes a single string as a parameter. When the
+ * [EMAIL PROTECTED] org.apache.commons.hivemind.parse.DescriptorParser} encounters
+ * a <code>translator</code> of the form
+ * "<code><i>translator-id</i>,<i>initializataion-string</i></code>"
+ * (example: "int,min=0") it will use the second constructor, passing
+ * the initialization string.
+ *
+ * <p>
+ * Generally, initializion strings are of the form
+ * <code><i>key</i>=<i>value</i>[,<i>key</i>=<i>value</i>]*</code>.
+ * Each initializer has a set of keys it recognizes, other keys are simply
+ * ignored.
*
* @author Howard Lewis Ship
* @version $Id$
1.18 +61 -11
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java
Index: DescriptorParser.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- DescriptorParser.java 1 Aug 2003 19:05:24 -0000 1.17
+++ DescriptorParser.java 4 Aug 2003 14:21:56 -0000 1.18
@@ -57,6 +57,7 @@
package org.apache.commons.hivemind.parse;
+import java.lang.reflect.Constructor;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
@@ -298,16 +299,17 @@
OCCURS_MAP.put("0..n", Occurances.UNBOUNDED);
}
+ private final Map _builtinTranslators = new HashMap();
private final Map _translatorMap = new HashMap();
// Seed the translator map with shared instances of built-in
// translators.
{
- _translatorMap.put("boolean", new BooleanTranslator());
- _translatorMap.put("class", new ClassTranslator());
- _translatorMap.put("int", new IntTranslator());
- _translatorMap.put("service", new ServiceTranslator());
+ _builtinTranslators.put("boolean", BooleanTranslator.class);
+ _builtinTranslators.put("class", ClassTranslator.class);
+ _builtinTranslators.put("int", IntTranslator.class);
+ _builtinTranslators.put("service", ServiceTranslator.class);
}
/**
@@ -1285,34 +1287,82 @@
return getTranslator(name);
}
+ /**
+ * The name may be a class name or a builtin id. In addition,
+ * an initializer may follow the name or id (separated by a comma).
+ */
private Translator getTranslator(String name)
{
Translator result = (Translator) _translatorMap.get(name);
- if (result == null)
+ if (result != null)
+ return result;
+
+ String className = name;
+ String initializer = null;
+
+ int commax = name.indexOf(',');
+
+ if (commax > 0)
{
- result = createTranslator(name);
+ className = name.substring(0, commax);
+ initializer = name.substring(commax + 1);
+ }
+
+ Class translatorClass = findTranslatorClass(className);
+ result = createTranslator(translatorClass, initializer);
+
+ if (result != null)
_translatorMap.put(name, result);
+
+ return result;
+
+ }
+
+ /**
+ * Finds the class for a translator based on class name. In addition,
+ * certain builtin ids are recognized.
+ */
+ private Class findTranslatorClass(String className)
+ {
+ Class result = (Class) _builtinTranslators.get(className);
+
+ if (result == null)
+ {
+ result = _resolver.findClass(className);
+ _builtinTranslators.put(className, result);
}
return result;
}
- private Translator createTranslator(String name)
+ private Translator createTranslator(Class translatorClass, String initializer)
{
try
{
- Class translatorClass = _resolver.findClass(name);
- return (Translator) translatorClass.newInstance();
+ if (initializer == null)
+ return (Translator) translatorClass.newInstance();
+
+ Constructor c = translatorClass.getConstructor(new Class[] {
String.class });
+
+ return (Translator) c.newInstance(new Object[] { initializer });
+ }
+ catch (NoSuchMethodException ex)
+ {
+ LOG.error(
+ HiveMind.format(
+ "DescriptorParser.missing-translator",
+ translatorClass.getName(),
+ getLocation()));
}
catch (Exception ex)
{
LOG.error(
HiveMind.format(
"DescriptorParser.bad-translator",
- name,
+ translatorClass.getName(),
getLocation(),
ex.getMessage()),
ex);
1.9 +2 -2
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/AbstractServiceDescriptor.java
Index: AbstractServiceDescriptor.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/AbstractServiceDescriptor.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- AbstractServiceDescriptor.java 29 Jul 2003 22:20:38 -0000 1.8
+++ AbstractServiceDescriptor.java 4 Aug 2003 14:21:56 -0000 1.9
@@ -65,7 +65,7 @@
/**
* Base class for [EMAIL PROTECTED]
org.apache.commons.hivemind.parse.ServiceDescriptor} and
- * [EMAIL PROTECTED] org.apache.commons.hivemind.parse.ServiceExtensionDescriptor}.
+ * [EMAIL PROTECTED] org.apache.commons.hivemind.parse.ExtendServiceDescriptor}.
*
*
* @author Howard Lewis Ship
1.10 +4 -1
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/HiveMindSuite.java
Index: HiveMindSuite.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/HiveMindSuite.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- HiveMindSuite.java 29 Jul 2003 22:20:32 -0000 1.9
+++ HiveMindSuite.java 4 Aug 2003 14:21:56 -0000 1.10
@@ -62,6 +62,7 @@
import hivemind.test.config.TestExtensionPoint;
import hivemind.test.parse.TestDescriptorParser;
import hivemind.test.parse.TestToString;
+import hivemind.test.rules.*;
import hivemind.test.services.TestServices;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -78,6 +79,8 @@
public static Test suite()
{
TestSuite suite = new TestSuite("Master HiveMind Test Suite");
+
+ suite.addTestSuite(TestConvertInitializer.class);
suite.addTestSuite(TestMessagesImpl.class);
1.3 +3 -3
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/ReadContentRule.java
Index: ReadContentRule.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/ReadContentRule.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ReadContentRule.java 1 Aug 2003 14:41:30 -0000 1.2
+++ ReadContentRule.java 4 Aug 2003 14:21:56 -0000 1.3
@@ -81,12 +81,12 @@
public void begin(SchemaProcessor processor, Element element)
{
- String value = processText(processor, element, element.getContent());
+ String value = RuleUtils.processText(processor, element,
element.getContent());
Object finalValue =
_translator == null ? value : _translator.translate(processor, element,
value);
- setProperty(processor, element, _propertyName, processor.peek(),
finalValue);
+ RuleUtils.setProperty(processor, element, _propertyName, processor.peek(),
finalValue);
}
public String getPropertyName()
1.2 +28 -4
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/BooleanTranslator.java
Index: BooleanTranslator.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/BooleanTranslator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BooleanTranslator.java 29 Jul 2003 22:20:48 -0000 1.1
+++ BooleanTranslator.java 4 Aug 2003 14:21:56 -0000 1.2
@@ -57,6 +57,8 @@
package org.apache.commons.hivemind.schema.rules;
+import java.util.Map;
+
import org.apache.commons.hivemind.Element;
import org.apache.commons.hivemind.HiveMind;
import org.apache.commons.hivemind.schema.SchemaProcessor;
@@ -76,10 +78,32 @@
{
private static final Log LOG = LogFactory.getLog(BooleanTranslator.class);
+ private Boolean _defaultValue = Boolean.FALSE;
+
+ public BooleanTranslator()
+ {
+ }
+
+ /**
+ * Initializes the translator, recognizing key "default" as the
+ * default value for the translator when the input is null or
+ * can't be converted.
+ */
+
+ public BooleanTranslator(String initializer)
+ {
+ Map m = RuleUtils.convertInitializer(initializer);
+
+ String defaultInit = (String) m.get("default");
+
+ if (defaultInit != null)
+ _defaultValue = Boolean.valueOf(defaultInit);
+ }
+
public Object translate(SchemaProcessor processor, Element element, String
inputValue)
{
if (StringUtils.isEmpty(inputValue))
- return Boolean.FALSE;
+ return _defaultValue;
if (inputValue.equals("true"))
return Boolean.TRUE;
@@ -93,8 +117,8 @@
inputValue,
processor.getElementPath(),
element.getLocation()));
-
- return Boolean.FALSE;
+
+ return _defaultValue;
}
}
1.2 +2 -2
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/SetParentRule.java
Index: SetParentRule.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/SetParentRule.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SetParentRule.java 29 Jul 2003 22:20:48 -0000 1.1
+++ SetParentRule.java 4 Aug 2003 14:21:56 -0000 1.2
@@ -88,7 +88,7 @@
Object child = processor.peek();
Object parent = processor.peek(1);
- setProperty(processor, element, _propertyName, child, parent);
+ RuleUtils.setProperty(processor, element, _propertyName, child, parent);
}
}
1.3 +1 -74
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/BaseRule.java
Index: BaseRule.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/BaseRule.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BaseRule.java 1 Aug 2003 14:41:30 -0000 1.2
+++ BaseRule.java 4 Aug 2003 14:21:56 -0000 1.3
@@ -57,14 +57,9 @@
package org.apache.commons.hivemind.schema.rules;
-import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.hivemind.Element;
-import org.apache.commons.hivemind.HiveMind;
-import org.apache.commons.hivemind.Registry;
import org.apache.commons.hivemind.schema.Rule;
import org.apache.commons.hivemind.schema.SchemaProcessor;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.spec.BaseLocatable;
/**
@@ -75,74 +70,6 @@
*/
public abstract class BaseRule extends BaseLocatable implements Rule
{
- private static final Log LOG = LogFactory.getLog(BaseRule.class);
-
- /**
- * Invoked to process text from an attribute or from an element's content.
Performs
- * two jobs:
- * <ul>
- * <li>Convert localized message references to localized strings
- * <li>Expand symbols using [EMAIL PROTECTED] Registry#expandSymbols(String,
ILocation)}
- * </ul>
- *
- * <p>
- * Note: if the input is a localized message then no symbol expansion takes
place.
- * Localized message references are simply strings that begin with '%'. The
remainder
- * of the string is the message key.
- *
- * <p>
- * A null input value passes through unchanged.
- */
- protected String processText(SchemaProcessor processor, Element element, String
inputValue)
- {
- if (inputValue == null)
- return null;
-
- if (inputValue.startsWith("%"))
- {
- String key = inputValue.substring(1);
-
- return processor.getContributingModule().getMessages().getMessage(key);
- }
-
- Registry registry = processor.getContributingModule().getRegistry();
-
- return registry.expandSymbols(inputValue, element.getLocation());
- }
-
- /**
- * Sets a property of the target object to the given value.
- * Logs an error if there is a problem.
- */
- protected void setProperty(
- SchemaProcessor processor,
- Element element,
- String propertyName,
- Object target,
- Object value)
- {
- try
- {
- BeanUtils.setProperty(target, propertyName, value);
- }
- catch (Exception ex)
- {
- // Have to decide if we need to display the location of the rule
- // or the element.
-
- LOG.error(
- HiveMind.format(
- "BaseRule.set-property-error",
- new Object[] {
- propertyName,
- target,
- value,
- processor.getElementPath(),
- element.getLocation(),
- ex.getMessage()}));
- }
- }
-
/**
* Does nothing; subclasses may override.
*/
1.2 +74 -4
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/IntTranslator.java
Index: IntTranslator.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/IntTranslator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IntTranslator.java 29 Jul 2003 22:20:48 -0000 1.1
+++ IntTranslator.java 4 Aug 2003 14:21:56 -0000 1.2
@@ -57,6 +57,8 @@
package org.apache.commons.hivemind.schema.rules;
+import java.util.Map;
+
import org.apache.commons.hivemind.Element;
import org.apache.commons.hivemind.HiveMind;
import org.apache.commons.hivemind.schema.SchemaProcessor;
@@ -75,6 +77,47 @@
{
private static final Log LOG = LogFactory.getLog(IntTranslator.class);
+ private int _minValue;
+ private boolean _isMinValue;
+ private int _maxValue;
+ private boolean _isMaxValue;
+ private int _defaultValue = 0;
+
+ public IntTranslator()
+ {
+ }
+
+ /**
+ * Initializers:
+ * <ul>
+ * <li>default: default value for empty or invalid input
+ * <li>min: minimum acceptible value
+ * <li>max: maximum acceptible value
+ */
+ public IntTranslator(String initializer)
+ {
+ Map m = RuleUtils.convertInitializer(initializer);
+
+ String defaultInit = (String) m.get("default");
+
+ if (defaultInit != null)
+ _defaultValue = Integer.parseInt(defaultInit);
+
+ String minInit = (String) m.get("min");
+ if (minInit != null)
+ {
+ _isMinValue = true;
+ _minValue = Integer.parseInt(minInit);
+ }
+
+ String maxInit = (String) m.get("max");
+ if (maxInit != null)
+ {
+ _isMaxValue = true;
+ _maxValue = Integer.parseInt(maxInit);
+ }
+ }
+
/**
* Converts the string to an Integer. The empty string is returned as zero.
* On failure, an error is logged and the method returns zero.
@@ -82,11 +125,37 @@
public Object translate(SchemaProcessor processor, Element element, String
inputValue)
{
if (StringUtils.isEmpty(inputValue))
- return new Integer(0);
+ return new Integer(_defaultValue);
+
+ int value;
try
{
- return new Integer(inputValue);
+ value = Integer.parseInt(inputValue);
+
+ if (_isMinValue && value < _minValue)
+ {
+ LOG.error(
+ HiveMind.format(
+ "IntTranslator.min-value",
+ inputValue,
+ element.getLocation(),
+ Integer.toString(_minValue)));
+
+ value = _minValue;
+ }
+
+ if (_isMaxValue && value > _maxValue)
+ {
+ LOG.error(
+ HiveMind.format(
+ "IntTranslator.max-value",
+ inputValue,
+ element.getLocation(),
+ Integer.toString(_maxValue)));
+
+ value = _maxValue;
+ }
}
catch (Exception ex)
{
@@ -96,9 +165,10 @@
inputValue,
processor.getElementPath(),
element.getLocation()));
+ value = _defaultValue;
}
- return new Integer(0);
+ return new Integer(value);
}
}
1.3 +3 -3
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/ReadAttributeRule.java
Index: ReadAttributeRule.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/ReadAttributeRule.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ReadAttributeRule.java 1 Aug 2003 14:41:30 -0000 1.2
+++ ReadAttributeRule.java 4 Aug 2003 14:21:56 -0000 1.3
@@ -84,12 +84,12 @@
if (rawValue == null && _skipIfNull)
return;
- String value = processText(processor, element, rawValue);
+ String value = RuleUtils.processText(processor, element, rawValue);
Object finalValue =
_translator == null ? value : _translator.translate(processor, element,
value);
- setProperty(processor, element, _propertyName, processor.peek(),
finalValue);
+ RuleUtils.setProperty(processor, element, _propertyName, processor.peek(),
finalValue);
}
public Translator getTranslator()
1.1
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/schema/rules/RuleUtils.java
Index: RuleUtils.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.hivemind.schema.rules;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.hivemind.Element;
import org.apache.commons.hivemind.HiveMind;
import org.apache.commons.hivemind.Registry;
import org.apache.commons.hivemind.schema.SchemaProcessor;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.ApplicationRuntimeException;
/**
* Static methods useful to [EMAIL PROTECTED]
org.apache.commons.hivemind.schema.Rule}s and
* [EMAIL PROTECTED] org.apache.commons.hivemind.schema.Translator}s.
*
* @author Howard Lewis Ship
* @version $Id: RuleUtils.java,v 1.1 2003/08/04 14:21:56 hlship Exp $
*/
public class RuleUtils
{
private static final Log LOG = LogFactory.getLog(RuleUtils.class);
/**
* Used to convert a [EMAIL PROTECTED]
org.apache.commons.hivemind.schema.Translator}
* initializer string of the form:
* <code><i>key</i>=<i>value</i>[,<i>key</i>=<i>value<i>]*</code>
* into a Map of keys and values. The keys and values are Strings.
*/
public static Map convertInitializer(String initializer)
{
if (StringUtils.isEmpty(initializer))
return Collections.EMPTY_MAP;
Map result = new HashMap();
int lastCommax = -1;
int inputLength = initializer.length();
while (lastCommax < inputLength)
{
int nextCommax = initializer.indexOf(',', lastCommax + 1);
if (nextCommax < 0)
nextCommax = inputLength;
String term = initializer.substring(lastCommax + 1, nextCommax);
int equalsx = term.indexOf('=');
if (equalsx <= 0)
throw new ApplicationRuntimeException(
HiveMind.format("RuleUtils.invalid-initializer", initializer));
String key = term.substring(0, equalsx);
String value = term.substring(equalsx + 1);
result.put(key, value);
lastCommax = nextCommax;
}
return result;
}
/**
* Invoked to process text from an attribute or from an element's content.
Performs
* two jobs:
* <ul>
* <li>Convert localized message references to localized strings
* <li>Expand symbols using [EMAIL PROTECTED] Registry#expandSymbols(String,
ILocation)}
* </ul>
*
* <p>
* Note: if the input is a localized message then no symbol expansion takes
place.
* Localized message references are simply strings that begin with '%'. The
remainder
* of the string is the message key.
*
* <p>
* A null input value passes through unchanged.
*/
public static String processText(SchemaProcessor processor, Element element,
String inputValue)
{
if (inputValue == null)
return null;
if (inputValue.startsWith("%"))
{
String key = inputValue.substring(1);
return processor.getContributingModule().getMessages().getMessage(key);
}
Registry registry = processor.getContributingModule().getRegistry();
return registry.expandSymbols(inputValue, element.getLocation());
}
/**
* Sets a property of the target object to the given value.
* Logs an error if there is a problem.
*/
public static void setProperty(
SchemaProcessor processor,
Element element,
String propertyName,
Object target,
Object value)
{
try
{
BeanUtils.setProperty(target, propertyName, value);
}
catch (Exception ex)
{
// Have to decide if we need to display the location of the rule
// or the element.
LOG.error(
HiveMind.format(
"BaseRule.set-property-error",
new Object[] {
propertyName,
target,
value,
processor.getElementPath(),
element.getLocation(),
ex.getMessage()}));
}
}
}
1.17 +6 -2
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMindMessages.properties
Index: HiveMindMessages.properties
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMindMessages.properties,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- HiveMindMessages.properties 1 Aug 2003 19:05:23 -0000 1.16
+++ HiveMindMessages.properties 4 Aug 2003 14:21:56 -0000 1.17
@@ -40,6 +40,7 @@
DescriptorParser.invalid-numeric-value=''{0}'' (attribute ''{1}'' of {2}, at {3})
can not be converted to a numeric value.
DescriptorParser.bad-translator=Unable to create translator ''{0}'' (at {1}): {2}
DescriptorParser.unknown-schema-id=Element {0} (at {1}) references unknown schema
''{2}''.
+DescriptorParser.missing-translator-constructor=Translator class {0} does not
contain an appropriate constructor (at {1}).
ExternalParser.missing-resource=Unable to locate {0}.
@@ -107,10 +108,13 @@
BooleanTranslator.invalid-value=''{0}'' (in element {1} at {2}) is not a boolean
value (which should be either ''true'' or ''false'').
-IntegerTransaltor.invalid-value=''{0}'' (in element {1} at {2}) is not an integer
value.
+IntTranslator.invalid-value=''{0}'' (in element {1} at {2}) is not an integer value.
+IntTranslator.min-value=Value {0} (at {1}) is less than minimum value {2}.
+IntTranslator.max-value=Value {0} (at {1}) is greater than maximum value {2}.
ServiceTranslator.invalid-value=Error resolving service {0} (in element {1} at
{2}): {3}
+RuleUtils.invalid-initializer=Initializer string (''{0}'') is not in proper format
(key=value[,key=value]*).
# service.impl package
1.12 +13 -4
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMind.java
Index: HiveMind.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMind.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- HiveMind.java 1 Aug 2003 18:26:02 -0000 1.11
+++ HiveMind.java 4 Aug 2003 14:21:56 -0000 1.12
@@ -59,11 +59,11 @@
import java.text.MessageFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.apache.commons.logging.Log;
@@ -136,7 +136,7 @@
return _registry;
}
-
+
/**
* Returns true if the shared registry is not null.
*/
@@ -167,7 +167,16 @@
public static String format(String key, Object[] args)
{
- String pattern = _bundle.getString(key);
+ String pattern = null;
+
+ try
+ {
+ pattern = _bundle.getString(key);
+ }
+ catch (MissingResourceException ex)
+ {
+ pattern = "[" + key.toUpperCase() + "]";
+ }
if (args == null)
return pattern;
1.2 +87 -53 jakarta-commons-sandbox/hivemind/xdocs/rules.xml
Index: rules.xml
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/rules.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- rules.xml 31 Jul 2003 21:06:24 -0000 1.1
+++ rules.xml 4 Aug 2003 14:21:56 -0000 1.2
@@ -55,6 +55,7 @@
are useful for creating hierarchies of objects.
</p>
+
<p>
The available rules are:
<ul>
@@ -66,50 +67,7 @@
</ul>
</p>
-</section>
-
-<section name="Translators">
-
-<p>
-Commonly, it is necessary to perform some translation or transformation of string
attribute value to convert the
-value into some other type, such as boolean, integer or date. This can be
accomplished by specifying a <i>translator</i>
-in the &read-attribute; rule (it also applies to element content, and the
&read-content; rule).
-</p>
-
-<p>
-A translator is an object implementing the
-<a href="apidocs/org/apache/commons/hivemind/schema/Translator.html">Translator</a>
interface. The
-<code>translator</code> value specified in a rule may be either the complete class
name of a class implementing
-the interface, or one of a number of builtin values:
-</p>
-
-<table>
-<tr>
- <th>translator</th>
- <th>Description</th>
- <th>Null/empty handled as</th>
-</tr>
-<tr>
-<td>boolean</td>
-<td>Expects the input to be either "true" or "false".</td>
-<td>false</td>
-</tr>
-<tr>
-<td>int</td>
-<td>Converts to integer value</td>
-<td>0</td>
-</tr>
-<tr>
-<td>service</td>
-<td>Looks up the named service in the registry, using a fully-qualified id</td>
-<td>null</td>
-</tr>
-</table>
-
-
-</section>
-
-<section name="create-object">
+<subsection name="create-object">
<p>
The &_create-object; rule is used to create a new object, which is pushed onto the
stack at <code>begin()</code>.
@@ -133,9 +91,9 @@
</tr>
</table>
-</section>
+</subsection>
-<section name="invoke-parent">
+<subsection name="invoke-parent">
<p>
The &_invoke-parent; rule is used to connect the child (top object on the stack) to
its parent
@@ -167,9 +125,9 @@
(or for service factories, adds the object as a parameter).
</p>
-</section>
+</subsection>
-<section name="read-attribute">
+<subsection name="read-attribute">
<p>
The
@@ -211,9 +169,9 @@
</tr>
</table>
-</section>
+</subsection>
-<section name="read-content">
+<subsection name="read-content">
<p>
The &_read-content; rule is similar to &read-attribute;, except it concerns the
content of the current element
@@ -240,9 +198,9 @@
<td>See <a
href="#Translators">Translators</a></td>
</tr>
</table>
-</section>
+</subsection>
-<section name="set-parent">
+<subsection name="set-parent">
<p>
The &set-parent; rule is used to set a property of the child object to parent
object. This allows
@@ -264,7 +222,83 @@
</tr>
</table>
+</subsection>
+ </section>
+
+<section name="Translators">
+
+<p>
+Commonly, it is necessary to perform some translation or transformation of string
attribute value to convert the
+value into some other type, such as boolean, integer or date. This can be
accomplished by specifying a <i>translator</i>
+in the &read-attribute; rule (it also applies to element content, and the
&read-content; rule).
+</p>
+
+<p>
+A translator is an object implementing the
+<a href="apidocs/org/apache/commons/hivemind/schema/Translator.html">Translator</a>
interface. The
+<code>translator</code> value specified in a rule may be either the complete class
name of a class implementing
+the interface, or one of a number of builtin values.
+</p>
+
+<p>
+Translators can be configured using <i>initializer strings</i>. The initializer
string is separated from the
+translator id (or translator class name) by a comma, ex: <code>int,min=0</code>.
Initializer
+strings are <i>generally</i> in the format of
+<code><i>key</i>=<i>value</i>[,<i>key</i>=<i>value</i>]*</code> ... but each
Translator
+is free to interpret the initializer string its own way.
+</p>
+
+<subsection name="boolean">
+
+<p>
+The boolean translator converts an input string into a boolean value. "true" is
translated to true, and "false" to false.
+</p>
+
+<p>
+A default value is used when the input is null or invalid. Normally, this default
is false, but the "default" key in the initializer
+can override this (i.e., <code>boolean,default=true</code>).
+ </p>
+
+</subsection>
+
+<subsection name="class">
+
+<p>
+ The class translator converts a fully qualified class name into an object
instance. The class must implement
+a public no-arguments constructor.
+</p>
+
+</subsection>
+
+<subsection name="int">
+
+<p>
+The int translator converts the input into an integer value. It recognizes three
initializer values:
+<ul>
+<li>default: the default value (normally 0) to use when the input is null or
invavlid</li>
+<li>min: a minimum acceptible value</li>
+<li>max: a maximum acceptible value</li>
+</ul>
+</p>
+
+<p>
+If the value is outside of the range defined by the min and max initializer keys,
it is constrained into the range.
+</p>
+
+</subsection>
+
+<subsection name="service">
+
+<p>
+The service translator is used to lookup a service in the registry. The input
value is either a local service id
+from the contributing module, or a fully qualified service id.
+</p>
+
+</subsection>
+
+
</section>
+
</body>
</document>
1.1
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/rules/TestConvertInitializer.java
Index: TestConvertInitializer.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package hivemind.test.rules;
import hivemind.test.HiveMindTestCase;
import java.util.Map;
import org.apache.commons.hivemind.schema.rules.RuleUtils;
import org.apache.tapestry.ApplicationRuntimeException;
/**
* Tests for [EMAIL PROTECTED]
org.apache.commons.hivemind.HiveMind#convertTranslatorInitializer(String)}.
*
* @author Howard Lewis Ship
* @version $Id: TestConvertInitializer.java,v 1.1 2003/08/04 14:21:56 hlship Exp $
*/
public class TestConvertInitializer extends HiveMindTestCase
{
public TestConvertInitializer(String name)
{
super(name);
}
public void testEmpty()
{
Map m = RuleUtils.convertInitializer(null);
assertEquals(true, m.isEmpty());
m = RuleUtils.convertInitializer("");
assertEquals(true, m.isEmpty());
}
public void testSimple()
{
Map m = RuleUtils.convertInitializer("alpha=bravo");
assertEquals(1, m.size());
assertEquals("bravo", m.get("alpha"));
}
public void testComplex()
{
Map m =
RuleUtils.convertInitializer("alpha=bravo,fred=barney,gromit=greyhound");
assertEquals(3, m.size());
assertEquals("bravo", m.get("alpha"));
assertEquals("barney", m.get("fred"));
assertEquals("greyhound", m.get("gromit"));
}
public void testFailure()
{
try
{
RuleUtils.convertInitializer("bad");
unreachable();
}
catch (ApplicationRuntimeException ex)
{
checkException(
ex,
"Initializer string ('bad') is not in proper format
(key=value[,key=value]*).");
}
}
}
1.1
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/config/impl/IntHolder.java
Index: IntHolder.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package hivemind.test.config.impl;
/**
* Used for testing [EMAIL PROTECTED]
org.apache.commons.hivemind.schema.rules.IntTranslator}.
*
* @author Howard Lewis Ship
* @version $Id: IntHolder.java,v 1.1 2003/08/04 14:21:56 hlship Exp $
*/
public class IntHolder
{
private int _value;
public int getValue()
{
return _value;
}
public void setValue(int i)
{
_value = i;
}
}
1.17 +4 -4
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java
Index: RegistryBuilder.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- RegistryBuilder.java 1 Aug 2003 14:21:38 -0000 1.16
+++ RegistryBuilder.java 4 Aug 2003 14:21:56 -0000 1.17
@@ -100,8 +100,8 @@
* here and in many of the related classes is divided into construction-time logic
* and runtime logic. Runtime logic is synchronized and threadsafe.
Construction-time logic
* is not threadsafe. Methods such as [EMAIL PROTECTED]
org.apache.commons.hivemind.impl.RegistryImpl#addModule(Module)},
- * [EMAIL PROTECTED]
org.apache.commons.hivemind.impl.ModuleImpl#addConfigurationExtensionPoint(ConfigurationExtensionPoint)},
- * [EMAIL PROTECTED]
org.apache.commons.hivemind.impl.ConfigurationExtensionPointImpl#addConfigurationContribution(ConfigurationContribution)}
+ * [EMAIL PROTECTED]
org.apache.commons.hivemind.impl.ModuleImpl#addExtensionPoint(ExtensionPoint))},
+ * [EMAIL PROTECTED]
org.apache.commons.hivemind.impl.ExtensionPointImpl#addExtension(Extension)}
* and the like are construction-time. Once the registry is fully constructed, it
is not
* allowed to invoke those methods (though, at this time, no checks occur).
*
@@ -494,7 +494,7 @@
}
/**
- * Adds an [EMAIL PROTECTED]
org.apache.commons.hivemind.parse.AbstractInstanceBuilderDescriptor}
+ * Adds an [EMAIL PROTECTED] InstanceBuilder}
* to a service extension point.
*
*
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]