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 }