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 */
018 package org.apache.camel.util;
019
020 import java.beans.PropertyEditor;
021 import java.beans.PropertyEditorManager;
022 import java.lang.reflect.Field;
023 import java.lang.reflect.Method;
024 import java.lang.reflect.Modifier;
025 import java.net.URI;
026 import java.net.URISyntaxException;
027 import java.util.Arrays;
028 import java.util.HashMap;
029 import java.util.Iterator;
030 import java.util.LinkedHashMap;
031 import java.util.Map;
032 import java.util.Map.Entry;
033 import java.util.Set;
034
035 public class IntrospectionSupport {
036
037
038 static public boolean getProperties(Object target, Map props, String optionPrefix) {
039
040 boolean rc = false;
041 if( target == null )
042 throw new IllegalArgumentException("target was null.");
043 if( props == null )
044 throw new IllegalArgumentException("props was null.");
045
046 if( optionPrefix == null )
047 optionPrefix="";
048
049 Class clazz = target.getClass();
050 Method[] methods = clazz.getMethods();
051 for (int i = 0; i < methods.length; i++) {
052 Method method = methods[i];
053 String name = method.getName();
054 Class type = method.getReturnType();
055 Class params[] = method.getParameterTypes();
056 if( name.startsWith("get") && params.length==0 &&
057 type!=null && isSettableType(type)) {
058
059 try {
060
061 Object value = method.invoke(target, 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()+name.substring(4);
070 props.put(optionPrefix+name, strValue);
071 rc = true;
072
073 } catch ( Throwable ignore) {
074 }
075
076 }
077 }
078
079 return rc;
080 }
081
082
083
084 static public boolean setProperties(Object target, Map props, 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 rc = new HashMap(props.size());
110
111 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
112 String name = (String) iter.next();
113 if( name.startsWith(optionPrefix) ) {
114 Object value = props.get(name);
115 name = name.substring(optionPrefix.length());
116 rc.put(name, value);
117 iter.remove();
118 }
119 }
120
121 return rc;
122 }
123
124 public static boolean setProperties(Object target, Map props) {
125 boolean rc = false;
126
127 if( target == null )
128 throw new IllegalArgumentException("target was null.");
129 if( props == null )
130 throw new IllegalArgumentException("props was null.");
131
132 for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) {
133 Map.Entry entry = (Entry) iter.next();
134 if( setProperty(target, (String) entry.getKey(), entry.getValue()) ) {
135 iter.remove();
136 rc=true;
137 }
138 }
139
140 return rc;
141 }
142
143 public static boolean setProperty(Object target, String name, Object value) {
144 try {
145 Class clazz = target.getClass();
146 Method setter = findSetterMethod(clazz, name);
147 if( setter == null )
148 return false;
149
150 // If the type is null or it matches the needed type, just use the value directly
151 if( value == null || value.getClass()==setter.getParameterTypes()[0] ) {
152 setter.invoke(target, new Object[]{value});
153 } else {
154 // We need to convert it
155 setter.invoke(target, new Object[]{ convert(value, setter.getParameterTypes()[0]) });
156 }
157 return true;
158 } catch (Throwable ignore) {
159 return false;
160 }
161 }
162
163 private static Object convert(Object value, Class type) throws URISyntaxException {
164 PropertyEditor editor = PropertyEditorManager.findEditor(type);
165 if( editor != null ) {
166 editor.setAsText(value.toString());
167 return editor.getValue();
168 }
169 if( type == URI.class ) {
170 return new URI(value.toString());
171 }
172 return null;
173 }
174
175 private static String convertToString(Object value, Class type) throws URISyntaxException {
176 PropertyEditor editor = PropertyEditorManager.findEditor(type);
177 if( editor != null ) {
178 editor.setValue(value);
179 return editor.getAsText();
180 }
181 if( type == URI.class ) {
182 return ((URI)value).toString();
183 }
184 return null;
185 }
186
187 private static Method findSetterMethod(Class clazz, String name) {
188 // Build the method name.
189 name = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
190 Method[] methods = clazz.getMethods();
191 for (int i = 0; i < methods.length; i++) {
192 Method method = methods[i];
193 Class params[] = method.getParameterTypes();
194 if( method.getName().equals(name)
195 && params.length==1
196 && isSettableType(params[0])) {
197 return method;
198 }
199 }
200 return null;
201 }
202
203 private static boolean isSettableType(Class clazz) {
204 if( PropertyEditorManager.findEditor(clazz)!=null )
205 return true;
206 if( clazz == URI.class )
207 return true;
208 if( clazz == Boolean.class )
209 return true;
210 return false;
211 }
212
213 static public String toString(Object target) {
214 return toString(target, Object.class);
215 }
216
217 static public String toString(Object target, Class stopClass) {
218 LinkedHashMap map = new LinkedHashMap();
219 addFields(target, target.getClass(), stopClass, map);
220 StringBuffer buffer = new StringBuffer(simpleName(target.getClass()));
221 buffer.append(" {");
222 Set entrySet = map.entrySet();
223 boolean first = true;
224 for (Iterator iter = entrySet.iterator(); iter.hasNext();) {
225 Map.Entry entry = (Map.Entry) iter.next();
226 if (first) {
227 first = false;
228 }
229 else {
230 buffer.append(", ");
231 }
232 buffer.append(entry.getKey());
233 buffer.append(" = ");
234 appendToString(buffer, entry.getValue());
235 }
236 buffer.append("}");
237 return buffer.toString();
238 }
239
240 protected static void appendToString(StringBuffer buffer, Object value) {
241 // if (value instanceof ActiveMQDestination) {
242 // ActiveMQDestination destination = (ActiveMQDestination) value;
243 // buffer.append(destination.getQualifiedName());
244 // }
245 // else {
246 buffer.append(value);
247 // }
248 }
249
250 static public String simpleName(Class clazz) {
251 String name = clazz.getName();
252 int p = name.lastIndexOf(".");
253 if( p >= 0 ) {
254 name = name.substring(p+1);
255 }
256 return name;
257 }
258
259
260 static private void addFields(Object target, Class startClass, Class stopClass, LinkedHashMap map) {
261
262 if( startClass!=stopClass )
263 addFields( target, startClass.getSuperclass(), stopClass, map );
264
265 Field[] fields = startClass.getDeclaredFields();
266 for (int i = 0; i < fields.length; i++) {
267 Field field = fields[i];
268 if( Modifier.isStatic(field.getModifiers()) ||
269 Modifier.isTransient(field.getModifiers()) ||
270 Modifier.isPrivate(field.getModifiers()) ) {
271 continue;
272 }
273
274 try {
275 field.setAccessible(true);
276 Object o = field.get(target);
277 if( o!=null && o.getClass().isArray() ) {
278 try {
279 o = Arrays.asList((Object[]) o);
280 } catch (Throwable e) {
281 }
282 }
283 map.put(field.getName(), o);
284 } catch (Throwable e) {
285 e.printStackTrace();
286 }
287 }
288
289 }
290
291
292 }