001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.util;
018:
019: import java.beans.PropertyEditor;
020: import java.beans.PropertyEditorManager;
021: import java.lang.reflect.Field;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024: import java.net.URI;
025: import java.net.URISyntaxException;
026: import java.util.Arrays;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.LinkedHashMap;
030: import java.util.Map;
031: import java.util.Set;
032: import java.util.Map.Entry;
033:
034: public class IntrospectionSupport {
035:
036: static public boolean getProperties(Object target,
037: Map<String, String> props, String optionPrefix) {
038:
039: boolean rc = false;
040: if (target == null)
041: throw new IllegalArgumentException("target was null.");
042: if (props == null)
043: throw new IllegalArgumentException("props was null.");
044:
045: if (optionPrefix == null)
046: optionPrefix = "";
047:
048: Class clazz = target.getClass();
049: Method[] methods = clazz.getMethods();
050: for (int i = 0; i < methods.length; i++) {
051: Method method = methods[i];
052: String name = method.getName();
053: Class type = method.getReturnType();
054: Class params[] = method.getParameterTypes();
055: if (name.startsWith("get") && params.length == 0
056: && type != null && isSettableType(type)) {
057:
058: try {
059:
060: Object value = method.invoke(target,
061: new Object[] {});
062: if (value == null)
063: continue;
064:
065: String strValue = convertToString(value, type);
066: if (strValue == null)
067: continue;
068:
069: name = name.substring(3, 4).toLowerCase()
070: + name.substring(4);
071: props.put(optionPrefix + name, strValue);
072: rc = true;
073:
074: } catch (Throwable ignore) {
075: }
076:
077: }
078: }
079:
080: return rc;
081: }
082:
083: static public boolean setProperties(Object target, Map props,
084: String optionPrefix) {
085: boolean rc = false;
086: if (target == null)
087: throw new IllegalArgumentException("target was null.");
088: if (props == null)
089: throw new IllegalArgumentException("props was null.");
090:
091: for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
092: String name = (String) iter.next();
093: if (name.startsWith(optionPrefix)) {
094: Object value = props.get(name);
095: name = name.substring(optionPrefix.length());
096: if (setProperty(target, name, value)) {
097: iter.remove();
098: rc = true;
099: }
100: }
101: }
102: return rc;
103: }
104:
105: public static Map extractProperties(Map props, String optionPrefix) {
106: if (props == null)
107: throw new IllegalArgumentException("props was null.");
108:
109: HashMap<String, Object> rc = new HashMap<String, Object>(props
110: .size());
111:
112: for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
113: String name = (String) iter.next();
114: if (name.startsWith(optionPrefix)) {
115: Object value = props.get(name);
116: name = name.substring(optionPrefix.length());
117: rc.put(name, value);
118: iter.remove();
119: }
120: }
121:
122: return rc;
123: }
124:
125: public static boolean setProperties(Object target, Map props) {
126: boolean rc = false;
127:
128: if (target == null)
129: throw new IllegalArgumentException("target was null.");
130: if (props == null)
131: throw new IllegalArgumentException("props was null.");
132:
133: for (Iterator iter = props.entrySet().iterator(); iter
134: .hasNext();) {
135: Map.Entry entry = (Entry) iter.next();
136: if (setProperty(target, (String) entry.getKey(), entry
137: .getValue())) {
138: iter.remove();
139: rc = true;
140: }
141: }
142:
143: return rc;
144: }
145:
146: private static boolean setProperty(Object target, String name,
147: Object value) {
148: try {
149: Class clazz = target.getClass();
150: Method setter = findSetterMethod(clazz, name);
151: if (setter == null)
152: return false;
153:
154: // If the type is null or it matches the needed type, just use the
155: // value directly
156: if (value == null
157: || value.getClass() == setter.getParameterTypes()[0]) {
158: setter.invoke(target, new Object[] { value });
159: } else {
160: // We need to convert it
161: setter.invoke(target, new Object[] { convert(value,
162: setter.getParameterTypes()[0]) });
163: }
164: return true;
165: } catch (Throwable ignore) {
166: return false;
167: }
168: }
169:
170: private static Object convert(Object value, Class type)
171: throws URISyntaxException {
172: PropertyEditor editor = PropertyEditorManager.findEditor(type);
173: if (editor != null) {
174: editor.setAsText(value.toString());
175: return editor.getValue();
176: }
177: if (type == URI.class) {
178: return new URI(value.toString());
179: }
180: return null;
181: }
182:
183: private static String convertToString(Object value, Class type)
184: throws URISyntaxException {
185: PropertyEditor editor = PropertyEditorManager.findEditor(type);
186: if (editor != null) {
187: editor.setValue(value);
188: return editor.getAsText();
189: }
190: if (type == URI.class) {
191: return ((URI) value).toString();
192: }
193: return null;
194: }
195:
196: private static Method findSetterMethod(Class clazz, String name) {
197: // Build the method name.
198: name = "set" + name.substring(0, 1).toUpperCase()
199: + name.substring(1);
200: Method[] methods = clazz.getMethods();
201: for (int i = 0; i < methods.length; i++) {
202: Method method = methods[i];
203: Class params[] = method.getParameterTypes();
204: if (method.getName().equals(name) && params.length == 1
205: && isSettableType(params[0])) {
206: return method;
207: }
208: }
209: return null;
210: }
211:
212: private static boolean isSettableType(Class clazz) {
213: if (PropertyEditorManager.findEditor(clazz) != null)
214: return true;
215: if (clazz == URI.class)
216: return true;
217: if (clazz == Boolean.class)
218: return true;
219: return false;
220: }
221:
222: static public String toString(Object target) {
223: return toString(target, Object.class);
224: }
225:
226: static public String toString(Object target, Class stopClass) {
227: LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
228: addFields(target, target.getClass(), stopClass, map);
229: StringBuffer buffer = new StringBuffer(simpleName(target
230: .getClass()));
231: buffer.append(" {");
232: Set entrySet = map.entrySet();
233: boolean first = true;
234: for (Iterator iter = entrySet.iterator(); iter.hasNext();) {
235: Map.Entry entry = (Map.Entry) iter.next();
236: if (first) {
237: first = false;
238: } else {
239: buffer.append(", ");
240: }
241: buffer.append(entry.getKey());
242: buffer.append(" = ");
243: appendToString(buffer, entry.getValue());
244: }
245: buffer.append("}");
246: return buffer.toString();
247: }
248:
249: protected static void appendToString(StringBuffer buffer,
250: Object value) {
251: buffer.append(value);
252: }
253:
254: static public String simpleName(Class clazz) {
255: String name = clazz.getName();
256: int p = name.lastIndexOf(".");
257: if (p >= 0) {
258: name = name.substring(p + 1);
259: }
260: return name;
261: }
262:
263: static private void addFields(Object target, Class startClass,
264: Class stopClass, LinkedHashMap<String, Object> map) {
265:
266: if (startClass != stopClass)
267: addFields(target, startClass.getSuperclass(), stopClass,
268: map);
269:
270: Field[] fields = startClass.getDeclaredFields();
271: for (int i = 0; i < fields.length; i++) {
272: Field field = fields[i];
273: if (Modifier.isStatic(field.getModifiers())
274: || Modifier.isTransient(field.getModifiers())
275: || Modifier.isPrivate(field.getModifiers())) {
276: continue;
277: }
278:
279: try {
280: field.setAccessible(true);
281: Object o = field.get(target);
282: if (o != null && o.getClass().isArray()) {
283: try {
284: o = Arrays.asList((Object[]) o);
285: } catch (Throwable e) {
286: }
287: }
288: map.put(field.getName(), o);
289: } catch (Throwable e) {
290: e.printStackTrace();
291: }
292: }
293:
294: }
295: }
|