⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propertyresolver.java

📁 Wicket一个开发Java Web应用程序框架。它使得开发web应用程序变得容易而轻松。 Wicket利用一个POJO data beans组件使得它可以与任何持久层技术相结合。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.wicket.util.lang;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.List;import java.util.Map;import org.apache.wicket.Application;import org.apache.wicket.Session;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.util.concurrent.ConcurrentHashMap;import org.apache.wicket.util.convert.ConversionException;import org.apache.wicket.util.string.Strings;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * This class parses expressions to lookup or set a value on the object that is given. <br/> The * supported expressions are: * <p> * "property": This can can then be a bean property with get and set method. Or if a map is given as * an object it will be lookup with the property as a key when there is not get method for that * property. <p/> * <p> * "property1.property2": Both properties are lookup as written above. If property1 evaluates to * null then if there is a setMethod (or if it is a map) and the Class of the property has a default * constructor then the object will be constructed and set on the object. <p/> * <p> * "property.index": If the property is a List or Array then the second property can be a index on * that list like: 'mylist.0' this expression will also map on a getProperty(index) or * setProperty(index,value) methods. If the object is a List then the list will grow automatically * if the index is greater then the size <p/> * <p> * Index or map properties can also be written as: "property[index]" or "property[key]" <p/> *  * @author jcompagner */public final class PropertyResolver{	private final static int RETURN_NULL = 0;	private final static int CREATE_NEW_VALUE = 1;	private final static int RESOLVE_CLASS = 2;	private final static Map applicationToClassesToGetAndSetters = new ConcurrentHashMap(2);	/** Log. */	private static final Logger log = LoggerFactory.getLogger(PropertyResolver.class);	/**	 * Looks up the value from the object with the given expression. If the expression, the object	 * itself or one property evaluates to null then a null will be returned.	 * 	 * @param expression	 *            The expression string with the property to be lookup.	 * @param object	 *            The object which is evaluated.	 * @return The value that is evaluated. Null something in the expression evaluated to null.	 */	public final static Object getValue(final String expression, final Object object)	{		if (expression == null || expression.equals("") || object == null)		{			return object;		}		ObjectAndGetSetter getter = getObjectAndGetSetter(expression, object, RETURN_NULL);		if (getter == null)		{			return null;		}		return getter.getValue();	}	/**	 * Set the value on the object with the given expression. If the expression can't be evaluated	 * then a WicketRuntimeException will be thrown. If a null object is encountered then it will	 * try to generate it by calling the default constructor and set it on the object.	 * 	 * The value will be tried to convert to the right type with the given converter.	 * 	 * @param expression	 *            The expression string with the property to be set.	 * @param object	 *            The object which is evaluated to set the value on.	 * @param value	 *            The value to set.	 * @param converter	 *            The converter to convert the value if needed to the right type.	 */	public final static void setValue(final String expression, final Object object, Object value,		PropertyResolverConverter converter)	{		if (expression == null || expression.equals(""))		{			throw new WicketRuntimeException("Empty expression setting value: " + value +				" on object: " + object);		}		if (object == null)		{			throw new WicketRuntimeException(				"Attempted to set property value on a null object. Property expression: " +					expression + " Value: " + value);		}		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, CREATE_NEW_VALUE);		if (setter == null)		{			throw new WicketRuntimeException("Null object returned for expression: " + expression +				" for setting value: " + value + " on: " + object);		}		setter.setValue(value, converter == null ? new PropertyResolverConverter(Application.get()			.getConverterLocator(), Session.get().getLocale()) : converter);	}	/**	 * @param expression	 * @param object	 * @return class of the target property object	 */	public final static Class getPropertyClass(String expression, Object object)	{		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, RESOLVE_CLASS);		if (setter == null)		{			throw new WicketRuntimeException("Null object returned for expression: " + expression +				" for getting the target classs of: " + object);		}		return setter.getTargetClass();	}	/**	 * @param expression	 * @param object	 * @return Field for the property expression or null if such field doesn't exist (only getters	 *         and setters)	 */	public final static Field getPropertyField(String expression, Object object)	{		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, RESOLVE_CLASS);		if (setter == null)		{			throw new WicketRuntimeException("Null object returned for expression: " + expression +				" for getting the target classs of: " + object);		}		return setter.getField();	}	/**	 * @param expression	 * @param object	 * @return Getter method for the property expression or null if such getter doesn't exist (only	 *         field)	 */	public final static Method getPropertyGetter(String expression, Object object)	{		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, RESOLVE_CLASS);		if (setter == null)		{			throw new WicketRuntimeException("Null object returned for expression: " + expression +				" for getting the target classs of: " + object);		}		return setter.getGetter();	}	/**	 * @param expression	 * @param object	 * @return Setter method for the property expression or null if such setter doesn't exist (only	 *         field)	 */	public final static Method getPropertySetter(String expression, Object object)	{		ObjectAndGetSetter setter = getObjectAndGetSetter(expression, object, RESOLVE_CLASS);		if (setter == null)		{			throw new WicketRuntimeException("Null object returned for expression: " + expression +				" for getting the target classs of: " + object);		}		return setter.getSetter();	}	private static ObjectAndGetSetter getObjectAndGetSetter(final String expression,		final Object object, int tryToCreateNull)	{		final String expressionBracketsSeperated = Strings.replaceAll(expression, "[", ".[")			.toString();		int index = getNextDotIndex(expressionBracketsSeperated, 0);		int lastIndex = 0;		Object value = object;		Class clz = value.getClass();		String exp = expressionBracketsSeperated;		while (index != -1)		{			exp = expressionBracketsSeperated.substring(lastIndex, index);			IGetAndSet getAndSetter = null;			try			{				getAndSetter = getGetAndSetter(exp, clz);			}			catch (WicketRuntimeException ex)			{				// expression by it self can't be found. try to find a				// setPropertyByIndex(int,value) method				index = getNextDotIndex(expressionBracketsSeperated, index + 1);				if (index != -1)				{					String indexExpression = expressionBracketsSeperated.substring(lastIndex, index);					getAndSetter = getGetAndSetter(indexExpression, clz);				}				else				{					exp = expressionBracketsSeperated.substring(lastIndex);					break;				}			}			Object newValue = null;			if (value != null)			{				newValue = getAndSetter.getValue(value);			}			if (newValue == null)			{				if (tryToCreateNull == CREATE_NEW_VALUE)				{					newValue = getAndSetter.newValue(value);					if (newValue == null)					{						return null;					}				}				else if (tryToCreateNull == RESOLVE_CLASS)				{					clz = getAndSetter.getTargetClass();				}				else				{					return null;				}			}			value = newValue;			if (value != null)			{				// value can be null if we are in the RESOLVE_CLASS				clz = value.getClass();			}			lastIndex = index + 1;			index = getNextDotIndex(expressionBracketsSeperated, lastIndex);			if (index == -1)			{				exp = expressionBracketsSeperated.substring(lastIndex);				break;			}		}		IGetAndSet getAndSetter = getGetAndSetter(exp, clz);		return new ObjectAndGetSetter(getAndSetter, value);	}	private static int getNextDotIndex(String expression, int start)	{		boolean insideBracket = false;		for (int i = start; i < expression.length(); i++)		{			char ch = expression.charAt(i);			if (ch == '.' && !insideBracket)			{				return i;			}			else if (ch == '[')			{				insideBracket = true;			}			else if (ch == ']')			{				insideBracket = false;			}		}		return -1;	}	private final static IGetAndSet getGetAndSetter(String exp, Class clz)	{		Map classesToGetAndSetters = getClassesToGetAndSetters();		Map getAndSetters = (Map)classesToGetAndSetters.get(clz);		if (getAndSetters == null)		{			getAndSetters = new ConcurrentHashMap(8);			classesToGetAndSetters.put(clz, getAndSetters);		}		IGetAndSet getAndSetter = (IGetAndSet)getAndSetters.get(exp);		if (getAndSetter == null)		{			Method method = null;			Field field = null;			if (exp.startsWith("["))			{				// if expression begins with [ skip method finding and use it as				// a key/index lookup on a map.				exp = exp.substring(1, exp.length() - 1);			}			else if (exp.endsWith("()"))			{				// if expression ends with (), don't test for setters just skip				// directly to method finding.				method = findMethod(clz, exp);			}			else			{				method = findGetter(clz, exp);			}			if (method == null)			{				if (List.class.isAssignableFrom(clz))				{					try					{						int index = Integer.parseInt(exp);						getAndSetter = new ListGetSet(index);					}					catch (NumberFormatException ex)					{						// can't parse the exp as an index, maybe the exp was a						// method.						method = findMethod(clz, exp);						if (method != null)						{							getAndSetter = new MethodGetAndSet(method, MethodGetAndSet.findSetter(								method, clz), null);						}						else						{							field = findField(clz, exp);							if (field != null)							{								getAndSetter = new FieldGetAndSetter(field);							}							else							{								throw new WicketRuntimeException(									"The expression '" +										exp +										"' is neither an index nor is it a method or field for the list " +										clz);							}						}					}				}				else if (Map.class.isAssignableFrom(clz))				{					getAndSetter = new MapGetSet(exp);				}				else if (clz.isArray())				{					try					{						int index = Integer.parseInt(exp);						getAndSetter = new ArrayGetSet(clz.getComponentType(), index);					}					catch (NumberFormatException ex)					{						if (exp.equals("length") || exp.equals("size"))						{							getAndSetter = new ArrayLengthGetSet();						}						else						{							throw new WicketRuntimeException("can't parse the exp " + exp +								" as an index for an array lookup");						}					}				}				else				{					field = findField(clz, exp);					if (field == null)					{						method = findMethod(clz, exp);						if (method == null)						{							int index = exp.indexOf('.');							if (index != -1)							{								String propertyName = exp.substring(0, index);								String propertyIndex = exp.substring(index + 1);								try								{									int parsedIndex = Integer.parseInt(propertyIndex);									// if so then it could be a									// getPropertyIndex(int)									// and setPropertyIndex(int, object)									String name = Character.toUpperCase(propertyName.charAt(0)) +										propertyName.substring(1);									method = clz.getMethod("get" + name, new Class[] { int.class });									getAndSetter = new ArrayPropertyGetSet(method, parsedIndex);								}								catch (Exception e)								{									throw new WicketRuntimeException(										"no get method defined for class: " + clz +											" expression: " + propertyName);								}							}							else							{								// We do not look for a public FIELD because								// that is								// not good								// programming with beans patterns								throw new WicketRuntimeException(									"No get method defined for class: " + clz + " expression: " +										exp);							}						}						else						{							getAndSetter = new MethodGetAndSet(method, MethodGetAndSet.findSetter(								method, clz), field);						}					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -