valueutils.java
来自「JXPath」· Java 代码 · 共 619 行 · 第 1/2 页
JAVA
619 行
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.jxpath.util;
import java.beans.IndexedPropertyDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.jxpath.Container;
import org.apache.commons.jxpath.DynamicPropertyHandler;
import org.apache.commons.jxpath.JXPathException;
/**
* Collection and property access utilities.
*
* @author Dmitri Plotnikov
* @version $Revision: 1.19 $ $Date: 2004/04/04 22:06:36 $
*/
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
*/
public static boolean isCollection(Object value) {
if (value == null) {
return false;
}
value = getValue(value);
if (value.getClass().isArray()) {
return true;
}
else 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.
*/
public static int getCollectionHint(Class clazz) {
if (clazz.isArray()) {
return 1;
}
if (Collection.class.isAssignableFrom(clazz)) {
return 1;
}
if (clazz.isPrimitive()) {
return -1;
}
if (clazz.isInterface()) {
return 0;
}
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.
*/
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());
}
for (int i = 0; i < UNKNOWN_LENGTH_MAX_COUNT; i++) {
try {
readMethod.invoke(object, new Object[] { new Integer(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.
*/
public static int getLength(Object collection) {
if (collection == null) {
return 0;
}
collection = getValue(collection);
if (collection.getClass().isArray()) {
return Array.getLength(collection);
}
else if (collection instanceof Collection) {
return ((Collection) collection).size();
}
else {
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.
*/
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();
}
else if (collection instanceof Collection) {
return ((Collection) collection).iterator();
}
else {
return Collections.singletonList(collection).iterator();
}
}
/**
* Grows the collection if necessary to the specified size. Returns
* the new, expanded collection.
*/
public static Object expandCollection(Object collection, int size) {
if (collection == null) {
return null;
}
else if (collection.getClass().isArray()) {
Object bigger =
Array.newInstance(
collection.getClass().getComponentType(),
size);
System.arraycopy(
collection,
0,
bigger,
0,
Array.getLength(collection));
return bigger;
}
else if (collection instanceof Collection) {
while (((Collection) collection).size() < size) {
((Collection) collection).add(null);
}
return collection;
}
else {
throw new JXPathException(
"Cannot turn "
+ collection.getClass().getName()
+ " into a collection of size "
+ size);
}
}
/**
* Returns the index'th element from the supplied collection.
*/
public static Object remove(Object collection, int index) {
collection = getValue(collection);
if (collection == null) {
return null;
}
else 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;
}
else if (collection instanceof List) {
int size = ((List) collection).size();
if (index < size) {
((List) collection).remove(index);
}
return collection;
}
else 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;
}
else {
throw new JXPathException(
"Cannot remove "
+ collection.getClass().getName()
+ "["
+ index
+ "]");
}
}
/**
* Returns the index'th element of the supplied collection.
*/
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.
*/
public static void setValue(Object collection, int index, Object value) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?