tomdz 2005/09/05 14:35:22
Modified: src/java/org/apache/ojb/broker/metadata
RepositoryXmlHandler.java CreationDescriptor.java
CreationParameter.java
src/test/org/apache/ojb/broker FactoryCreatedObject.java
CreationTest.java FactoryCreatedObjectImpl.java
ObjectTestFactory.java
src/test/org/apache/ojb repository_junit.xml repository.dtd
Added: src/java/org/apache/ojb/broker/metadata ClassForName.java
Log:
Added type parameter to the creation-descriptor parameter element that allows
for specifying the exact type of the parameter which helps OJB in determining
the constructor/method to use
Revision Changes Path
1.73 +3 -1
db-ojb/src/java/org/apache/ojb/broker/metadata/RepositoryXmlHandler.java
Index: RepositoryXmlHandler.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/RepositoryXmlHandler.java,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- RepositoryXmlHandler.java 3 Sep 2005 15:28:14 -0000 1.72
+++ RepositoryXmlHandler.java 5 Sep 2005 21:35:22 -0000 1.73
@@ -408,7 +408,9 @@
CreationParameter param = new CreationParameter();
String fieldRef = atts.getValue("field-ref");
String constExpr = atts.getValue("value");
+ String type = atts.getValue("type");
+ param.setTypeName(type);
if ((fieldRef == null) || (fieldRef.length() == 0))
{
param.setValue(constExpr);
1.2 +35 -2
db-ojb/src/java/org/apache/ojb/broker/metadata/CreationDescriptor.java
Index: CreationDescriptor.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/CreationDescriptor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- CreationDescriptor.java 3 Sep 2005 15:28:14 -0000 1.1
+++ CreationDescriptor.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -178,7 +178,7 @@
for (int idx = 0; idx < constructors.length; idx++)
{
- if (constructors[idx].getParameterTypes().length ==
parameters.size())
+ if
(fitsCreationParameters(constructors[idx].getParameterTypes()))
{
constructor = constructors[idx];
break;
@@ -276,7 +276,7 @@
for (int idx = 0; idx < methods.length; idx++)
{
if (methods[idx].getName().equals(factoryMethodName) &&
- methods[idx].getParameterTypes().length ==
parameters.size())
+ fitsCreationParameters(methods[idx].getParameterTypes()))
{
factoryMethod = methods[idx];
break;
@@ -291,6 +291,39 @@
}
/**
+ * Determines whether the given method/constructor parameter types fit
the
+ * creation parameters.
+ *
+ * @param paramTypes
+ * @return <code>true</code> if the given param types fit
+ */
+ private boolean fitsCreationParameters(Class[] paramTypes)
+ {
+ if ((paramTypes == null) || (paramTypes.length == 0))
+ {
+ return parameters.isEmpty();
+ }
+ else if (paramTypes.length != parameters.size())
+ {
+ return false;
+ }
+ else
+ {
+ for (int idx = 0; idx < paramTypes.length; idx++)
+ {
+ CreationParameter param =
(CreationParameter)parameters.get(idx);
+
+ if ((param.getType() != null) &&
+ !param.getType().equals(paramTypes[idx]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
* Creates an XML representation of this creation descriptor.
*
* @return The XML representation
1.2 +46 -3
db-ojb/src/java/org/apache/ojb/broker/metadata/CreationParameter.java
Index: CreationParameter.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/CreationParameter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- CreationParameter.java 3 Sep 2005 15:28:14 -0000 1.1
+++ CreationParameter.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -8,9 +8,6 @@
* Describes a parameter to the constructor/method used for constructing
objects.
* Such a parameter either refers to a field or a constant expression that
can be converted
* to the correponding parameter type of the constructor/method.
- *
- * TODO: It might be useful to allow for the specification of the parameter
types
- * which then can be used to determine the target constructor/method
*/
public class CreationParameter implements Serializable
{
@@ -21,6 +18,8 @@
private String fieldName;
/** The constant value */
private String value;
+ /** The parameter type (optional) */
+ private Class type;
/**
* Determines whether this parameter is defined by a constant value.
@@ -73,6 +72,50 @@
}
/**
+ * Returns the parameter type.
+ *
+ * @return The type
+ */
+ public Class getType()
+ {
+ return type;
+ }
+
+ /**
+ * Sets the parameter type.
+ *
+ * @param type The type
+ */
+ public void setType(Class type)
+ {
+ this.type = type;
+ }
+
+ /**
+ * Sets the parameter type.
+ *
+ * @param typeName The qualified type name
+ */
+ public void setTypeName(String typeName)
+ {
+ if ((typeName == null) || (typeName.length() == 0))
+ {
+ type = null;
+ }
+ else
+ {
+ try
+ {
+ type = new ClassForName().forName(typeName);
+ }
+ catch (Exception ex)
+ {
+ throw new MetadataException("Undefined parameter type
"+typeName, ex);
+ }
+ }
+ }
+
+ /**
* Creates an XML representation of this creation parameter.
*
* @return The XML representation
1.1
db-ojb/src/java/org/apache/ojb/broker/metadata/ClassForName.java
Index: ClassForName.java
===================================================================
package org.apache.ojb.broker.metadata;
/* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.HashMap;
import java.util.StringTokenizer;
/**
* Enhanced form of Class.forName that instead of requiring bytecode
specification
* (eg. "[Ljava.lang.Object;" for an Object[]) uses normal type and array
specifications.
*
* Note: This class might be included into commons-lang. Until then it
remains here.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Thomas Dudziak</a>
*/
public class ClassForName
{
/** Maps primitive type name to class loader identifiers (for
Class.forName) */
private HashMap primitiveNameToClassloaderName = new HashMap();
/**
* Creates a new instance.
*/
public ClassForName()
{
primitiveNameToClassloaderName.put("boolean", "Z");
primitiveNameToClassloaderName.put("byte", "B");
primitiveNameToClassloaderName.put("char", "C");
primitiveNameToClassloaderName.put("short", "S");
primitiveNameToClassloaderName.put("int", "I");
primitiveNameToClassloaderName.put("long", "J");
primitiveNameToClassloaderName.put("float", "F");
primitiveNameToClassloaderName.put("double", "D");
}
/**
* Returns the class object for the given type specifications. These
might specify<br/>
* <ul>
* <li>primitive types such as <code>int, byte, boolean</code></li>
* <li>arrays of primitive types, eg. <code>double[]</code> or
<code>char[][][]</code></li>
* <li>reference types (qualified names) such as <code>java.lang.String,
java.io.Serializable</code></li>
* <li>arrays of reference types such as
<code>java.lang.Object[][]</code></li>
* </ul><br/>
* The method ignores dimension specifications, eg. a
<code>double[5]</code> will work the same way
* that <code>double[]</code> would.
*
* @param typeSpec The type specification
* @return The class object
* @throws ClassNotFoundException If the type could not be found
* @throws IllegalArgumentException If the type specification is invalid
* @see java.lang.Class#forName(java.lang.String)
*/
public Class forName(String typeSpec) throws ClassNotFoundException,
IllegalArgumentException
{
return forName(typeSpec, true, null);
}
/**
* Returns the class object for the given type specifications. These
might specify<br/>
* <ul>
* <li>primitive types such as <code>int, byte, boolean</code></li>
* <li>arrays of primitive types, eg. <code>double[]</code> or
<code>char[][][]</code></li>
* <li>reference types (qualified names) such as <code>java.lang.String,
java.io.Serializable</code></li>
* <li>arrays of reference types such as
<code>java.lang.Object[][]</code></li>
* </ul><br/>
* The method ignores dimension specifications, eg. a
<code>double[5]</code> will work the same way
* that <code>double[]</code> would.
*
* @param typeSpec The type specification
* @param initialize Whether the class must be initialized
* @param loader Class loader from which the class must be loaded
* @return The class object
* @throws ClassNotFoundException If the type could not be found
* @throws IllegalArgumentException If the type specification is invalid
* @see java.lang.Class#forName(java.lang.String, boolean,
java.lang.ClassLoader)
*/
public Class forName(String typeSpec, boolean initialize, ClassLoader
classLoader) throws ClassNotFoundException, IllegalArgumentException
{
StringTokenizer tokenizer = new StringTokenizer(typeSpec,
"[]", true);
String className = null;
int numOpeningBrackets = 0;
int numClosingBrackets = 0;
while (tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken().trim();
if ("[".equals(token))
{
if (numOpeningBrackets != numClosingBrackets)
{
throw new IllegalArgumentException("Unbalanced array
brackets in type specification "+typeSpec);
}
numOpeningBrackets++;
}
else if ("]".equals(token))
{
numClosingBrackets++;
if (numOpeningBrackets != numClosingBrackets)
{
throw new IllegalArgumentException("Unbalanced array
brackets in type specification "+typeSpec);
}
}
else if (token.length() > 0)
{
// we ignore text once the first bracket has been parsed
if (numOpeningBrackets == 0)
{
className = token;
}
}
}
if (className == null)
{
throw new IllegalArgumentException("Illegal type specification in
type specification "+typeSpec);
}
StringBuffer classNameForClassLoader = new StringBuffer();
boolean isPrimitive =
primitiveNameToClassloaderName.containsKey(className);
for (int idx = 0; idx < numOpeningBrackets; idx++)
{
classNameForClassLoader.append("[");
}
if (isPrimitive)
{
// for arrays we need to use the bytecode identifier
// for non-array primitive types, we use a normal array of that
type and retrieve the component type
// this is because int.class is not guaranteed to be equal to
Integer.class etc.
if (numOpeningBrackets == 0)
{
classNameForClassLoader.append("[");
}
classNameForClassLoader.append((String)primitiveNameToClassloaderName.get(className));
}
else
{
if (numOpeningBrackets > 0)
{
// for arrays we also need to add a L before and a semicolon
after
classNameForClassLoader.append("L");
classNameForClassLoader.append(className);
classNameForClassLoader.append(";");
}
else
{
classNameForClassLoader.append(className);
}
}
className = classNameForClassLoader.toString();
Class clazz = (classLoader == null ? Class.forName(className) :
Class.forName(className, initialize, classLoader));
return (isPrimitive && (numOpeningBrackets == 0) ?
clazz.getComponentType() : clazz);
}
}
1.2 +3 -3
db-ojb/src/test/org/apache/ojb/broker/FactoryCreatedObject.java
Index: FactoryCreatedObject.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/test/org/apache/ojb/broker/FactoryCreatedObject.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FactoryCreatedObject.java 3 Sep 2005 15:28:13 -0000 1.1
+++ FactoryCreatedObject.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -4,9 +4,9 @@
{
private Integer id;
private String name;
- private Integer value;
+ private int value;
- FactoryCreatedObject(String name, Integer value)
+ FactoryCreatedObject(String name, int value)
{
this.name = name;
this.value = value;
@@ -17,7 +17,7 @@
return name;
}
- public Integer getValue()
+ public int getValue()
{
return value;
}
1.2 +2 -2 db-ojb/src/test/org/apache/ojb/broker/CreationTest.java
Index: CreationTest.java
===================================================================
RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/CreationTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- CreationTest.java 3 Sep 2005 15:28:13 -0000 1.1
+++ CreationTest.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -104,7 +104,7 @@
*/
public void testSimpleFactoryCreation() throws Exception
{
- FactoryCreatedObject obj = new
ObjectTestFactory().createInstance("test", new Integer(2));
+ FactoryCreatedObject obj = new
ObjectTestFactory().createInstance("test", 2);
broker.beginTransaction();
broker.store(obj);
@@ -118,7 +118,7 @@
assertEquals("test",
obj.getName());
- assertEquals(new Integer(2),
+ assertEquals(2,
obj.getValue());
}
1.2 +1 -1
db-ojb/src/test/org/apache/ojb/broker/FactoryCreatedObjectImpl.java
Index: FactoryCreatedObjectImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/test/org/apache/ojb/broker/FactoryCreatedObjectImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FactoryCreatedObjectImpl.java 3 Sep 2005 15:28:13 -0000 1.1
+++ FactoryCreatedObjectImpl.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -21,7 +21,7 @@
{
private static final long serialVersionUID = -3040240766695562349L;
- FactoryCreatedObjectImpl(String name, Integer value)
+ FactoryCreatedObjectImpl(String name, int value)
{
super(name, value);
}
1.2 +6 -1
db-ojb/src/test/org/apache/ojb/broker/ObjectTestFactory.java
Index: ObjectTestFactory.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/test/org/apache/ojb/broker/ObjectTestFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ObjectTestFactory.java 3 Sep 2005 15:28:13 -0000 1.1
+++ ObjectTestFactory.java 5 Sep 2005 21:35:22 -0000 1.2
@@ -5,8 +5,13 @@
*/
public class ObjectTestFactory
{
- public FactoryCreatedObject createInstance(String name, Integer value)
+ public FactoryCreatedObject createInstance(String name, int value)
{
return new FactoryCreatedObjectImpl(name, value);
}
+
+ public FactoryCreatedObject createInstance(String name, Integer value)
+ {
+ return new FactoryCreatedObjectImpl(name, value.intValue());
+ }
}
1.136 +3 -3 db-ojb/src/test/org/apache/ojb/repository_junit.xml
Index: repository_junit.xml
===================================================================
RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/repository_junit.xml,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -r1.135 -r1.136
--- repository_junit.xml 3 Sep 2005 15:28:14 -0000 1.135
+++ repository_junit.xml 5 Sep 2005 21:35:22 -0000 1.136
@@ -508,7 +508,7 @@
table="Container"
>
<creation-descriptor type="constructor">
- <parameter field-ref="name"/>
+ <parameter field-ref="name" type="java.lang.String"/>
</creation-descriptor>
<field-descriptor
name="id"
@@ -556,7 +556,7 @@
factory-method="createInstance"
>
<parameter field-ref="name"/>
- <parameter field-ref="value"/>
+ <parameter field-ref="value" type="int"/>
</creation-descriptor>
<field-descriptor
name="id"
1.65 +8 -1 db-ojb/src/test/org/apache/ojb/repository.dtd
Index: repository.dtd
===================================================================
RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/repository.dtd,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- repository.dtd 3 Sep 2005 15:28:14 -0000 1.64
+++ repository.dtd 5 Sep 2005 21:35:22 -0000 1.65
@@ -419,11 +419,18 @@
<!ELEMENT parameter EMPTY>
<!--
field-ref specifies the field in the owning class descriptor that gives
the value.
- valu specifies the constant value to be used as the argument.
+
+ value specifies the constant value to be used as the argument.
+
+ type allows to specify the parameter type which helps OJB in
determining the
+ constructor/method. For primitive types, simply state the type, eg. int
or char[].
+ For reference type, specify the fully qualified type name, for instance
+ java.lang.Object or java.lang.String[][].
-->
<!ATTLIST parameter
field-ref CDATA #IMPLIED
value CDATA #IMPLIED
+ type CDATA #IMPLIED
>
<!--
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]