001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.xwork.util;
006:
007: import java.util.Map;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: /**
013: * <!-- START SNIPPET: javadoc -->
014: *
015: * This {@link ObjectTypeDeterminer} looks at the <b>Class-conversion.properties</b> for entries that indicated what
016: * objects are contained within Maps and Collections. For Collections, such as Lists, the element is specified using the
017: * pattern <b>Element_xxx</b>, where xxx is the field name of the collection property in your action or object. For
018: * Maps, both the key and the value may be specified by using the pattern <b>Key_xxx</b> and <b>Element_xxx</b>,
019: * respectively.
020: *
021: * <p/> From WebWork 2.1.x, the <b>Collection_xxx</b> format is still supported and honored, although it is deprecated
022: * and will be removed eventually.
023: *
024: * <!-- END SNIPPET: javadoc -->
025: *
026: *
027: * @author Gabriel Zimmerman
028: * @see XWorkListPropertyAccessor
029: * @see XWorkCollectionPropertyAccessor
030: * @see XWorkMapPropertyAccessor
031: */
032: public class DefaultObjectTypeDeterminer implements
033: ObjectTypeDeterminer {
034: protected static final Log LOG = LogFactory
035: .getLog(DefaultObjectTypeDeterminer.class);
036:
037: public static final String KEY_PREFIX = "Key_";
038: public static final String ELEMENT_PREFIX = "Element_";
039: public static final String KEY_PROPERTY_PREFIX = "KeyProperty_";
040: public static final String CREATE_IF_NULL_PREFIX = "CreateIfNull_";
041: public static final String DEPRECATED_ELEMENT_PREFIX = "Collection_";
042:
043: /**
044: * Determines the key class by looking for the value of Key_${property} in the properties file for the given class.
045: *
046: * @param parentClass the Class which contains as a property the Map or Collection we are finding the key for.
047: * @param property the property of the Map or Collection for the given parent class
048: * @see ObjectTypeDeterminer#getKeyClass(Class, String)
049: */
050: public Class getKeyClass(Class parentClass, String property) {
051: return (Class) XWorkConverter.getInstance().getConverter(
052: parentClass, KEY_PREFIX + property);
053: }
054:
055: /**
056: * Determines the key class by looking for the value of Element_${property} in the properties file for the given
057: * class. Also looks for the deprecated Collection_${property}
058: *
059: * @param parentClass the Class which contains as a property the Map or Collection we are finding the key for.
060: * @param property the property of the Map or Collection for the given parent class
061: * @see ObjectTypeDeterminer#getElementClass(Class, String, Object)
062: */
063: public Class getElementClass(Class parentClass, String property,
064: Object key) {
065: Class clazz = (Class) XWorkConverter.getInstance()
066: .getConverter(parentClass, ELEMENT_PREFIX + property);
067: if (clazz == null) {
068: clazz = (Class) XWorkConverter.getInstance().getConverter(
069: parentClass, DEPRECATED_ELEMENT_PREFIX + property);
070:
071: if (clazz != null) {
072: LOG
073: .info("The Collection_xxx pattern for collection type conversion is deprecated. Please use Element_xxx!");
074: }
075: }
076: return clazz;
077: }
078:
079: /**
080: * Determines the String key property for a Collection by getting it from the conversion properties file using the
081: * KeyProperty_ prefix. KeyProperty_${property}=somePropertyOfBeansInTheSet
082: *
083: * @param parentClass the Class which contains as a property the Map or Collection we are finding the KeyProperty for.
084: * @param property the property of the Map or Collection for the given parent class
085: */
086: public String getKeyProperty(Class parentClass, String property) {
087: return (String) XWorkConverter.getInstance().getConverter(
088: parentClass, KEY_PROPERTY_PREFIX + property);
089: }
090:
091: /**
092: * Determines the boolean CreateIfNull property for a Collection or Map by getting it from the conversion properties
093: * file using the CreateIfNull_ prefix. CreateIfNull_${property}=true|false
094: *
095: * @param parentClass the Class which contains as a property the Map or Collection we are finding the CreateIfNull for.
096: * @param property the property of the Map or Collection for the given parent class
097: * @param target
098: * @param keyProperty
099: * @param isIndexAccessed
100: * @return <tt>true</tt>, if the Collection or Map should be created, <tt>false</tt> otherwise.
101: */
102: public boolean shouldCreateIfNew(Class parentClass,
103: String property, Object target, String keyProperty,
104: boolean isIndexAccessed) {
105:
106: String configValue = (String) XWorkConverter.getInstance()
107: .getConverter(parentClass,
108: CREATE_IF_NULL_PREFIX + property);
109: //check if a value is in the config
110: if (configValue != null) {
111: if (configValue.equals("true")) {
112: return true;
113: }
114: if (configValue.equals("false")) {
115: return false;
116: }
117: }
118:
119: //default values depend on target type
120: //and whether this is accessed by an index
121: //in the case of List
122: if ((target instanceof Map) || isIndexAccessed) {
123: return true;
124: } else {
125: return false;
126: }
127: }
128: }
|