xworkconverter.java
来自「在Struts2中的jar包xwork的源代码.版本为2.0.7」· Java 代码 · 共 840 行 · 第 1/3 页
JAVA
840 行
/* * Copyright (c) 2002-2006 by OpenSymphony * All rights reserved. */package com.opensymphony.xwork2.util;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Member;import java.lang.reflect.Method;import java.lang.annotation.Annotation;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Properties;import ognl.DefaultTypeConverter;import ognl.OgnlRuntime;import ognl.TypeConverter;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import com.opensymphony.xwork2.inject.Inject;import com.opensymphony.xwork2.util.FileManager;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ObjectFactory;import com.opensymphony.xwork2.XWorkMessages;import com.opensymphony.xwork2.conversion.annotations.Conversion;import com.opensymphony.xwork2.conversion.annotations.TypeConversion;import com.opensymphony.xwork2.conversion.annotations.ConversionType;import com.opensymphony.xwork2.conversion.annotations.ConversionRule;/** * XWorkConverter is a singleton used by many of the WebWork's Ognl extention points, * such as InstantiatingNullHandler, XWorkListPropertyAccessor etc to do object * conversion. * * <!-- START SNIPPET: javadoc --> * * Type conversion is great for situations where you need to turn a String in to a more complex object. Because the web * is type-agnostic (everything is a string in HTTP), WebWork's type conversion features are very useful. For instance, * if you were prompting a user to enter in coordinates in the form of a string (such as "3, 22"), you could have * WebWork do the conversion both from String to Point and from Point to String. * * <p/> Using this "point" example, if your action (or another compound object in which you are setting properties on) * has a corresponding ClassName-conversion.properties file, WebWork will use the configured type converters for * conversion to and from strings. So turning "3, 22" in to new Point(3, 22) is done by merely adding the following * entry to <b>ClassName-conversion.properties</b> (Note that the PointConverter should impl the ognl.TypeConverter * interface): * * <p/><b>point = com.acme.PointConverter</b> * * <p/> Your type converter should be sure to check what class type it is being requested to convert. Because it is used * for both to and from strings, you will need to split the conversion method in to two parts: one that turns Strings in * to Points, and one that turns Points in to Strings. * * <p/> After this is done, you can now reference your point (using <ww:property value="post"/> in JSP or ${point} * in FreeMarker) and it will be printed as "3, 22" again. As such, if you submit this back to an action, it will be * converted back to a Point once again. * * <p/> In some situations you may wish to apply a type converter globally. This can be done by editing the file * <b>xwork-conversion.properties</b> in the root of your class path (typically WEB-INF/classes) and providing a * property in the form of the class name of the object you wish to convert on the left hand side and the class name of * the type converter on the right hand side. For example, providing a type converter for all Point objects would mean * adding the following entry: * * <p/><b>com.acme.Point = com.acme.PointConverter</b> * * <!-- END SNIPPET: javadoc --> * * <p/> * * <!-- START SNIPPET: i18n-note --> * * Type conversion should not be used as a substitute for i18n. It is not recommended to use this feature to print out * properly formatted dates. Rather, you should use the i18n features of WebWork (and consult the JavaDocs for JDK's * MessageFormat object) to see how a properly formatted date should be displayed. * * <!-- END SNIPPET: i18n-note --> * * <p/> * * <!-- START SNIPPET: error-reporting --> * * Any error that occurs during type conversion may or may not wish to be reported. For example, reporting that the * input "abc" could not be converted to a number might be important. On the other hand, reporting that an empty string, * "", cannot be converted to a number might not be important - especially in a web environment where it is hard to * distinguish between a user not entering a value vs. entering a blank value. * * <p/> By default, all conversion errors are reported using the generic i18n key <b>xwork.default.invalid.fieldvalue</b>, * which you can override (the default text is <i>Invalid field value for field "xxx"</i>, where xxx is the field name) * in your global i18n resource bundle. * * <p/>However, sometimes you may wish to override this message on a per-field basis. You can do this by adding an i18n * key associated with just your action (Action.properties) using the pattern <b>invalid.fieldvalue.xxx</b>, where xxx * is the field name. * * <p/>It is important to know that none of these errors are actually reported directly. Rather, they are added to a map * called <i>conversionErrors</i> in the ActionContext. There are several ways this map can then be accessed and the * errors can be reported accordingly. * * <!-- END SNIPPET: error-reporting --> * * @author <a href="mailto:plightbo@gmail.com">Pat Lightbody</a> * @author Rainer Hermanns * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a> * @author tm_jee * * @version $Date: 2007-07-16 17:32:09 +0200 (Mo, 16 Jul 2007) $ $Id: XWorkConverter.java 1548 2007-07-16 15:32:09Z rainerh $ * * @see XWorkBasicConverter */public class XWorkConverter extends DefaultTypeConverter { private static XWorkConverter instance; protected static final Log LOG = LogFactory.getLog(XWorkConverter.class); public static final String REPORT_CONVERSION_ERRORS = "report.conversion.errors"; public static final String CONVERSION_PROPERTY_FULLNAME = "conversion.property.fullName"; public static final String CONVERSION_ERROR_PROPERTY_PREFIX = "invalid.fieldvalue."; public static final String CONVERSION_COLLECTION_PREFIX = "Collection_"; public static final String LAST_BEAN_CLASS_ACCESSED = "last.bean.accessed"; public static final String LAST_BEAN_PROPERTY_ACCESSED = "last.property.accessed"; /** * Target class conversion Mappings. * <pre> * Map<Class, Map<String, Object>> * - Class -> convert to class * - Map<String, Object> * - String -> property name * eg. Element_property, property etc. * - Object -> String to represent properties * eg. value part of * KeyProperty_property=id * -> TypeConverter to represent an Ognl TypeConverter * eg. value part of * property=foo.bar.MyConverter * -> Class to represent a class * eg. value part of * Element_property=foo.bar.MyObject * </pre> */ protected HashMap<Class,Map<String,Object>> mappings = new HashMap<Class,Map<String,Object>>(); // action /** * Unavailable target class conversion mappings, serves as a simple cache. */ protected HashSet<Class> noMapping = new HashSet<Class>(); // action /** * Record class and its type converter mapping. * <pre> * - String - classname as String * - TypeConverter - instance of TypeConverter * </pre> */ protected HashMap<String, TypeConverter> defaultMappings = new HashMap<String, TypeConverter>(); // non-action (eg. returned value) /** * Record classes that doesn't have conversion mapping defined. * <pre> * - String -> classname as String * </pre> */ protected HashSet<String> unknownMappings = new HashSet<String>(); // non-action (eg. returned value) protected TypeConverter defaultTypeConverter = new XWorkBasicConverter(); protected ObjectTypeDeterminer objectTypeDeterminer = null; protected XWorkConverter() { try { // note: this file is deprecated loadConversionProperties("xwork-default-conversion.properties"); } catch (Exception e) { } try { loadConversionProperties("xwork-conversion.properties"); } catch (Exception e) { } } public static String getConversionErrorMessage(String propertyName, ValueStack stack) { String defaultMessage = LocalizedTextUtil.findDefaultText(XWorkMessages.DEFAULT_INVALID_FIELDVALUE, ActionContext.getContext().getLocale(), new Object[]{ propertyName }); String getTextExpression = "getText('" + CONVERSION_ERROR_PROPERTY_PREFIX + propertyName + "','" + defaultMessage + "')"; String message = (String) stack.findValue(getTextExpression); if (message == null) { message = defaultMessage; } return message; } public static XWorkConverter getInstance() { if (instance == null) { instance = new XWorkConverter(); } return instance; } @Inject public static void setInstance(XWorkConverter instance) { XWorkConverter.instance = instance; } public static String buildConverterFilename(Class clazz) { String className = clazz.getName(); String resource = className.replace('.', '/') + "-conversion.properties"; return resource; } public static void resetInstance() { instance = null; } public void setDefaultConverter(TypeConverter defaultTypeConverter) { this.defaultTypeConverter = defaultTypeConverter; } public Object convertValue(Map map, Object o, Class aClass) { return convertValue(map, null, null, null, o, aClass); } /** * Convert value from one form to another. * Minimum requirement of arguments: * <ul> * <li>supplying context, toClass and value</li> * <li>supplying context, target and value.</li> * </ul> * * @see ognl.TypeConverter#convertValue(java.util.Map, java.lang.Object, java.lang.reflect.Member, java.lang.String, java.lang.Object, java.lang.Class) */ public Object convertValue(Map context, Object target, Member member, String property, Object value, Class toClass) { // // Process the conversion using the default mappings, if one exists // TypeConverter tc = null; if ((value != null) && (toClass == value.getClass())) { return value; } // allow this method to be called without any context // i.e. it can be called with as little as "Object value" and "Class toClass" if (target != null) { Class clazz = target.getClass(); Object[] classProp = null; // this is to handle weird issues with setValue with a different type if ((target instanceof CompoundRoot) && (context != null)) { classProp = getClassProperty(context); } if (classProp != null) { clazz = (Class) classProp[0]; property = (String) classProp[1]; } tc = (TypeConverter) getConverter(clazz, property); if (LOG.isDebugEnabled()) LOG.debug("field-level type converter for property ["+property+"] = "+(tc==null?"none found":tc)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?