001: /**
002: * Copyright (C) 2006, 2007 David Bulmore, Software Sensation Inc.
003: * All Rights Reserved.
004: *
005: * This file is part of jCommonTk.
006: *
007: * jCommonTk is free software; you can redistribute it and/or modify it under
008: * the terms of the GNU General Public License (Version 2) as published by
009: * the Free Software Foundation.
010: *
011: * jCommonTk is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with jCommonTk; if not, write to the Free Software Foundation,
018: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
019: */package jcommontk.object;
020:
021: import java.lang.reflect.Field;
022: import java.lang.reflect.InvocationTargetException;
023: import java.lang.reflect.Method;
024: import java.util.HashSet;
025: import java.util.Set;
026: import jcommontk.utils.StringUtils;
027:
028: /**
029: * Object filler will fill an objects public members with values from a map.
030: */
031:
032: @SuppressWarnings("unchecked")
033: // working to complete a Java 1.5 version
034: public class ObjectFiller {
035: /**
036: * Fill the object with values from the given getHandler.
037: *
038: * @param getHandler the GetHandler providing values for the object being filled
039: * @param object the object being filled
040: *
041: * @return the object passed in
042: */
043:
044: public static <T> T fillObject(GetHandler getHandler, T object)
045: throws IllegalAccessException, InvocationTargetException {
046: return fillObject(getHandler, object, null, true, false, null,
047: false);
048: }
049:
050: /**
051: * Fill the object with values from the given getHandler.
052: *
053: * @param getHandler the GetHandler providing values for the object being filled
054: * @param object the object being filled
055: * @param ignoreValueNames ignore the value names in the set
056: * @param setNulls set or ignore null values
057: *
058: * @return the object passed in
059: */
060:
061: public static <T> T fillObject(GetHandler getHandler, T object,
062: Set<String> ignoreValueNames, boolean setNulls)
063: throws IllegalAccessException, InvocationTargetException {
064: return fillObject(getHandler, object, null, true, false,
065: ignoreValueNames, setNulls);
066: }
067:
068: /**
069: * Fill the object with values from the given getHandler.
070: *
071: * @param getHandler the GetHandler providing values for the object being filled
072: * @param object the object being filled
073: * @param fillPublicSetMethods fill public set methods of the object
074: * @param fillPublicFields fill public fields of the object
075: * @param ignoreValueNames ignore the value names in the set
076: * @param setNulls set or ignore null values
077: *
078: * @return the object passed in
079: */
080:
081: public static <T> T fillObject(GetHandler getHandler, T object,
082: boolean fillPublicSetMethods, boolean fillPublicFields,
083: Set<String> ignoreValueNames, boolean setNulls)
084: throws IllegalAccessException, InvocationTargetException {
085: return fillObject(getHandler, object, null,
086: fillPublicSetMethods, fillPublicFields,
087: ignoreValueNames, setNulls);
088: }
089:
090: /**
091: * Fill the object with values from the given getHandler.
092: *
093: * @param getHandler the GetHandler providing values for the object being filled
094: * @param object the object being filled
095: * @param c the declaring class that methods and fields must exist in or null for no restriction
096: * @param fillPublicSetMethods fill public set methods of the object
097: * @param fillPublicFields fill public fields of the object
098: * @param ignoreValueNames ignore the value names in the set
099: * @param setNulls set or ignore null values
100: *
101: * @return the object passed in
102: */
103:
104: public static <T> T fillObject(GetHandler getHandler, T object,
105: Class<T> c, boolean fillPublicSetMethods,
106: boolean fillPublicFields, Set<String> ignoreValueNames,
107: boolean setNulls) throws IllegalAccessException,
108: InvocationTargetException {
109: Set memberSet = new HashSet();
110:
111: if (fillPublicSetMethods) {
112: Method[] methods = c != null ? c.getMethods() : object
113: .getClass().getMethods();
114:
115: for (int i = 0; i < methods.length; i++) {
116: Method method = methods[i];
117: String methodName = method.getName();
118:
119: if (c == null
120: || methods[i].getDeclaringClass().equals(c))
121: if (methodName.startsWith("set")
122: && !methodName.equalsIgnoreCase("set")) {
123: String valueName = methodName.substring(3, 4)
124: .toLowerCase()
125: + methodName.substring(4);
126:
127: if (!memberSet.contains(valueName)) {
128: memberSet.add(valueName);
129:
130: if (method.getParameterTypes().length > 0
131: && (ignoreValueNames == null || !ignoreValueNames
132: .contains(valueName))) {
133: try {
134: Object value = getHandler
135: .get(
136: valueName,
137: method
138: .getParameterTypes()[0]);
139:
140: if (value == null)
141: value = getHandler
142: .get(
143: StringUtils
144: .camelCaseToLowerCaseUnderline(valueName),
145: method
146: .getParameterTypes()[0]);
147:
148: if (value == null)
149: value = getHandler
150: .get(
151: valueName
152: .toLowerCase(),
153: method
154: .getParameterTypes()[0]);
155:
156: if (setNulls || value != null)
157: if (method.getParameterTypes() != null
158: && method
159: .getParameterTypes().length == 1)
160: method
161: .invoke(
162: object,
163: new Object[] { ObjectConverter
164: .convertObject(
165: method
166: .getParameterTypes()[0],
167: value) });
168: } catch (ItemNotFoundException e) {
169: }
170: }
171: }
172: }
173: }
174: }
175:
176: if (fillPublicFields) {
177: Field[] fields = c != null ? c.getFields() : object
178: .getClass().getFields();
179:
180: for (int i = 0; i < fields.length; i++) {
181: String fieldName = fields[i].getName();
182:
183: if (c == null
184: || fields[i].getDeclaringClass().equals(c))
185: if (!memberSet.contains(fieldName)) {
186: memberSet.add(fieldName);
187:
188: if (ignoreValueNames == null
189: || !ignoreValueNames
190: .contains(fieldName)) {
191: try {
192: Object value = getHandler.get(
193: fieldName, fields[i].getType());
194:
195: if (value == null)
196: value = getHandler.get(fieldName
197: .toLowerCase(), fields[i]
198: .getType());
199:
200: if (value == null)
201: value = getHandler
202: .get(
203: StringUtils
204: .camelCaseToLowerCaseUnderline(fieldName),
205: fields[i].getType());
206:
207: if (setNulls || value != null)
208: fields[i]
209: .set(
210: object,
211: new Object[] { ObjectConverter
212: .convertObject(
213: fields[i]
214: .getType(),
215: value) });
216: } catch (ItemNotFoundException e) {
217: }
218: }
219: }
220: }
221: }
222:
223: return object;
224: }
225:
226: /**
227: * Implement this interface for ObjectFiller to gain access to your data.
228: * If your object has a field that doesn't match up to data,
229: * throw ItemNotFoundException instead of returning null so ObjectFiller
230: * doesn't set the field to null.
231: */
232: public interface GetHandler {
233: public <T> T get(String key, Class<T> objectType)
234: throws ItemNotFoundException;
235: }
236:
237: public static class ItemNotFoundException extends Exception {
238: private static final long serialVersionUID = 100L;
239: }
240: }
|