dmitri 2003/03/24 18:41:35
Modified: jxpath project.xml
jxpath/src/java/org/apache/commons/jxpath/ri
EvalContext.java JXPathContextReferenceImpl.java
jxpath/src/java/org/apache/commons/jxpath/ri/axes
InitialContext.java PredicateContext.java
RootContext.java SimplePathInterpreter.java
UnionContext.java
jxpath/src/java/org/apache/commons/jxpath/ri/compiler
ExpressionPath.java
jxpath/src/java/org/apache/commons/jxpath/ri/model
NodePointer.java VariablePointer.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/beans
CollectionPointer.java PropertyIterator.java
jxpath/src/java/org/apache/commons/jxpath/util
BasicTypeConverter.java
jxpath/src/test/org/apache/commons/jxpath/ri/compiler
ExtensionFunctionTest.java TestFunctions.java
jxpath/src/test/org/apache/commons/jxpath/ri/model
BeanModelTestCase.java
jxpath/src/test/org/apache/commons/jxpath/util
BasicTypeConverterTest.java
jxpath/xdocs users-guide.xml
Added: jxpath/src/java/org/apache/commons/jxpath BasicNodeSet.java
jxpath/src/java/org/apache/commons/jxpath/ri/axes
NodeSetContext.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/beans
CollectionAttributeNodeIterator.java
CollectionChildNodeIterator.java
CollectionNodeIterator.java
jxpath/src/test/org/apache/commons/jxpath/ri StressTest.java
Log:
Fixed collection as return value of extension function
Reduced the amount of cloning
Revision Changes Path
1.13 +10 -10 jakarta-commons/jxpath/project.xml
Index: project.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/project.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- project.xml 11 Mar 2003 00:59:10 -0000 1.12
+++ project.xml 25 Mar 2003 02:41:33 -0000 1.13
@@ -93,18 +93,18 @@
<reports>
<report>maven-junit-report-plugin</report>
- <!--
+
<report>maven-jdepend-plugin</report>
<report>maven-checkstyle-plugin</report>
- <report>maven-changelog-plugin</report>
- <report>maven-developer-activity-plugin</report>
- <report>maven-file-activity-plugin</report>
- <report>maven-javadoc-plugin</report>
+ <!--report>maven-changelog-plugin</report-->
+ <!--report>maven-developer-activity-plugin</report-->
+ <!--report>maven-file-activity-plugin</report-->
+ <!--report>maven-javadoc-plugin</report-->
<report>maven-jxr-plugin</report>
- <report>maven-license-plugin</report>
- <report>maven-linkcheck-plugin</report>
- <report>maven-tasklist-plugin</report>
- <report>maven-clover-plugin</report>
- -->
+ <!--report>maven-license-plugin</report-->
+ <!--report>maven-linkcheck-plugin</report-->
+ <!--report>maven-tasklist-plugin</report-->
+ <!--report>maven-clover-plugin</report-->
+
</reports>
</project>
1.1
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/BasicNodeSet.java
Index: BasicNodeSet.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/BasicNodeSet.java,v
1.1 2003/03/25 02:41:33 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:33 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.jxpath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A simple implementation of NodeSet that behaves as a collection of pointers.
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:33 $
*/
public class BasicNodeSet implements NodeSet {
private List pointers = new ArrayList();
private List readOnlyPointers;
private List nodes;
private List values;
public void add(Pointer pointer) {
pointers.add(pointer);
readOnlyPointers = null;
}
public void remove(Pointer pointer) {
pointers.remove(pointer);
readOnlyPointers = null;
}
public List getPointers() {
if (readOnlyPointers == null) {
readOnlyPointers = Collections.unmodifiableList(pointers);
}
return readOnlyPointers;
}
public List getNodes() {
if (nodes == null) {
nodes = new ArrayList();
for (int i = 0; i < pointers.size(); i++) {
Pointer pointer = (Pointer) pointers.get(i);
nodes.add(pointer.getValue());
}
nodes = Collections.unmodifiableList(nodes);
}
return nodes;
}
public List getValues() {
if (values == null) {
values = new ArrayList();
for (int i = 0; i < pointers.size(); i++) {
Pointer pointer = (Pointer) pointers.get(i);
values.add(pointer.getValue());
}
values = Collections.unmodifiableList(values);
}
return values;
}
public String toString() {
return pointers.toString();
}
}
1.24 +17 -56
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/EvalContext.java
Index: EvalContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/EvalContext.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- EvalContext.java 11 Mar 2003 00:59:18 -0000 1.23
+++ EvalContext.java 25 Mar 2003 02:41:33 -0000 1.24
@@ -69,6 +69,7 @@
import java.util.List;
import java.util.NoSuchElementException;
+import org.apache.commons.jxpath.BasicNodeSet;
import org.apache.commons.jxpath.ExpressionContext;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
@@ -176,7 +177,7 @@
throw new NoSuchElementException();
}
hasPerformedIteratorStep = false;
- return (NodePointer) getCurrentNodePointer().clone();
+ return getCurrentNodePointer();
}
}
@@ -214,9 +215,9 @@
while (nextNode()) {
NodePointer pointer = getCurrentNodePointer();
if (!set.contains(pointer)) {
- Pointer cln = (Pointer) pointer.clone();
- set.add(cln);
- list.add(cln);
+// Pointer cln = (Pointer) pointer.clone();
+ set.add(pointer);
+ list.add(pointer);
}
}
}
@@ -268,8 +269,14 @@
+ "should not request pointer list while "
+ "iterating over an EvalContext");
}
-
- return new SimpleNodeSet();
+ BasicNodeSet set = new BasicNodeSet();
+ while (nextSet()) {
+ while (nextNode()) {
+ set.add(getCurrentNodePointer());
+ }
+ }
+
+ return set;
}
public String toString() {
@@ -376,50 +383,4 @@
this.position = position;
return true;
}
-
- class SimpleNodeSet implements NodeSet {
- private List pointers;
- private List nodes;
- private List values;
-
- public SimpleNodeSet() {
- pointers = new ArrayList();
- while (nextSet()) {
- while (nextNode()) {
- pointers.add(getCurrentNodePointer());
- }
- }
- }
-
- public List getPointers() {
- return Collections.unmodifiableList(pointers);
- }
-
- public List getNodes() {
- if (nodes == null) {
- List pointers = getPointers();
- nodes = new ArrayList();
- for (int i = 0; i < pointers.size(); i++) {
- Pointer pointer = (Pointer) pointers.get(i);
- nodes.add(pointer.getValue());
- }
- nodes = Collections.unmodifiableList(nodes);
- }
- return nodes;
- }
-
- public List getValues() {
- if (values == null) {
- List pointers = getPointers();
- values = new ArrayList();
- for (int i = 0; i < pointers.size(); i++) {
- Pointer pointer = (Pointer) pointers.get(i);
- values.add(pointer.getValue());
- }
- values = Collections.unmodifiableList(values);
- }
- return values;
- }
- }
-
}
1.31 +21 -17
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/JXPathContextReferenceImpl.java
Index: JXPathContextReferenceImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/JXPathContextReferenceImpl.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- JXPathContextReferenceImpl.java 11 Mar 2003 00:59:18 -0000 1.30
+++ JXPathContextReferenceImpl.java 25 Mar 2003 02:41:33 -0000 1.31
@@ -103,7 +103,8 @@
public class JXPathContextReferenceImpl extends JXPathContext {
/**
- * Change this to <code>false</code> to disable soft caching of
CompiledExpressions.
+ * Change this to <code>false</code> to disable soft caching of
+ * CompiledExpressions.
*/
public static final boolean USE_SOFT_CACHE = true;
@@ -227,9 +228,8 @@
*
* Override this to return an aternate compiler.
*/
- protected Compiler getCompiler(){
+ protected Compiler getCompiler() {
return COMPILER;
-
}
protected CompiledExpression compilePath(String xpath) {
@@ -247,7 +247,9 @@
if (expr == null) {
expr =
(Expression) Parser.parseExpression(xpath, getCompiler());
- compiled.put(xpath, new SoftReference(expr));
+ synchronized (compiled) {
+ compiled.put(xpath, new SoftReference(expr));
+ }
if (cleanupCount++ >= CLEANUP_THRESHOLD) {
cleanupCache();
}
@@ -265,14 +267,16 @@
}
private static void cleanupCache() {
- Iterator it = compiled.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry me = (Map.Entry) it.next();
- if (((SoftReference) me.getValue()).get() == null) {
- it.remove();
+ synchronized (compiled) {
+ Iterator it = compiled.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry me = (Map.Entry) it.next();
+ if (((SoftReference) me.getValue()).get() == null) {
+ it.remove();
+ }
}
+ cleanupCount = 0;
}
- cleanupCount = 0;
}
/**
@@ -539,7 +543,7 @@
}
}
- public JXPathContext getRelativeContext(Pointer pointer){
+ public JXPathContext getRelativeContext(Pointer pointer) {
Object contextBean = pointer.getNode();
if (contextBean == null) {
throw new JXPathException(
@@ -550,11 +554,11 @@
}
public synchronized Pointer getContextPointer() {
- return (Pointer) contextPointer.clone();
+ return contextPointer;
}
private synchronized NodePointer getAbsoluteRootPointer() {
- return (NodePointer) rootPointer.clone();
+ return (NodePointer) rootPointer;
}
private EvalContext getEvalContext() {
1.11 +6 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/InitialContext.java
Index: InitialContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/InitialContext.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- InitialContext.java 11 Mar 2003 00:59:20 -0000 1.10
+++ InitialContext.java 25 Mar 2003 02:41:34 -0000 1.11
@@ -81,7 +81,8 @@
public InitialContext(EvalContext parentContext) {
super(parentContext);
- nodePointer = parentContext.getCurrentNodePointer();
+ nodePointer =
+ (NodePointer) parentContext.getCurrentNodePointer().clone();
if (nodePointer != null) {
collection =
(nodePointer.getIndex() == NodePointer.WHOLE_COLLECTION);
1.19 +7 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/PredicateContext.java
Index: PredicateContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/PredicateContext.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- PredicateContext.java 11 Mar 2003 00:59:20 -0000 1.18
+++ PredicateContext.java 25 Mar 2003 02:41:34 -0000 1.19
@@ -154,7 +154,9 @@
return false;
}
dynamicPropertyPointer =
- ((PropertyOwnerPointer) parent).getPropertyPointer();
+ (PropertyPointer) ((PropertyOwnerPointer) parent)
+ .getPropertyPointer()
+ .clone();
return true;
}
1.12 +11 -4
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/RootContext.java
Index: RootContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/RootContext.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- RootContext.java 11 Mar 2003 00:59:20 -0000 1.11
+++ RootContext.java 25 Mar 2003 02:41:34 -0000 1.12
@@ -63,6 +63,7 @@
import org.apache.commons.jxpath.Function;
import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.NodeSet;
import org.apache.commons.jxpath.ri.EvalContext;
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
import org.apache.commons.jxpath.ri.QName;
@@ -124,6 +125,12 @@
}
public EvalContext getConstantContext(Object constant) {
+ if (constant instanceof NodeSet) {
+ return new NodeSetContext(
+ new RootContext(jxpathContext, null),
+ (NodeSet) constant);
+ }
+
NodePointer pointer;
if (constant instanceof NodePointer) {
pointer = (NodePointer) constant;
1.11 +3 -3
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java
Index: SimplePathInterpreter.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- SimplePathInterpreter.java 11 Mar 2003 00:59:20 -0000 1.10
+++ SimplePathInterpreter.java 25 Mar 2003 02:41:34 -0000 1.11
@@ -250,6 +250,7 @@
// execute remaining steps for each node,
// looking for the best quality match
int bestQuality = 0;
+ childPointer = (NodePointer) childPointer.clone();
NodePointer bestMatch = null;
int count = childPointer.getLength();
for (int i = 0; i < count; i++) {
@@ -525,13 +526,11 @@
// if so - proceed to the next predicate
NodePointer bestMatch = null;
int bestQuality = 0;
+ child = (NodePointer) child.clone();
int count = child.getLength();
for (int i = 0; i < count; i++) {
child.setIndex(i);
NodePointer valuePointer = valuePointer(child);
- if (valuePointer == child) {
- valuePointer = (NodePointer) child.clone();
- }
NodePointer pointer;
if ((valuePointer instanceof PropertyOwnerPointer)
|| valuePointer.isCollection()) {
@@ -672,6 +671,7 @@
int index = indexFromPredicate(context, predicate);
NodePointer pointer = parent;
if (isCollectionElement(pointer, index)) {
+ pointer = (NodePointer) pointer.clone();
pointer.setIndex(index);
return doPredicate(
context,
1.10 +22 -49
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/UnionContext.java
Index: UnionContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/UnionContext.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- UnionContext.java 11 Mar 2003 00:59:20 -0000 1.9
+++ UnionContext.java 25 Mar 2003 02:41:34 -0000 1.10
@@ -61,10 +61,9 @@
*/
package org.apache.commons.jxpath.ri.axes;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
+import org.apache.commons.jxpath.BasicNodeSet;
import org.apache.commons.jxpath.ri.EvalContext;
import org.apache.commons.jxpath.ri.model.NodePointer;
@@ -75,13 +74,13 @@
* @author Dmitri Plotnikov
* @version $Revision$ $Date$
*/
-public class UnionContext extends EvalContext {
+public class UnionContext extends NodeSetContext {
private boolean startedSet = false;
private EvalContext contexts[];
- private List list;
+ private boolean prepared = false;
public UnionContext(EvalContext parentContext, EvalContext contexts[]) {
- super(parentContext);
+ super(parentContext, new BasicNodeSet());
this.contexts = contexts;
}
@@ -92,50 +91,24 @@
return super.getDocumentOrder();
}
- public NodePointer getCurrentNodePointer() {
- if (position == 0) {
- if (!setPosition(1)) {
- return null;
- }
- }
- return (NodePointer) list.get(position - 1);
- }
-
public boolean setPosition(int position) {
- super.setPosition(position);
- if (list == null) {
- prepareList();
- }
- return position >= 1 && position <= list.size();
- }
-
- public boolean nextSet() {
- if (startedSet) {
- return false;
- }
- startedSet = true;
- return true;
- }
-
- public boolean nextNode() {
- return setPosition(position + 1);
- }
-
- private void prepareList() {
- list = new ArrayList();
- HashSet set = new HashSet();
- for (int i = 0; i < contexts.length; i++) {
- EvalContext ctx = (EvalContext) contexts[i];
- while (ctx.nextSet()) {
- while (ctx.nextNode()) {
- NodePointer ptr = ctx.getCurrentNodePointer();
- if (!set.contains(ptr)) {
- ptr = (NodePointer) ptr.clone();
- list.add(ptr);
- set.add(ptr);
+ if (!prepared) {
+ prepared = true;
+ BasicNodeSet nodeSet = (BasicNodeSet) getNodeSet();
+ HashSet set = new HashSet();
+ for (int i = 0; i < contexts.length; i++) {
+ EvalContext ctx = (EvalContext) contexts[i];
+ while (ctx.nextSet()) {
+ while (ctx.nextNode()) {
+ NodePointer ptr = ctx.getCurrentNodePointer();
+ if (!set.contains(ptr)) {
+ nodeSet.add(ptr);
+ set.add(ptr);
+ }
}
}
}
}
+ return super.setPosition(position);
}
}
1.1
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/NodeSetContext.java
Index: NodeSetContext.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/NodeSetContext.java,v
1.1 2003/03/25 02:41:34 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:34 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.jxpath.ri.axes;
import org.apache.commons.jxpath.NodeSet;
import org.apache.commons.jxpath.ri.EvalContext;
import org.apache.commons.jxpath.ri.model.NodePointer;
/**
* A simple context that is based on a NodeSet.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:34 $
*/
public class NodeSetContext extends EvalContext {
private boolean startedSet = false;
private NodeSet nodeSet;
public NodeSetContext(EvalContext parentContext, NodeSet nodeSet) {
super(parentContext);
this.nodeSet = nodeSet;
}
public NodeSet getNodeSet() {
return nodeSet;
}
public NodePointer getCurrentNodePointer() {
if (position == 0) {
if (!setPosition(1)) {
return null;
}
}
return (NodePointer) nodeSet.getPointers().get(position - 1);
}
public boolean setPosition(int position) {
super.setPosition(position);
return position >= 1 && position <= nodeSet.getPointers().size();
}
public boolean nextSet() {
if (startedSet) {
return false;
}
startedSet = true;
return true;
}
public boolean nextNode() {
return setPosition(position + 1);
}
}
1.9 +6 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/ExpressionPath.java
Index: ExpressionPath.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/ExpressionPath.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ExpressionPath.java 11 Mar 2003 00:59:22 -0000 1.8
+++ ExpressionPath.java 25 Mar 2003 02:41:34 -0000 1.9
@@ -63,6 +63,7 @@
import org.apache.commons.jxpath.ri.EvalContext;
import org.apache.commons.jxpath.ri.axes.InitialContext;
+import org.apache.commons.jxpath.ri.axes.NodeSetContext;
import org.apache.commons.jxpath.ri.axes.PredicateContext;
import org.apache.commons.jxpath.ri.axes.SimplePathInterpreter;
import org.apache.commons.jxpath.ri.axes.UnionContext;
@@ -202,7 +203,7 @@
if (firstMatch
&& isSimpleExpressionPath()
- && !(context instanceof UnionContext)) {
+ && !(context instanceof NodeSetContext)) {
EvalContext ctx = context;
NodePointer ptr = (NodePointer) ctx.getSingleNodePointer();
if (ptr != null
1.18 +10 -6
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java
Index: NodePointer.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- NodePointer.java 11 Mar 2003 00:59:23 -0000 1.17
+++ NodePointer.java 25 Mar 2003 02:41:34 -0000 1.18
@@ -325,9 +325,9 @@
return getValuePointer().getImmediateNode();
}
- public Object getRootNode(){
+ public Object getRootNode() {
if (rootNode == null) {
- if (parent != null){
+ if (parent != null) {
rootNode = parent.getRootNode();
}
else {
@@ -369,6 +369,10 @@
}
QName testName = ((NodeNameTest) test).getNodeName();
QName nodeName = getName();
+ if (nodeName == null) {
+ return false;
+ }
+
String testPrefix = testName.getPrefix();
String nodePrefix = nodeName.getPrefix();
if (!equalStrings(testPrefix, nodePrefix)) {
1.15 +7 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/VariablePointer.java
Index: VariablePointer.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/VariablePointer.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- VariablePointer.java 11 Mar 2003 00:59:23 -0000 1.14
+++ VariablePointer.java 25 Mar 2003 02:41:34 -0000 1.15
@@ -229,7 +229,9 @@
throw new JXPathException(
"Factory could not create object path: " + asPath());
}
- setIndex(index);
+ NodePointer cln = (NodePointer) clone();
+ cln.setIndex(index);
+ return cln;
}
return this;
}
1.15 +13 -7
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionPointer.java
Index: CollectionPointer.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionPointer.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- CollectionPointer.java 11 Mar 2003 00:59:25 -0000 1.14
+++ CollectionPointer.java 25 Mar 2003 02:41:34 -0000 1.15
@@ -208,14 +208,20 @@
boolean reverse, NodePointer startWith)
{
if (index == WHOLE_COLLECTION) {
- return null;
+ return new CollectionChildNodeIterator(
+ this,
+ test,
+ reverse,
+ startWith);
+ }
+ else {
+ return getValuePointer().childIterator(test, reverse, startWith);
}
- return getValuePointer().childIterator(test, reverse, startWith);
}
public NodeIterator attributeIterator(QName name) {
if (index == WHOLE_COLLECTION) {
- return null;
+ return new CollectionAttributeNodeIterator(this, name);
}
return getValuePointer().attributeIterator(name);
}
1.10 +7 -7
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/PropertyIterator.java
Index: PropertyIterator.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/PropertyIterator.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- PropertyIterator.java 11 Mar 2003 00:59:25 -0000 1.9
+++ PropertyIterator.java 25 Mar 2003 02:41:34 -0000 1.10
@@ -91,7 +91,8 @@
boolean reverse,
NodePointer startWith)
{
- propertyNodePointer = pointer.getPropertyPointer();
+ propertyNodePointer =
+ (PropertyPointer) pointer.getPropertyPointer().clone();
this.name = name;
this.reverse = reverse;
this.includeStart = true;
@@ -149,8 +150,7 @@
}
}
try {
- NodePointer clone = (NodePointer) propertyNodePointer.clone();
- return clone.getValuePointer();
+ return propertyNodePointer.getValuePointer();
}
catch (Throwable ex) {
// @todo: should this exception be reported in any way?
1.1
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionAttributeNodeIterator.java
Index: CollectionAttributeNodeIterator.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionAttributeNodeIterator.java,v
1.1 2003/03/25 02:41:34 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:34 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/package org.apache.commons.jxpath.ri.model.beans;
import org.apache.commons.jxpath.ri.QName;
import org.apache.commons.jxpath.ri.model.NodeIterator;
import org.apache.commons.jxpath.ri.model.NodePointer;
/**
* Combines attribute node iterators of all elements of a collection into one
* aggregate attribute node iterator.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:34 $
*/
public class CollectionAttributeNodeIterator extends CollectionNodeIterator {
private QName name;
public CollectionAttributeNodeIterator(
CollectionPointer pointer,
QName name)
{
super(pointer, false, null);
this.name = name;
}
protected NodeIterator getElementNodeIterator(NodePointer elementPointer) {
return elementPointer.attributeIterator(name);
}
}
1.1
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionChildNodeIterator.java
Index: CollectionChildNodeIterator.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionChildNodeIterator.java,v
1.1 2003/03/25 02:41:34 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:34 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/package org.apache.commons.jxpath.ri.model.beans;
import org.apache.commons.jxpath.ri.compiler.NodeTest;
import org.apache.commons.jxpath.ri.model.NodeIterator;
import org.apache.commons.jxpath.ri.model.NodePointer;
/**
* Combines child node iterators of all elements of a collection into one
* aggregate child node iterator.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:34 $
*/
public class CollectionChildNodeIterator extends CollectionNodeIterator {
private NodeTest test;
public CollectionChildNodeIterator(
CollectionPointer pointer,
NodeTest test,
boolean reverse,
NodePointer startWith)
{
super(pointer, reverse, startWith);
this.test = test;
}
protected NodeIterator getElementNodeIterator(NodePointer elementPointer) {
return elementPointer.childIterator(test, false, null);
}
}
1.1
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionNodeIterator.java
Index: CollectionNodeIterator.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/CollectionNodeIterator.java,v
1.1 2003/03/25 02:41:34 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:34 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/package org.apache.commons.jxpath.ri.model.beans;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.jxpath.JXPathException;
import org.apache.commons.jxpath.ri.model.NodeIterator;
import org.apache.commons.jxpath.ri.model.NodePointer;
/**
* Combines node iterators of all elements of a collection into one
* aggregate node iterator.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:34 $
*/
public abstract class CollectionNodeIterator implements NodeIterator {
private CollectionPointer pointer;
private boolean reverse;
private NodePointer startWith;
private int position;
private List collection;
protected CollectionNodeIterator(
CollectionPointer pointer,
boolean reverse,
NodePointer startWith)
{
this.pointer = pointer;
this.reverse = reverse;
this.startWith = startWith;
}
/**
* Implemened by subclasses to produce child/attribute node iterators.
*/
protected abstract NodeIterator
getElementNodeIterator(NodePointer elementPointer);
public int getPosition() {
return position;
}
public boolean setPosition(int position) {
if (collection == null) {
prepare();
}
if (position < 1 || position > collection.size()) {
return false;
}
this.position = position;
return true;
}
public NodePointer getNodePointer() {
if (position == 0) {
return null;
}
return (NodePointer) collection.get(position - 1);
}
private void prepare() {
collection = new ArrayList();
NodePointer ptr = (NodePointer) pointer.clone();
int length = ptr.getLength();
for (int i = 0; i < length; i++) {
ptr.setIndex(i);
NodePointer elementPointer = ptr.getValuePointer();
NodeIterator iter = getElementNodeIterator(elementPointer);
for (int j = 1; iter.setPosition(j); j++) {
NodePointer childPointer = iter.getNodePointer();
if (reverse) {
collection.add(0, childPointer);
}
else {
collection.add(childPointer);
}
}
}
if (startWith != null) {
int index = collection.indexOf(startWith);
if (index == -1) {
throw new JXPathException(
"Invalid starting pointer for iterator: " + startWith);
}
while (collection.size() > index) {
if (!reverse) {
collection.remove(collection.size() - 1);
}
else {
collection.remove(0);
}
}
}
}
}
1.8 +78 -66
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java
Index: BasicTypeConverter.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- BasicTypeConverter.java 11 Mar 2003 00:59:34 -0000 1.7
+++ BasicTypeConverter.java 25 Mar 2003 02:41:34 -0000 1.8
@@ -157,9 +157,14 @@
else if (Collection.class.isAssignableFrom(toType)) {
return canCreateCollection(toType);
}
- else if (Array.getLength(object) == 1) {
- Object value = Array.get(object, 0);
- return canConvert(value, toType);
+ else {
+ if (Array.getLength(object) > 0) {
+ Object value = Array.get(object, 0);
+ return canConvert(value, toType);
+ }
+ else {
+ return canConvert("", toType);
+ }
}
}
else if (object instanceof Collection) {
@@ -178,16 +183,21 @@
else if (Collection.class.isAssignableFrom(toType)) {
return canCreateCollection(toType);
}
- else if (((Collection) object).size() == 1) {
- Object value;
- if (object instanceof List) {
- value = ((List) object).get(0);
+ else {
+ if (((Collection) object).size() > 0) {
+ Object value;
+ if (object instanceof List) {
+ value = ((List) object).get(0);
+ }
+ else {
+ Iterator it = ((Collection) object).iterator();
+ value = it.next();
+ }
+ return canConvert(value, toType);
}
else {
- Iterator it = ((Collection) object).iterator();
- value = it.next();
+ return canConvert("", toType);
}
- return canConvert(value, toType);
}
}
else if (object instanceof NodeSet) {
@@ -198,6 +208,7 @@
}
return false;
}
+
/**
* Converts the supplied object to the specified
* type. Throws a runtime exception if the conversion is
@@ -220,39 +231,7 @@
return object;
}
- if (toType == String.class) {
- return object.toString();
- }
-
- if (object instanceof Boolean) {
- if (toType == boolean.class) {
- return object;
- }
- boolean value = ((Boolean) object).booleanValue();
- return allocateNumber(toType, value ? 1 : 0);
- }
- else if (object instanceof Number) {
- double value = ((Number) object).doubleValue();
- if (toType == boolean.class || toType == Boolean.class) {
- return value == 0.0 ? Boolean.FALSE : Boolean.TRUE;
- }
- if (toType.isPrimitive()
- || Number.class.isAssignableFrom(toType)) {
- return allocateNumber(toType, value);
- }
- }
- else if (object instanceof Character) {
- if (toType == char.class) {
- return object;
- }
- }
- else if (object instanceof String) {
- Object value = convertStringToPrimitive(object, toType);
- if (value != null) {
- return value;
- }
- }
- else if (fromType.isArray()) {
+ if (fromType.isArray()) {
int length = Array.getLength(object);
if (toType.isArray()) {
Class cType = toType.getComponentType();
@@ -271,9 +250,14 @@
}
return unmodifiableCollection(collection);
}
- else if (length == 1) {
- Object value = Array.get(object, 0);
- return convert(value, toType);
+ else {
+ if (length > 0) {
+ Object value = Array.get(object, 0);
+ return convert(value, toType);
+ }
+ else {
+ return convert("", toType);
+ }
}
}
else if (object instanceof Collection) {
@@ -293,24 +277,21 @@
collection.addAll((Collection) object);
return unmodifiableCollection(collection);
}
- else if (length == 1) {
- Object value;
- if (object instanceof List) {
- value = ((List) object).get(0);
+ else {
+ if (length > 0) {
+ Object value;
+ if (object instanceof List) {
+ value = ((List) object).get(0);
+ }
+ else {
+ Iterator it = ((Collection) object).iterator();
+ value = it.next();
+ }
+ return convert(value, toType);
}
else {
- Iterator it = ((Collection) object).iterator();
- value = it.next();
+ return convert("", toType);
}
- return convert(value, toType);
- }
- else {
- throw new RuntimeException(
- "Cannot convert collection to "
- + toType
- + ", it contains "
- + length
- + " elements");
}
}
else if (object instanceof NodeSet) {
@@ -319,6 +300,37 @@
else if (object instanceof Pointer) {
return convert(((Pointer) object).getValue(), toType);
}
+ else if (toType == String.class) {
+ return object.toString();
+ }
+ else if (object instanceof Boolean) {
+ if (toType == boolean.class) {
+ return object;
+ }
+ boolean value = ((Boolean) object).booleanValue();
+ return allocateNumber(toType, value ? 1 : 0);
+ }
+ else if (object instanceof Number) {
+ double value = ((Number) object).doubleValue();
+ if (toType == boolean.class || toType == Boolean.class) {
+ return value == 0.0 ? Boolean.FALSE : Boolean.TRUE;
+ }
+ if (toType.isPrimitive()
+ || Number.class.isAssignableFrom(toType)) {
+ return allocateNumber(toType, value);
+ }
+ }
+ else if (object instanceof Character) {
+ if (toType == char.class) {
+ return object;
+ }
+ }
+ else if (object instanceof String) {
+ Object value = convertStringToPrimitive(object, toType);
+ if (value != null) {
+ return value;
+ }
+ }
throw new RuntimeException(
"Cannot convert " + object.getClass() + " to " + toType);
@@ -503,7 +515,7 @@
throw new UnsupportedOperationException();
}
- public Object clone(){
+ public Object clone() {
return this;
}
1.1
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/StressTest.java
Index: StressTest.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/StressTest.java,v
1.1 2003/03/25 02:41:34 dmitri Exp $
* $Revision: 1.1 $
* $Date: 2003/03/25 02:41:34 $
*
* ====================================================================
* 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 and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.jxpath.ri;
import junit.framework.TestCase;
import org.apache.commons.jxpath.JXPathContext;
/**
* Test thread safety.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2003/03/25 02:41:34 $
*/
public class StressTest extends TestCase {
private static final int THREAD_COUNT = 50;
private static final int THREAD_DURATION = 1000;
private static JXPathContext context;
private static int count;
private static Throwable exception;
/**
* Construct a new instance of this test case.
*
* @param name Name of the test case
*/
public StressTest(String name) {
super(name);
}
public void testThreads() throws Throwable {
context = JXPathContext.newContext(null, new Double(100));
Thread[] threadArray = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threadArray[i] = new Thread(new StressRunnable());
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].start();
}
for (int i = 0; i < threadArray.length; i++) {
try {
threadArray[i].join();
}
catch (InterruptedException e) {
assertTrue("Interrupted", false);
}
}
if (exception != null) {
throw exception;
}
assertEquals("Test count", THREAD_COUNT * THREAD_DURATION, count);
}
private final class StressRunnable implements Runnable {
public void run() {
for (int j = 0; j < THREAD_DURATION && exception == null; j++) {
try {
double random = 1 + Math.random();
double sum =
((Double) context.getValue("/ + " + random))
.doubleValue();
assertEquals(100 + random, sum, 0.0001);
synchronized (context) {
count++;
}
}
catch (Throwable t) {
exception = t;
}
}
}
}
}
1.8 +53 -5
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/ExtensionFunctionTest.java
Index: ExtensionFunctionTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/ExtensionFunctionTest.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ExtensionFunctionTest.java 11 Mar 2003 00:59:36 -0000 1.7
+++ ExtensionFunctionTest.java 25 Mar 2003 02:41:34 -0000 1.8
@@ -290,7 +290,9 @@
// Two ClassFunctions are sharing the same prefix.
// This is TestFunctions2
assertXPathValue(context, "string(test:increment(8))", "9");
-
+
+ // See that a NodeSet gets properly converted to a string
+ assertXPathValue(context, "test:string(/beans/name)", "Name 1");
}
public void testExpressionContext() {
@@ -330,6 +332,52 @@
context,
"/beans[contains(test:path(), '[2]')]/name",
"Name 2");
+ }
+
+ public void testCollectionReturn() {
+ assertXPathValueIterator(
+ context,
+ "test:collection()/name",
+ list("foo", "bar"));
+
+ assertXPathPointerIterator(
+ context,
+ "test:collection()/name",
+ list("/.[1]/name", "/.[2]/name"));
+
+ assertXPathValue(
+ context,
+ "test:collection()/name",
+ "foo");
+
+ assertXPathValue(
+ context,
+ "test:collection()/@name",
+ "foo");
+ }
+
+ public void testNodeSetReturn() {
+ assertXPathValueIterator(
+ context,
+ "test:nodeSet()/name",
+ list("Name 1", "Name 2"));
+
+ assertXPathPointerIterator(
+ context,
+ "test:nodeSet()/name",
+ list("/beans[1]/name", "/beans[2]/name"));
+
+ assertXPathValueAndPointer(
+ context,
+ "test:nodeSet()/name",
+ "Name 1",
+ "/beans[1]/name");
+
+ assertXPathValueAndPointer(
+ context,
+ "test:nodeSet()/@name",
+ "Name 1",
+ "/beans[1]/@name");
}
private static class Context implements ExpressionContext {
1.6 +28 -4
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/TestFunctions.java
Index: TestFunctions.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/TestFunctions.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TestFunctions.java 11 Mar 2003 00:59:36 -0000 1.5
+++ TestFunctions.java 25 Mar 2003 02:41:34 -0000 1.6
@@ -61,11 +61,15 @@
*/
package org.apache.commons.jxpath.ri.compiler;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
+import org.apache.commons.jxpath.BasicNodeSet;
import org.apache.commons.jxpath.ExpressionContext;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.NestedTestBean;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.NodeSet;
@@ -160,5 +164,25 @@
public static int countPointers(NodeSet nodeSet) {
return nodeSet.getPointers().size();
+ }
+
+ public static String string(String string) {
+ return string;
+ }
+
+ public static Collection collection() {
+ ArrayList list = new ArrayList();
+ list.add(new NestedTestBean("foo"));
+ list.add(new NestedTestBean("bar"));
+ return list;
+ }
+
+ public static NodeSet nodeSet(ExpressionContext context) {
+ JXPathContext jxpathCtx = context.getJXPathContext();
+ BasicNodeSet set = new BasicNodeSet();
+ set.add(jxpathCtx.getPointer("/beans[1]"));
+ set.add(jxpathCtx.getPointer("/beans[2]"));
+
+ return set;
}
}
1.13 +5 -5
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/BeanModelTestCase.java
Index: BeanModelTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/BeanModelTestCase.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- BeanModelTestCase.java 11 Mar 2003 00:59:37 -0000 1.12
+++ BeanModelTestCase.java 25 Mar 2003 02:41:35 -0000 1.13
@@ -837,7 +837,7 @@
new Integer(1),
"/nestedBean/beans[last() + 1]");
}
- catch (Exception e){
+ catch (Exception e) {
ex = true;
}
assertTrue("Exception thrown on invalid path for creation", ex);
1.4 +73 -4
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/util/BasicTypeConverterTest.java
Index: BasicTypeConverterTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/util/BasicTypeConverterTest.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- BasicTypeConverterTest.java 11 Mar 2003 00:59:40 -0000 1.3
+++ BasicTypeConverterTest.java 25 Mar 2003 02:41:35 -0000 1.4
@@ -65,11 +65,15 @@
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import junit.framework.TestCase;
+import org.apache.commons.jxpath.NodeSet;
+import org.apache.commons.jxpath.Pointer;
+
/**
* Tests BasicTypeConverter
*
@@ -144,4 +148,69 @@
expected,
result);
}
+
+ public void testSingletonCollectionToString() {
+ assertConversion(Collections.singleton("Earth"), String.class, "Earth");
+ }
+
+ public void testSingletonArrayToString() {
+ assertConversion(new String[] { "Earth" }, String.class, "Earth");
+ }
+
+ public void testPointerToString() {
+ assertConversion(new Pointer() {
+ public Object getValue() {
+ return "value";
+ }
+ public Object getNode() {
+ return null;
+ }
+ public void setValue(Object value) {
+ }
+ public Object getRootNode() {
+ return null;
+ }
+ public String asPath() {
+ return null;
+ }
+ public Object clone() {
+ return null;
+ }
+ public int compareTo(Object o) {
+ return 0;
+ }
+ }, String.class, "value");
+ }
+
+ public void testNodeSetToString() {
+ assertConversion(new NodeSet() {
+ public List getNodes() {
+ return null;
+ }
+ public List getPointers() {
+ return null;
+ }
+ public List getValues() {
+ List list = new ArrayList();
+ list.add("hello");
+ list.add("goodbye");
+ return Collections.singletonList(list);
+ }
+ }, String.class, "hello");
+ }
+
+ // succeeds in current version
+ public void testNodeSetToInteger() {
+ assertConversion(new NodeSet() {
+ public List getNodes() {
+ return null;
+ }
+ public List getPointers() {
+ return null;
+ }
+ public List getValues() {
+ return Collections.singletonList("9");
+ }
+ }, Integer.class, new Integer(9));
+ }
}
1.12 +12 -0 jakarta-commons/jxpath/xdocs/users-guide.xml
Index: users-guide.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/xdocs/users-guide.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- users-guide.xml 19 Feb 2003 00:59:51 -0000 1.11
+++ users-guide.xml 25 Mar 2003 02:41:35 -0000 1.12
@@ -116,6 +116,8 @@
</li>
<li><a href="#Collections as Arguments">Collections as Arguments</a>
</li>
+ <li><a href="#Collection as the Return Value">Collection as the Return
Value</a>
+ </li>
</ul>
</li>
<li><a href="#Type Conversions">Type Conversions</a>
@@ -1183,6 +1185,7 @@
</subsection>
<subsection name="Collections as Arguments">
+ <p>
There are two ways a collection can be passed to an extension function:
as a <a
href="apidocs/org/apache/commons/jxpath/NodeSet.html"><code>NodeSet</code></a>
or as a Collection proper. If the argument type is declared
@@ -1190,6 +1193,7 @@
out of the node set and pass those to the function as a regular collection.
Note that a collection is always passed to an extension function by value -
it cannot be modified.
+ </p>
<!--============================ + SOURCE + ============================-->
<source>
@@ -1234,6 +1238,14 @@
</source>
<!--============================ - SOURCE - ============================-->
+ </subsection>
+ <subsection name="Collection as the Return Value">
+ <p>
+ A custom function can return a collection of arbitrary objects or a
NodeSet.
+ The simple implementation of NodeSet,
+ <a
href="apidocs/org/apache/commons/jxpath/BasicNodeSet.html#setLocale">BasicNodeSet</a>,
+ may come handy.
+ </p>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]