diff --git a/pom.xml b/pom.xml
index 9e9d0f8b7..e02f84973 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,13 +21,15 @@ under the License.
org.apache.commons
commons-parent
- 10
+ 11
4.0.0
commons-jxpath
commons-jxpath
Commons JXPath
- 1.3-SNAPSHOT
+
+ 1.3
A Java-based implementation of XPath 1.0 that, in addition to XML processing, can inspect/modify Java object graphs (the library's explicit purpose) and even mixed Java/XML structures.
http://commons.apache.org/jxpath/
@@ -62,7 +64,8 @@ under the License.
jxpath
- 1.2
+
+ 1.3
JXPATH
12310480
@@ -98,20 +101,32 @@ under the License.
gnu
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
+
+ commons-logging
+ commons-logging
+ 1.1.1
+ runtime
+
+
+
-
- commons-logging
- commons-logging
- 1.1.1
- true
- runtime
-
xerces
xercesImpl
2.4.0
+ provided
true
@@ -153,13 +168,6 @@ under the License.
1.7.0
true
-
- commons-collections
- commons-collections
- 3.2
- true
- runtime
-
com.mockrunner
mockrunner-jdk1.3-j2ee1.3
diff --git a/src/assembly/src.xml b/src/assembly/src.xml
index 558c9955a..5e9f37a9f 100644
--- a/src/assembly/src.xml
+++ b/src/assembly/src.xml
@@ -44,5 +44,8 @@
xdocs
+
+ conf
+
diff --git a/src/java/org/apache/commons/jxpath/JXPathBasicBeanInfo.java b/src/java/org/apache/commons/jxpath/JXPathBasicBeanInfo.java
index 7c0db8906..31eb20c99 100644
--- a/src/java/org/apache/commons/jxpath/JXPathBasicBeanInfo.java
+++ b/src/java/org/apache/commons/jxpath/JXPathBasicBeanInfo.java
@@ -23,153 +23,165 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.Map;
/**
* An implementation of JXPathBeanInfo based on JavaBeans' BeanInfo. Properties
* advertised by JXPathBasicBeanInfo are the same as those advertised by
* BeanInfo for the corresponding class.
*
- * @see java.beans.BeanInfo
- * @see java.beans.Introspector
- *
* @author Dmitri Plotnikov
* @version $Revision$ $Date$
+ * @see java.beans.BeanInfo
+ * @see java.beans.Introspector
*/
+@SuppressWarnings({"unchecked", "WeakerAccess"})
public class JXPathBasicBeanInfo implements JXPathBeanInfo {
- private static final long serialVersionUID = -3863803443111484155L;
- private static final Comparator PROPERTY_DESCRIPTOR_COMPARATOR = new Comparator() {
- public int compare(Object left, Object right) {
- return ((PropertyDescriptor) left).getName().compareTo(
- ((PropertyDescriptor) right).getName());
- }
- };
-
- private boolean atomic = false;
- private Class clazz;
- private Class dynamicPropertyHandlerClass;
- private transient PropertyDescriptor[] propertyDescriptors;
- private transient HashMap propertyDescriptorMap;
-
- /**
- * Create a new JXPathBasicBeanInfo.
- * @param clazz bean class
- */
- public JXPathBasicBeanInfo(Class clazz) {
- this.clazz = clazz;
- }
+ private static final long serialVersionUID = -3863803443111484155L;
- /**
- * Create a new JXPathBasicBeanInfo.
- * @param clazz bean class
- * @param atomic whether objects of this class are treated as atomic
- * objects which have no properties of their own.
- */
- public JXPathBasicBeanInfo(Class clazz, boolean atomic) {
- this.clazz = clazz;
- this.atomic = atomic;
- }
+ private static final Comparator PROPERTY_DESCRIPTOR_COMPARATOR =
+ Comparator.comparing(left -> ((PropertyDescriptor) left).getName());
- /**
- * Create a new JXPathBasicBeanInfo.
- * @param clazz bean class
- * @param dynamicPropertyHandlerClass dynamic property handler class
- */
- public JXPathBasicBeanInfo(Class clazz, Class dynamicPropertyHandlerClass) {
- this.clazz = clazz;
- this.atomic = false;
- this.dynamicPropertyHandlerClass = dynamicPropertyHandlerClass;
- }
+ private boolean atomic = false;
+ private Class clazz;
+ private Class dynamicPropertyHandlerClass;
+ private transient volatile PropertyDescriptor[] propertyDescriptors;
+ private transient volatile Map propertyDescriptorMap;
- /**
- * Returns true if objects of this class are treated as atomic
- * objects which have no properties of their own.
- * @return boolean
- */
- public boolean isAtomic() {
- return atomic;
- }
+ /**
+ * Create a new JXPathBasicBeanInfo.
+ *
+ * @param clazz bean class
+ */
+ public JXPathBasicBeanInfo(Class clazz) {
+ this.clazz = clazz;
+ this.propertyDescriptors = descriptors();
+ }
+
+ /**
+ * Create a new JXPathBasicBeanInfo.
+ *
+ * @param clazz bean class
+ * @param atomic whether objects of this class are treated as atomic
+ * objects which have no properties of their own.
+ */
+ public JXPathBasicBeanInfo(Class clazz, boolean atomic) {
+ this.clazz = clazz;
+ this.atomic = atomic;
+ this.propertyDescriptors = descriptors();
+ }
+
+ /**
+ * Create a new JXPathBasicBeanInfo.
+ *
+ * @param clazz bean class
+ * @param dynamicPropertyHandlerClass dynamic property handler class
+ */
+ public JXPathBasicBeanInfo(Class clazz, Class dynamicPropertyHandlerClass) {
+ this.clazz = clazz;
+ this.atomic = false;
+ this.dynamicPropertyHandlerClass = dynamicPropertyHandlerClass;
+ this.propertyDescriptors = descriptors();
+ }
+
+ /**
+ * Returns true if objects of this class are treated as atomic
+ * objects which have no properties of their own.
+ *
+ * @return boolean
+ */
+ public boolean isAtomic() {
+ return atomic;
+ }
- /**
- * Return true if the corresponding objects have dynamic properties.
- * @return boolean
- */
- public boolean isDynamic() {
- return dynamicPropertyHandlerClass != null;
+ /**
+ * Return true if the corresponding objects have dynamic properties.
+ *
+ * @return boolean
+ */
+ public boolean isDynamic() {
+ return dynamicPropertyHandlerClass != null;
+ }
+
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ if (this.propertyDescriptors == null) {
+ this.propertyDescriptors = descriptors();
}
+ return this.propertyDescriptors;
+ }
- public synchronized PropertyDescriptor[] getPropertyDescriptors() {
- if (propertyDescriptors == null) {
- if (clazz == Object.class) {
- propertyDescriptors = new PropertyDescriptor[0];
- }
- else {
- try {
- BeanInfo bi = null;
- if (clazz.isInterface()) {
- bi = Introspector.getBeanInfo(clazz);
- }
- else {
- bi = Introspector.getBeanInfo(clazz, Object.class);
- }
- PropertyDescriptor[] pds = bi.getPropertyDescriptors();
- PropertyDescriptor[] descriptors = new PropertyDescriptor[pds.length];
- System.arraycopy(pds, 0, descriptors, 0, pds.length);
- Arrays.sort(descriptors, PROPERTY_DESCRIPTOR_COMPARATOR);
- propertyDescriptors = descriptors;
- }
- catch (IntrospectionException ex) {
- ex.printStackTrace();
- }
- }
- }
- if (propertyDescriptors.length == 0) {
- return propertyDescriptors;
- }
- PropertyDescriptor[] result = new PropertyDescriptor[propertyDescriptors.length];
- System.arraycopy(propertyDescriptors, 0, result, 0, propertyDescriptors.length);
- return result;
+ public PropertyDescriptor getPropertyDescriptor(String propertyName) {
+ if (this.propertyDescriptorMap == null) {
+ this.propertyDescriptorMap = descriptorsMap();
}
+ return (PropertyDescriptor) propertyDescriptorMap.get(propertyName);
+ }
- public synchronized PropertyDescriptor getPropertyDescriptor(String propertyName) {
- if (propertyDescriptorMap == null) {
- propertyDescriptorMap = new HashMap();
- PropertyDescriptor[] pds = getPropertyDescriptors();
- for (int i = 0; i < pds.length; i++) {
- propertyDescriptorMap.put(pds[i].getName(), pds[i]);
- }
+ /**
+ * For a dynamic class, returns the corresponding DynamicPropertyHandler
+ * class.
+ *
+ * @return Class
+ */
+ public Class getDynamicPropertyHandlerClass() {
+ return dynamicPropertyHandlerClass;
+ }
+
+ private PropertyDescriptor[] descriptors() {
+ if (clazz == Object.class) {
+ return new PropertyDescriptor[0];
+ } else {
+ try {
+ BeanInfo bi;
+ if (clazz.isInterface()) {
+ bi = Introspector.getBeanInfo(clazz);
+ } else {
+ bi = Introspector.getBeanInfo(clazz, Object.class);
}
- return (PropertyDescriptor) propertyDescriptorMap.get(propertyName);
+ PropertyDescriptor[] pds = bi.getPropertyDescriptors();
+ PropertyDescriptor[] descriptors = new PropertyDescriptor[pds.length];
+ System.arraycopy(pds, 0, descriptors, 0, pds.length);
+ Arrays.sort(descriptors, PROPERTY_DESCRIPTOR_COMPARATOR);
+ return descriptors;
+ } catch (IntrospectionException ex) {
+ ex.printStackTrace();
+ }
}
+ return new PropertyDescriptor[0];
+ }
- /**
- * For a dynamic class, returns the corresponding DynamicPropertyHandler
- * class.
- * @return Class
- */
- public Class getDynamicPropertyHandlerClass() {
- return dynamicPropertyHandlerClass;
+ private Map descriptorsMap() {
+ Map propertyDescriptorMap = new HashMap();
+ PropertyDescriptor[] pds = getPropertyDescriptors();
+ for (PropertyDescriptor pd : pds) {
+ propertyDescriptorMap.put(pd.getName(), pd);
}
+ return propertyDescriptorMap;
+ }
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append("BeanInfo [class = ");
- buffer.append(clazz.getName());
- if (isDynamic()) {
- buffer.append(", dynamic");
- }
- if (isAtomic()) {
- buffer.append(", atomic");
- }
- buffer.append(", properties = ");
- PropertyDescriptor[] jpds = getPropertyDescriptors();
- for (int i = 0; i < jpds.length; i++) {
- buffer.append("\n ");
- buffer.append(jpds[i].getPropertyType());
- buffer.append(": ");
- buffer.append(jpds[i].getName());
- }
- buffer.append("]");
- return buffer.toString();
+
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("BeanInfo [class = ");
+ buffer.append(clazz.getName());
+ if (isDynamic()) {
+ buffer.append(", dynamic");
+ }
+ if (isAtomic()) {
+ buffer.append(", atomic");
}
+ buffer.append(", properties = ");
+ PropertyDescriptor[] jpds = getPropertyDescriptors();
+ for (PropertyDescriptor jpd : jpds) {
+ buffer.append("\n ");
+ buffer.append(jpd.getPropertyType());
+ buffer.append(": ");
+ buffer.append(jpd.getName());
+ }
+ buffer.append("]");
+ return buffer.toString();
+ }
+
+
}
diff --git a/src/java/org/apache/commons/jxpath/JXPathIntrospector.java b/src/java/org/apache/commons/jxpath/JXPathIntrospector.java
index c52ff31ec..6c5f3757c 100644
--- a/src/java/org/apache/commons/jxpath/JXPathIntrospector.java
+++ b/src/java/org/apache/commons/jxpath/JXPathIntrospector.java
@@ -18,7 +18,7 @@
import java.util.Date;
import java.util.Map;
-import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
/**
* JXPathIntrospector maintains a registry of {@link JXPathBeanInfo
@@ -29,8 +29,8 @@
*/
public class JXPathIntrospector {
- private static HashMap byClass = new HashMap();
- private static HashMap byInterface = new HashMap();
+ private static Map byClass = new ConcurrentHashMap();
+ private static Map byInterface = new ConcurrentHashMap();
static {
registerAtomicClass(Class.class);
@@ -163,7 +163,7 @@ private static JXPathBeanInfo findDynamicBeanInfo(Class beanClass) {
* @param beanClass for which to look for an info provider
* @return JXPathBeanInfo instance or null if none found
*/
- private static synchronized JXPathBeanInfo findInformant(Class beanClass) {
+ private static JXPathBeanInfo findInformant(Class beanClass) {
String name = beanClass.getName() + "XBeanInfo";
try {
return (JXPathBeanInfo) instantiate(beanClass, name);
diff --git a/src/java/org/apache/commons/jxpath/ri/compiler/Path.java b/src/java/org/apache/commons/jxpath/ri/compiler/Path.java
index 221140296..2aa476a6d 100644
--- a/src/java/org/apache/commons/jxpath/ri/compiler/Path.java
+++ b/src/java/org/apache/commons/jxpath/ri/compiler/Path.java
@@ -196,7 +196,7 @@ protected Pointer getSingleNodePointerForSteps(EvalContext context) {
* @param context evaluation context
* @return Pointer
*/
- private Pointer searchForPath(EvalContext context) {
+ protected Pointer searchForPath(EvalContext context) {
EvalContext ctx = buildContextChain(context, steps.length, true);
Pointer pointer = ctx.getSingleNodePointer();
@@ -245,7 +245,7 @@ protected EvalContext evalSteps(EvalContext context) {
* @param createInitialContext whether to create the initial context
* @return created context
*/
- private EvalContext buildContextChain(
+ protected EvalContext buildContextChain(
EvalContext context,
int stepCount,
boolean createInitialContext) {
diff --git a/src/java/org/apache/commons/jxpath/ri/model/beans/BeanPropertyPointer.java b/src/java/org/apache/commons/jxpath/ri/model/beans/BeanPropertyPointer.java
index caf9e4f19..cf1fa961c 100644
--- a/src/java/org/apache/commons/jxpath/ri/model/beans/BeanPropertyPointer.java
+++ b/src/java/org/apache/commons/jxpath/ri/model/beans/BeanPropertyPointer.java
@@ -303,7 +303,7 @@ private PropertyDescriptor getPropertyDescriptor() {
* Get all PropertyDescriptors.
* @return PropertyDescriptor[]
*/
- protected synchronized PropertyDescriptor[] getPropertyDescriptors() {
+ protected PropertyDescriptor[] getPropertyDescriptors() {
if (propertyDescriptors == null) {
propertyDescriptors = beanInfo.getPropertyDescriptors();
}
diff --git a/src/java/org/apache/commons/jxpath/util/ValueUtils.java b/src/java/org/apache/commons/jxpath/util/ValueUtils.java
index 7b288a650..0d489b0f0 100644
--- a/src/java/org/apache/commons/jxpath/util/ValueUtils.java
+++ b/src/java/org/apache/commons/jxpath/util/ValueUtils.java
@@ -41,621 +41,621 @@
* @version $Revision$ $Date$
*/
public class ValueUtils {
- private static Map dynamicPropertyHandlerMap = new HashMap();
- private static final int UNKNOWN_LENGTH_MAX_COUNT = 16000;
-
- /**
- * Returns true if the object is an array or a Collection.
- * @param value to test
- * @return boolean
- */
- public static boolean isCollection(Object value) {
- value = getValue(value);
- if (value == null) {
- return false;
- }
- if (value.getClass().isArray()) {
- return true;
- }
- if (value instanceof Collection) {
- return true;
- }
- return false;
- }
-
- /**
- * Returns 1 if the type is a collection,
- * -1 if it is definitely not
- * and 0 if it may be a collection in some cases.
- * @param clazz to test
- * @return int
- */
- public static int getCollectionHint(Class clazz) {
- if (clazz.isArray()) {
- return 1;
- }
+ private static Map dynamicPropertyHandlerMap = new HashMap();
+ private static final int UNKNOWN_LENGTH_MAX_COUNT = 16000;
+
+ /**
+ * Returns true if the object is an array or a Collection.
+ * @param value to test
+ * @return boolean
+ */
+ public static boolean isCollection(Object value) {
+ value = getValue(value);
+ if (value == null) {
+ return false;
+ }
+ if (value.getClass().isArray()) {
+ return true;
+ }
+ if (value instanceof Collection) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns 1 if the type is a collection,
+ * -1 if it is definitely not
+ * and 0 if it may be a collection in some cases.
+ * @param clazz to test
+ * @return int
+ */
+ public static int getCollectionHint(Class clazz) {
+ if (clazz.isArray()) {
+ return 1;
+ }
- if (Collection.class.isAssignableFrom(clazz)) {
- return 1;
- }
+ if (Collection.class.isAssignableFrom(clazz)) {
+ return 1;
+ }
- if (clazz.isPrimitive()) {
- return -1;
- }
+ if (clazz.isPrimitive()) {
+ return -1;
+ }
- if (clazz.isInterface()) {
- return 0;
- }
+ if (clazz.isInterface()) {
+ return 0;
+ }
- if (Modifier.isFinal(clazz.getModifiers())) {
- return -1;
- }
+ if (Modifier.isFinal(clazz.getModifiers())) {
+ return -1;
+ }
- return 0;
- }
-
- /**
- * If there is a regular non-indexed read method for this property,
- * uses this method to obtain the collection and then returns its
- * length.
- * Otherwise, attempts to guess the length of the collection by
- * calling the indexed get method repeatedly. The method is supposed
- * to throw an exception if the index is out of bounds.
- * @param object collection
- * @param pd IndexedPropertyDescriptor
- * @return int
- */
- public static int getIndexedPropertyLength(Object object,
- IndexedPropertyDescriptor pd) {
- if (pd.getReadMethod() != null) {
- return getLength(getValue(object, pd));
- }
+ return 0;
+ }
+
+ /**
+ * If there is a regular non-indexed read method for this property,
+ * uses this method to obtain the collection and then returns its
+ * length.
+ * Otherwise, attempts to guess the length of the collection by
+ * calling the indexed get method repeatedly. The method is supposed
+ * to throw an exception if the index is out of bounds.
+ * @param object collection
+ * @param pd IndexedPropertyDescriptor
+ * @return int
+ */
+ public static int getIndexedPropertyLength(Object object,
+ IndexedPropertyDescriptor pd) {
+ if (pd.getReadMethod() != null) {
+ return getLength(getValue(object, pd));
+ }
- Method readMethod = pd.getIndexedReadMethod();
- if (readMethod == null) {
- throw new JXPathException(
- "No indexed read method for property " + pd.getName());
- }
+ Method readMethod = pd.getIndexedReadMethod();
+ if (readMethod == null) {
+ throw new JXPathException(
+ "No indexed read method for property " + pd.getName());
+ }
- for (int i = 0; i < UNKNOWN_LENGTH_MAX_COUNT; i++) {
- try {
- readMethod.invoke(object, new Object[] { new Integer(i)});
- }
- catch (Throwable t) {
- return i;
- }
- }
+ for (int i = 0; i < UNKNOWN_LENGTH_MAX_COUNT; i++) {
+ try {
+ readMethod.invoke(object, i);
+ }
+ catch (Throwable t) {
+ return i;
+ }
+ }
- throw new JXPathException(
- "Cannot determine the length of the indexed property "
- + pd.getName());
- }
-
- /**
- * Returns the length of the supplied collection. If the supplied object
- * is not a collection, returns 1. If collection is null, returns 0.
- * @param collection to check
- * @return int
- */
- public static int getLength(Object collection) {
- if (collection == null) {
- return 0;
- }
- collection = getValue(collection);
- if (collection.getClass().isArray()) {
- return Array.getLength(collection);
- }
- if (collection instanceof Collection) {
- return ((Collection) collection).size();
- }
- return 1;
- }
-
- /**
- * Returns an iterator for the supplied collection. If the argument
- * is null, returns an empty iterator. If the argument is not
- * a collection, returns an iterator that produces just that one object.
- * @param collection to iterate
- * @return Iterator
- */
- public static Iterator iterate(Object collection) {
- if (collection == null) {
- return Collections.EMPTY_LIST.iterator();
- }
- if (collection.getClass().isArray()) {
- int length = Array.getLength(collection);
- if (length == 0) {
- return Collections.EMPTY_LIST.iterator();
- }
- ArrayList list = new ArrayList();
- for (int i = 0; i < length; i++) {
- list.add(Array.get(collection, i));
- }
- return list.iterator();
- }
- if (collection instanceof Collection) {
- return ((Collection) collection).iterator();
- }
- return Collections.singletonList(collection).iterator();
- }
-
- /**
- * Grows the collection if necessary to the specified size. Returns
- * the new, expanded collection.
- * @param collection to expand
- * @param size desired size
- * @return collection or array
- */
- public static Object expandCollection(Object collection, int size) {
- if (collection == null) {
- return null;
- }
- if (size < getLength(collection)) {
- throw new JXPathException("adjustment of " + collection
- + " to size " + size + " is not an expansion");
+ throw new JXPathException(
+ "Cannot determine the length of the indexed property "
+ + pd.getName());
+ }
+
+ /**
+ * Returns the length of the supplied collection. If the supplied object
+ * is not a collection, returns 1. If collection is null, returns 0.
+ * @param collection to check
+ * @return int
+ */
+ public static int getLength(Object collection) {
+ if (collection == null) {
+ return 0;
+ }
+ collection = getValue(collection);
+ if (collection.getClass().isArray()) {
+ return Array.getLength(collection);
+ }
+ if (collection instanceof Collection) {
+ return ((Collection) collection).size();
+ }
+ return 1;
+ }
+
+ /**
+ * Returns an iterator for the supplied collection. If the argument
+ * is null, returns an empty iterator. If the argument is not
+ * a collection, returns an iterator that produces just that one object.
+ * @param collection to iterate
+ * @return Iterator
+ */
+ public static Iterator iterate(Object collection) {
+ if (collection == null) {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ if (collection.getClass().isArray()) {
+ int length = Array.getLength(collection);
+ if (length == 0) {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < length; i++) {
+ list.add(Array.get(collection, i));
+ }
+ return list.iterator();
+ }
+ if (collection instanceof Collection) {
+ return ((Collection) collection).iterator();
+ }
+ return Collections.singletonList(collection).iterator();
+ }
+
+ /**
+ * Grows the collection if necessary to the specified size. Returns
+ * the new, expanded collection.
+ * @param collection to expand
+ * @param size desired size
+ * @return collection or array
+ */
+ public static Object expandCollection(Object collection, int size) {
+ if (collection == null) {
+ return null;
+ }
+ if (size < getLength(collection)) {
+ throw new JXPathException("adjustment of " + collection
+ + " to size " + size + " is not an expansion");
+ }
+ if (collection.getClass().isArray()) {
+ Object bigger =
+ Array.newInstance(
+ collection.getClass().getComponentType(),
+ size);
+ System.arraycopy(
+ collection,
+ 0,
+ bigger,
+ 0,
+ Array.getLength(collection));
+ return bigger;
+ }
+ if (collection instanceof Collection) {
+ while (((Collection) collection).size() < size) {
+ ((Collection) collection).add(null);
+ }
+ return collection;
+ }
+ throw new JXPathException(
+ "Cannot turn "
+ + collection.getClass().getName()
+ + " into a collection of size "
+ + size);
+ }
+
+ /**
+ * Remove the index'th element from the supplied collection.
+ * @param collection to edit
+ * @param index int
+ * @return the resulting collection
+ */
+ public static Object remove(Object collection, int index) {
+ collection = getValue(collection);
+ if (collection == null) {
+ return null;
+ }
+ if (index >= getLength(collection)) {
+ throw new JXPathException("No such element at index " + index);
+ }
+ if (collection.getClass().isArray()) {
+ int length = Array.getLength(collection);
+ Object smaller =
+ Array.newInstance(
+ collection.getClass().getComponentType(),
+ length - 1);
+ if (index > 0) {
+ System.arraycopy(collection, 0, smaller, 0, index);
+ }
+ if (index < length - 1) {
+ System.arraycopy(
+ collection,
+ index + 1,
+ smaller,
+ index,
+ length - index - 1);
+ }
+ return smaller;
+ }
+ if (collection instanceof List) {
+ int size = ((List) collection).size();
+ if (index < size) {
+ ((List) collection).remove(index);
+ }
+ return collection;
+ }
+ if (collection instanceof Collection) {
+ Iterator it = ((Collection) collection).iterator();
+ for (int i = 0; i < index; i++) {
+ if (!it.hasNext()) {
+ break;
+ }
+ it.next();
+ }
+ if (it.hasNext()) {
+ it.next();
+ it.remove();
+ }
+ return collection;
+ }
+ throw new JXPathException(
+ "Cannot remove "
+ + collection.getClass().getName()
+ + "["
+ + index
+ + "]");
+ }
+
+ /**
+ * Returns the index'th element of the supplied collection.
+ * @param collection to read
+ * @param index int
+ * @return collection[index]
+ */
+ public static Object getValue(Object collection, int index) {
+ collection = getValue(collection);
+ Object value = collection;
+ if (collection != null) {
+ if (collection.getClass().isArray()) {
+ if (index < 0 || index >= Array.getLength(collection)) {
+ return null;
+ }
+ value = Array.get(collection, index);
+ }
+ else if (collection instanceof List) {
+ if (index < 0 || index >= ((List) collection).size()) {
+ return null;
+ }
+ value = ((List) collection).get(index);
+ }
+ else if (collection instanceof Collection) {
+ int i = 0;
+ Iterator it = ((Collection) collection).iterator();
+ for (; i < index; i++) {
+ it.next();
+ }
+ if (it.hasNext()) {
+ value = it.next();
}
- if (collection.getClass().isArray()) {
- Object bigger =
- Array.newInstance(
- collection.getClass().getComponentType(),
- size);
- System.arraycopy(
- collection,
- 0,
- bigger,
- 0,
- Array.getLength(collection));
- return bigger;
+ else {
+ value = null;
}
- if (collection instanceof Collection) {
- while (((Collection) collection).size() < size) {
- ((Collection) collection).add(null);
- }
- return collection;
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Modifies the index'th element of the supplied collection.
+ * Converts the value to the required type if necessary.
+ * @param collection to edit
+ * @param index to replace
+ * @param value new value
+ */
+ public static void setValue(Object collection, int index, Object value) {
+ collection = getValue(collection);
+ if (collection != null) {
+ if (collection.getClass().isArray()) {
+ Array.set(
+ collection,
+ index,
+ convert(value, collection.getClass().getComponentType()));
+ }
+ else if (collection instanceof List) {
+ ((List) collection).set(index, value);
+ }
+ else if (collection instanceof Collection) {
+ throw new UnsupportedOperationException(
+ "Cannot set value of an element of a "
+ + collection.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * Returns the value of the bean's property represented by
+ * the supplied property descriptor.
+ * @param bean to read
+ * @param propertyDescriptor indicating what to read
+ * @return Object value
+ */
+ public static Object getValue(Object bean,
+ PropertyDescriptor propertyDescriptor) {
+ Object value;
+ try {
+ Method method =
+ getAccessibleMethod(propertyDescriptor.getReadMethod());
+ if (method == null) {
+ throw new JXPathException("No read method");
+ }
+ value = method.invoke(bean, new Object[0]);
+ }
+ catch (Exception ex) {
+ throw new JXPathException(
+ "Cannot access property: "
+ + (bean == null ? "null" : bean.getClass().getName())
+ + "."
+ + propertyDescriptor.getName(),
+ ex);
+ }
+ return value;
+ }
+
+ /**
+ * Modifies the value of the bean's property represented by
+ * the supplied property descriptor.
+ * @param bean to read
+ * @param propertyDescriptor indicating what to read
+ * @param value to set
+ */
+ public static void setValue(Object bean,
+ PropertyDescriptor propertyDescriptor, Object value) {
+ try {
+ Method method =
+ getAccessibleMethod(propertyDescriptor.getWriteMethod());
+ if (method == null) {
+ throw new JXPathException("No write method");
+ }
+ value = convert(value, propertyDescriptor.getPropertyType());
+ method.invoke(bean, new Object[] { value });
+ }
+ catch (Exception ex) {
+ throw new JXPathException(
+ "Cannot modify property: "
+ + (bean == null ? "null" : bean.getClass().getName())
+ + "."
+ + propertyDescriptor.getName(),
+ ex);
+ }
+ }
+
+ /**
+ * Convert value to type.
+ * @param value Object
+ * @param type destination
+ * @return conversion result
+ */
+ private static Object convert(Object value, Class type) {
+ try {
+ return TypeUtils.convert(value, type);
+ }
+ catch (Exception ex) {
+ throw new JXPathException(
+ "Cannot convert value of class "
+ + (value == null ? "null" : value.getClass().getName())
+ + " to type "
+ + type,
+ ex);
+ }
+ }
+
+ /**
+ * Returns the index'th element of the bean's property represented by
+ * the supplied property descriptor.
+ * @param bean to read
+ * @param propertyDescriptor indicating what to read
+ * @param index int
+ * @return Object
+ */
+ public static Object getValue(Object bean,
+ PropertyDescriptor propertyDescriptor, int index) {
+ if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
+ try {
+ IndexedPropertyDescriptor ipd =
+ (IndexedPropertyDescriptor) propertyDescriptor;
+ Method method = ipd.getIndexedReadMethod();
+ if (method != null) {
+ return method.invoke(
+ bean,
+ new Object[] { new Integer(index)});
+ }
+ }
+ catch (InvocationTargetException ex) {
+ Throwable t = ex.getTargetException();
+ if (t instanceof IndexOutOfBoundsException) {
+ return null;
}
throw new JXPathException(
- "Cannot turn "
- + collection.getClass().getName()
- + " into a collection of size "
- + size);
- }
-
- /**
- * Remove the index'th element from the supplied collection.
- * @param collection to edit
- * @param index int
- * @return the resulting collection
- */
- public static Object remove(Object collection, int index) {
- collection = getValue(collection);
- if (collection == null) {
- return null;
- }
- if (index >= getLength(collection)) {
- throw new JXPathException("No such element at index " + index);
- }
- if (collection.getClass().isArray()) {
- int length = Array.getLength(collection);
- Object smaller =
- Array.newInstance(
- collection.getClass().getComponentType(),
- length - 1);
- if (index > 0) {
- System.arraycopy(collection, 0, smaller, 0, index);
- }
- if (index < length - 1) {
- System.arraycopy(
- collection,
- index + 1,
- smaller,
- index,
- length - index - 1);
- }
- return smaller;
- }
- if (collection instanceof List) {
- int size = ((List) collection).size();
- if (index < size) {
- ((List) collection).remove(index);
- }
- return collection;
- }
- if (collection instanceof Collection) {
- Iterator it = ((Collection) collection).iterator();
- for (int i = 0; i < index; i++) {
- if (!it.hasNext()) {
- break;
- }
- it.next();
- }
- if (it.hasNext()) {
- it.next();
- it.remove();
- }
- return collection;
- }
+ "Cannot access property: " + propertyDescriptor.getName(),
+ t);
+ }
+ catch (Throwable ex) {
throw new JXPathException(
- "Cannot remove "
- + collection.getClass().getName()
- + "["
- + index
- + "]");
- }
-
- /**
- * Returns the index'th element of the supplied collection.
- * @param collection to read
- * @param index int
- * @return collection[index]
- */
- public static Object getValue(Object collection, int index) {
- collection = getValue(collection);
- Object value = collection;
- if (collection != null) {
- if (collection.getClass().isArray()) {
- if (index < 0 || index >= Array.getLength(collection)) {
- return null;
- }
- value = Array.get(collection, index);
- }
- else if (collection instanceof List) {
- if (index < 0 || index >= ((List) collection).size()) {
- return null;
- }
- value = ((List) collection).get(index);
- }
- else if (collection instanceof Collection) {
- int i = 0;
- Iterator it = ((Collection) collection).iterator();
- for (; i < index; i++) {
- it.next();
- }
- if (it.hasNext()) {
- value = it.next();
- }
- else {
- value = null;
- }
- }
- }
- return value;
- }
-
- /**
- * Modifies the index'th element of the supplied collection.
- * Converts the value to the required type if necessary.
- * @param collection to edit
- * @param index to replace
- * @param value new value
- */
- public static void setValue(Object collection, int index, Object value) {
- collection = getValue(collection);
- if (collection != null) {
- if (collection.getClass().isArray()) {
- Array.set(
- collection,
- index,
- convert(value, collection.getClass().getComponentType()));
- }
- else if (collection instanceof List) {
- ((List) collection).set(index, value);
- }
- else if (collection instanceof Collection) {
- throw new UnsupportedOperationException(
- "Cannot set value of an element of a "
- + collection.getClass().getName());
- }
- }
+ "Cannot access property: " + propertyDescriptor.getName(),
+ ex);
+ }
}
- /**
- * Returns the value of the bean's property represented by
- * the supplied property descriptor.
- * @param bean to read
- * @param propertyDescriptor indicating what to read
- * @return Object value
- */
- public static Object getValue(Object bean,
- PropertyDescriptor propertyDescriptor) {
- Object value;
- try {
- Method method =
- getAccessibleMethod(propertyDescriptor.getReadMethod());
- if (method == null) {
- throw new JXPathException("No read method");
- }
- value = method.invoke(bean, new Object[0]);
- }
- catch (Exception ex) {
- throw new JXPathException(
- "Cannot access property: "
- + (bean == null ? "null" : bean.getClass().getName())
- + "."
- + propertyDescriptor.getName(),
- ex);
- }
- return value;
- }
-
- /**
- * Modifies the value of the bean's property represented by
- * the supplied property descriptor.
- * @param bean to read
- * @param propertyDescriptor indicating what to read
- * @param value to set
- */
- public static void setValue(Object bean,
- PropertyDescriptor propertyDescriptor, Object value) {
- try {
- Method method =
- getAccessibleMethod(propertyDescriptor.getWriteMethod());
- if (method == null) {
- throw new JXPathException("No write method");
- }
- value = convert(value, propertyDescriptor.getPropertyType());
- method.invoke(bean, new Object[] { value });
- }
- catch (Exception ex) {
- throw new JXPathException(
- "Cannot modify property: "
- + (bean == null ? "null" : bean.getClass().getName())
- + "."
- + propertyDescriptor.getName(),
- ex);
- }
+ // We will fall through if there is no indexed read
+
+ return getValue(getValue(bean, propertyDescriptor), index);
+ }
+
+ /**
+ * Modifies the index'th element of the bean's property represented by
+ * the supplied property descriptor. Converts the value to the required
+ * type if necessary.
+ * @param bean to edit
+ * @param propertyDescriptor indicating what to set
+ * @param index int
+ * @param value to set
+ */
+ public static void setValue(Object bean,
+ PropertyDescriptor propertyDescriptor, int index, Object value) {
+ if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
+ try {
+ IndexedPropertyDescriptor ipd =
+ (IndexedPropertyDescriptor) propertyDescriptor;
+ Method method = ipd.getIndexedWriteMethod();
+ if (method != null) {
+ method.invoke(
+ bean,
+ new Object[] {
+ new Integer(index),
+ convert(value, ipd.getIndexedPropertyType())});
+ return;
+ }
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(
+ "Cannot access property: "
+ + propertyDescriptor.getName()
+ + ", "
+ + ex.getMessage());
+ }
}
-
- /**
- * Convert value to type.
- * @param value Object
- * @param type destination
- * @return conversion result
- */
- private static Object convert(Object value, Class type) {
- try {
- return TypeUtils.convert(value, type);
- }
- catch (Exception ex) {
- throw new JXPathException(
- "Cannot convert value of class "
- + (value == null ? "null" : value.getClass().getName())
- + " to type "
- + type,
- ex);
- }
+ // We will fall through if there is no indexed read
+ Object collection = getValue(bean, propertyDescriptor);
+ if (isCollection(collection)) {
+ setValue(collection, index, value);
}
-
- /**
- * Returns the index'th element of the bean's property represented by
- * the supplied property descriptor.
- * @param bean to read
- * @param propertyDescriptor indicating what to read
- * @param index int
- * @return Object
- */
- public static Object getValue(Object bean,
- PropertyDescriptor propertyDescriptor, int index) {
- if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
- try {
- IndexedPropertyDescriptor ipd =
- (IndexedPropertyDescriptor) propertyDescriptor;
- Method method = ipd.getIndexedReadMethod();
- if (method != null) {
- return method.invoke(
- bean,
- new Object[] { new Integer(index)});
- }
- }
- catch (InvocationTargetException ex) {
- Throwable t = ex.getTargetException();
- if (t instanceof IndexOutOfBoundsException) {
- return null;
- }
- throw new JXPathException(
- "Cannot access property: " + propertyDescriptor.getName(),
- t);
- }
- catch (Throwable ex) {
- throw new JXPathException(
- "Cannot access property: " + propertyDescriptor.getName(),
- ex);
- }
- }
-
- // We will fall through if there is no indexed read
-
- return getValue(getValue(bean, propertyDescriptor), index);
- }
-
- /**
- * Modifies the index'th element of the bean's property represented by
- * the supplied property descriptor. Converts the value to the required
- * type if necessary.
- * @param bean to edit
- * @param propertyDescriptor indicating what to set
- * @param index int
- * @param value to set
- */
- public static void setValue(Object bean,
- PropertyDescriptor propertyDescriptor, int index, Object value) {
- if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
- try {
- IndexedPropertyDescriptor ipd =
- (IndexedPropertyDescriptor) propertyDescriptor;
- Method method = ipd.getIndexedWriteMethod();
- if (method != null) {
- method.invoke(
- bean,
- new Object[] {
- new Integer(index),
- convert(value, ipd.getIndexedPropertyType())});
- return;
- }
- }
- catch (Exception ex) {
- throw new RuntimeException(
- "Cannot access property: "
- + propertyDescriptor.getName()
- + ", "
- + ex.getMessage());
- }
- }
- // We will fall through if there is no indexed read
- Object collection = getValue(bean, propertyDescriptor);
- if (isCollection(collection)) {
- setValue(collection, index, value);
- }
- else if (index == 0) {
- setValue(bean, propertyDescriptor, value);
- }
- else {
- throw new RuntimeException(
- "Not a collection: " + propertyDescriptor.getName());
- }
+ else if (index == 0) {
+ setValue(bean, propertyDescriptor, value);
+ }
+ else {
+ throw new RuntimeException(
+ "Not a collection: " + propertyDescriptor.getName());
+ }
+ }
+
+ /**
+ * If the parameter is a container, opens the container and
+ * return the contents. The method is recursive.
+ * @param object to read
+ * @return Object
+ */
+ public static Object getValue(Object object) {
+ while (object instanceof Container) {
+ object = ((Container) object).getValue();
+ }
+ return object;
+ }
+
+ /**
+ * Returns a shared instance of the dynamic property handler class
+ * returned by getDynamicPropertyHandlerClass().
+ * @param clazz to handle
+ * @return DynamicPropertyHandler
+ */
+ public static DynamicPropertyHandler getDynamicPropertyHandler(Class clazz) {
+ DynamicPropertyHandler handler =
+ (DynamicPropertyHandler) dynamicPropertyHandlerMap.get(clazz);
+ if (handler == null) {
+ try {
+ handler = (DynamicPropertyHandler) clazz.newInstance();
+ }
+ catch (Exception ex) {
+ throw new JXPathException(
+ "Cannot allocate dynamic property handler of class "
+ + clazz.getName(),
+ ex);
+ }
+ dynamicPropertyHandlerMap.put(clazz, handler);
+ }
+ return handler;
+ }
+
+ // -------------------------------------------------------- Private Methods
+ //
+ // The rest of the code in this file was copied FROM
+ // org.apache.commons.beanutils.PropertyUtil. We don't want to introduce
+ // a dependency on BeanUtils yet - DP.
+ //
+
+ /**
+ * Return an accessible method (that is, one that can be invoked via
+ * reflection) that implements the specified Method. If no such method
+ * can be found, return null.
+ *
+ * @param method The method that we wish to call
+ * @return Method
+ */
+ public static Method getAccessibleMethod(Method method) {
+
+ // Make sure we have a method to check
+ if (method == null) {
+ return (null);
}
- /**
- * If the parameter is a container, opens the container and
- * return the contents. The method is recursive.
- * @param object to read
- * @return Object
- */
- public static Object getValue(Object object) {
- while (object instanceof Container) {
- object = ((Container) object).getValue();
- }
- return object;
- }
-
- /**
- * Returns a shared instance of the dynamic property handler class
- * returned by getDynamicPropertyHandlerClass().
- * @param clazz to handle
- * @return DynamicPropertyHandler
- */
- public static DynamicPropertyHandler getDynamicPropertyHandler(Class clazz) {
- DynamicPropertyHandler handler =
- (DynamicPropertyHandler) dynamicPropertyHandlerMap.get(clazz);
- if (handler == null) {
- try {
- handler = (DynamicPropertyHandler) clazz.newInstance();
- }
- catch (Exception ex) {
- throw new JXPathException(
- "Cannot allocate dynamic property handler of class "
- + clazz.getName(),
- ex);
- }
- dynamicPropertyHandlerMap.put(clazz, handler);
- }
- return handler;
- }
-
- // -------------------------------------------------------- Private Methods
- //
- // The rest of the code in this file was copied FROM
- // org.apache.commons.beanutils.PropertyUtil. We don't want to introduce
- // a dependency on BeanUtils yet - DP.
- //
-
- /**
- * Return an accessible method (that is, one that can be invoked via
- * reflection) that implements the specified Method. If no such method
- * can be found, return null.
- *
- * @param method The method that we wish to call
- * @return Method
- */
- public static Method getAccessibleMethod(Method method) {
-
- // Make sure we have a method to check
- if (method == null) {
- return (null);
- }
-
- // If the requested method is not public we cannot call it
- if (!Modifier.isPublic(method.getModifiers())) {
- return (null);
- }
+ // If the requested method is not public we cannot call it
+ if (!Modifier.isPublic(method.getModifiers())) {
+ return (null);
+ }
- // If the declaring class is public, we are done
- Class clazz = method.getDeclaringClass();
- if (Modifier.isPublic(clazz.getModifiers())) {
- return (method);
- }
+ // If the declaring class is public, we are done
+ Class clazz = method.getDeclaringClass();
+ if (Modifier.isPublic(clazz.getModifiers())) {
+ return (method);
+ }
- String name = method.getName();
- Class[] parameterTypes = method.getParameterTypes();
- while (clazz != null) {
- // Check the implemented interfaces and subinterfaces
- Method aMethod = getAccessibleMethodFromInterfaceNest(clazz,
- name, parameterTypes);
- if (aMethod != null) {
- return aMethod;
- }
-
- clazz = clazz.getSuperclass();
- if (clazz != null && Modifier.isPublic(clazz.getModifiers())) {
- try {
- return clazz.getDeclaredMethod(name, parameterTypes);
- }
- catch (NoSuchMethodException e) { //NOPMD
- //ignore
- }
- }
+ String name = method.getName();
+ Class[] parameterTypes = method.getParameterTypes();
+ while (clazz != null) {
+ // Check the implemented interfaces and subinterfaces
+ Method aMethod = getAccessibleMethodFromInterfaceNest(clazz,
+ name, parameterTypes);
+ if (aMethod != null) {
+ return aMethod;
+ }
+
+ clazz = clazz.getSuperclass();
+ if (clazz != null && Modifier.isPublic(clazz.getModifiers())) {
+ try {
+ return clazz.getDeclaredMethod(name, parameterTypes);
}
- return null;
- }
-
- /**
- * Return an accessible method (that is, one that can be invoked via
- * reflection) that implements the specified method, by scanning through
- * all implemented interfaces and subinterfaces. If no such Method
- * can be found, return null.
- *
- * @param clazz Parent class for the interfaces to be checked
- * @param methodName Method name of the method we wish to call
- * @param parameterTypes The parameter type signatures
- * @return Method
- */
- private static Method getAccessibleMethodFromInterfaceNest(Class clazz,
- String methodName, Class[] parameterTypes) {
-
- Method method = null;
-
- // Check the implemented interfaces of the parent class
- Class[] interfaces = clazz.getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
-
- // Is this interface public?
- if (!Modifier.isPublic(interfaces[i].getModifiers())) {
- continue;
- }
-
- // Does the method exist on this interface?
- try {
- method =
- interfaces[i].getDeclaredMethod(methodName, parameterTypes);
- }
- catch (NoSuchMethodException e) { //NOPMD
- //ignore
- }
- if (method != null) {
- break;
- }
-
- // Recursively check our parent interfaces
- method =
- getAccessibleMethodFromInterfaceNest(
- interfaces[i],
- methodName,
- parameterTypes);
- if (method != null) {
- break;
- }
+ catch (NoSuchMethodException e) { //NOPMD
+ //ignore
}
-
- // Return whatever we have found
- return (method);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return an accessible method (that is, one that can be invoked via
+ * reflection) that implements the specified method, by scanning through
+ * all implemented interfaces and subinterfaces. If no such Method
+ * can be found, return null.
+ *
+ * @param clazz Parent class for the interfaces to be checked
+ * @param methodName Method name of the method we wish to call
+ * @param parameterTypes The parameter type signatures
+ * @return Method
+ */
+ private static Method getAccessibleMethodFromInterfaceNest(Class clazz,
+ String methodName, Class[] parameterTypes) {
+
+ Method method = null;
+
+ // Check the implemented interfaces of the parent class
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+
+ // Is this interface public?
+ if (!Modifier.isPublic(interfaces[i].getModifiers())) {
+ continue;
+ }
+
+ // Does the method exist on this interface?
+ try {
+ method =
+ interfaces[i].getDeclaredMethod(methodName, parameterTypes);
+ }
+ catch (NoSuchMethodException e) { //NOPMD
+ //ignore
+ }
+ if (method != null) {
+ break;
+ }
+
+ // Recursively check our parent interfaces
+ method =
+ getAccessibleMethodFromInterfaceNest(
+ interfaces[i],
+ methodName,
+ parameterTypes);
+ if (method != null) {
+ break;
+ }
}
+
+ // Return whatever we have found
+ return (method);
+ }
}
diff --git a/xdocs/download_jxpath.xml b/xdocs/download_jxpath.xml
index 599536b82..82a25b5d0 100644
--- a/xdocs/download_jxpath.xml
+++ b/xdocs/download_jxpath.xml
@@ -102,17 +102,17 @@ limitations under the License.
Binary
Source
- - 1.2.tar.gz
+
- 1.3.tar.gz
- - 1.2.zip
+
- 1.3.zip
diff --git a/xdocs/release-notes-1.3.xml b/xdocs/release-notes-1.3.xml
index e3b74731c..7b5216d34 100644
--- a/xdocs/release-notes-1.3.xml
+++ b/xdocs/release-notes-1.3.xml
@@ -127,6 +127,8 @@
- [JXPATH-108] - problems with NodeSet returned from custom function.
+- [JXPATH-124] - Make buildContextChain method of Path class protected
+
New Feature
diff --git a/xdocs/users-guide.xml b/xdocs/users-guide.xml
index e511319c7..920a68455 100644
--- a/xdocs/users-guide.xml
+++ b/xdocs/users-guide.xml
@@ -58,108 +58,108 @@
JXPathContext class.