KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > propertyeditor > PropertyEditors


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.util.propertyeditor;
23
24 import java.beans.BeanInfo JavaDoc;
25 import java.beans.IntrospectionException JavaDoc;
26 import java.beans.Introspector JavaDoc;
27 import java.beans.PropertyDescriptor JavaDoc;
28 import java.beans.PropertyEditor JavaDoc;
29 import java.beans.PropertyEditorManager JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.security.AccessController JavaDoc;
32 import java.security.PrivilegedAction JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Properties JavaDoc;
36
37 import org.jboss.logging.Logger;
38 import org.jboss.util.Classes;
39
40 /**
41  * A collection of PropertyEditor utilities. Provides the same interface
42  * as PropertyEditorManager plus more...
43  *
44  * <p>Installs the default PropertyEditors.
45  *
46  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
47  * @author <a HREF="mailto:scott.stark@jboss.org">Scott Stark</a>
48  * @version <tt>$Revision: 1958 $</tt>
49  */

50 public class PropertyEditors
51 {
52    /** The Logger object */
53    private static Logger log = Logger.getLogger(PropertyEditors.class);
54
55    /** The null string */
56    private static final String JavaDoc NULL = "null";
57    
58    /** Whether we handle nulls */
59    private static boolean disableIsNull = false;
60    
61    /** Whether or not initialization of the editor search path has been done */
62    private static boolean initialized = false;
63    
64    static
65    {
66       init();
67    }
68
69    /**
70     * Augment the PropertyEditorManager search path to incorporate the JBoss
71     * specific editors by appending the org.jboss.util.propertyeditor package
72     * to the PropertyEditorManager editor search path.
73     */

74    public synchronized static void init()
75    {
76       if( initialized == false )
77       {
78          AccessController.doPrivileged(Initialize.instance);
79          initialized = true;
80       }
81    }
82
83    /**
84     * Whether a string is interpreted as the null value,
85     * including the empty string.
86     *
87     * @param value the value
88     * @return true when the string has the value null
89     */

90    public static final boolean isNull(final String JavaDoc value)
91    {
92       return isNull(value, true, true);
93    }
94
95    /**
96     * Whether a string is interpreted as the null value
97     *
98     * @param value the value
99     * @param trim whether to trim the string
100     * @param empty whether to include the empty string as null
101     * @return true when the string has the value null
102     */

103    public static final boolean isNull(final String JavaDoc value, final boolean trim, final boolean empty)
104    {
105       // For backwards compatibility
106
if (disableIsNull)
107          return false;
108       // No value?
109
if (value == null)
110          return true;
111       // Trim the text when requested
112
String JavaDoc trimmed = trim ? value.trim() : value;
113       // Is the empty string null?
114
if (empty && trimmed.length() == 0)
115          return true;
116       // Just check it.
117
return NULL.equalsIgnoreCase(trimmed);
118    }
119
120    /**
121     * Will the standard editors return null from their
122     * {@link PropertyEditor#setAsText(String)} method for non-primitive targets?
123     *
124     * @return True if nulls can be returned; false otherwise.
125     */

126    public static boolean isNullHandlingEnabled()
127    {
128       return !disableIsNull;
129    }
130    
131    /**
132     * Locate a value editor for a given target type.
133     *
134     * @param type The class of the object to be edited.
135     * @return An editor for the given type or null if none was found.
136     */

137    public static PropertyEditor JavaDoc findEditor(final Class JavaDoc type)
138    {
139       return PropertyEditorManager.findEditor(type);
140    }
141
142    /**
143     * Locate a value editor for a given target type.
144     *
145     * @param typeName The class name of the object to be edited.
146     * @return An editor for the given type or null if none was found.
147     */

148    public static PropertyEditor JavaDoc findEditor(final String JavaDoc typeName)
149       throws ClassNotFoundException JavaDoc
150    {
151       // see if it is a primitive type first
152
Class JavaDoc type = Classes.getPrimitiveTypeForName(typeName);
153       if (type == null)
154       {
155          // nope try look up
156
ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
157          type = loader.loadClass(typeName);
158       }
159
160       return PropertyEditorManager.findEditor(type);
161    }
162
163    /**
164     * Get a value editor for a given target type.
165     *
166     * @param type The class of the object to be edited.
167     * @return An editor for the given type.
168     *
169     * @throws RuntimeException No editor was found.
170     */

171    public static PropertyEditor JavaDoc getEditor(final Class JavaDoc type)
172    {
173       PropertyEditor JavaDoc editor = findEditor(type);
174       if (editor == null)
175       {
176          throw new RuntimeException JavaDoc("No property editor for type: " + type);
177       }
178
179       return editor;
180    }
181
182    /**
183     * Get a value editor for a given target type.
184     *
185     * @param typeName The class name of the object to be edited.
186     * @return An editor for the given type.
187     *
188     * @throws RuntimeException No editor was found.
189     */

190    public static PropertyEditor JavaDoc getEditor(final String JavaDoc typeName)
191       throws ClassNotFoundException JavaDoc
192    {
193       PropertyEditor JavaDoc editor = findEditor(typeName);
194       if (editor == null)
195       {
196          throw new RuntimeException JavaDoc("No property editor for type: " + typeName);
197       }
198
199       return editor;
200    }
201
202    /**
203     * Register an editor class to be used to editor values of a given target class.
204     *
205     * @param type The class of the objetcs to be edited.
206     * @param editorType The class of the editor.
207     */

208    public static void registerEditor(final Class JavaDoc type, final Class JavaDoc editorType)
209    {
210       PropertyEditorManager.registerEditor(type, editorType);
211    }
212
213    /**
214     * Register an editor class to be used to editor values of a given target class.
215     *
216     * @param typeName The classname of the objetcs to be edited.
217     * @param editorTypeName The class of the editor.
218     */

219    public static void registerEditor(final String JavaDoc typeName,
220                                      final String JavaDoc editorTypeName)
221       throws ClassNotFoundException JavaDoc
222    {
223       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
224       Class JavaDoc type = loader.loadClass(typeName);
225       Class JavaDoc editorType = loader.loadClass(editorTypeName);
226
227       PropertyEditorManager.registerEditor(type, editorType);
228    }
229
230    /** Convert a string value into the true value for typeName using the
231     * PropertyEditor associated with typeName.
232     *
233     * @param text the string represention of the value. This is passed to
234     * the PropertyEditor.setAsText method.
235     * @param typeName the fully qualified class name of the true value type
236     * @return the PropertyEditor.getValue() result
237     * @exception ClassNotFoundException thrown if the typeName class cannot
238     * be found
239     * @exception IntrospectionException thrown if a PropertyEditor for typeName
240     * cannot be found
241     */

242    public static Object JavaDoc convertValue(String JavaDoc text, String JavaDoc typeName)
243          throws ClassNotFoundException JavaDoc, IntrospectionException JavaDoc
244    {
245       // see if it is a primitive type first
246
Class JavaDoc typeClass = Classes.getPrimitiveTypeForName(typeName);
247       if (typeClass == null)
248       {
249          ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
250          typeClass = loader.loadClass(typeName);
251       }
252
253       PropertyEditor JavaDoc editor = PropertyEditorManager.findEditor(typeClass);
254       if (editor == null)
255       {
256          throw new IntrospectionException JavaDoc
257                ("No property editor for type=" + typeClass);
258       }
259
260       editor.setAsText(text);
261       return editor.getValue();
262    }
263
264    /**
265     * This method takes the properties found in the given beanProps
266     * to the bean using the property editor registered for the property.
267     * Any property in beanProps that does not have an associated java bean
268     * property will result in an IntrospectionException. The string property
269     * values are converted to the true java bean property type using the
270     * java bean PropertyEditor framework. If a property in beanProps does not
271     * have a PropertyEditor registered it will be ignored.
272     *
273     * @param bean - the java bean instance to apply the properties to
274     * @param beanProps - map of java bean property name to property value.
275     * @throws IntrospectionException thrown on introspection of bean and if
276     * a property in beanProps does not map to a property of bean.
277     */

278    public static void mapJavaBeanProperties(Object JavaDoc bean, Properties JavaDoc beanProps)
279       throws IntrospectionException JavaDoc
280    {
281       mapJavaBeanProperties(bean, beanProps, true);
282    }
283
284    /**
285     * This method takes the properties found in the given beanProps
286     * to the bean using the property editor registered for the property.
287     * Any property in beanProps that does not have an associated java bean
288     * property will result in an IntrospectionException. The string property
289     * values are converted to the true java bean property type using the
290     * java bean PropertyEditor framework. If a property in beanProps does not
291     * have a PropertyEditor registered it will be ignored.
292     *
293     * @param bean - the java bean instance to apply the properties to
294     * @param beanProps - map of java bean property name to property value.
295     * @param isStrict - indicates if should throw exception if bean property can not
296     * be matched. True for yes, false for no.
297     * @throws IntrospectionException thrown on introspection of bean and if
298     * a property in beanProps does not map to a property of bean.
299     */

300    public static void mapJavaBeanProperties(Object JavaDoc bean, Properties JavaDoc beanProps, boolean isStrict)
301       throws IntrospectionException JavaDoc
302    {
303
304       HashMap JavaDoc propertyMap = new HashMap JavaDoc();
305       BeanInfo JavaDoc beanInfo = Introspector.getBeanInfo(bean.getClass());
306       PropertyDescriptor JavaDoc[] props = beanInfo.getPropertyDescriptors();
307       for (int p = 0; p < props.length; p++)
308       {
309          String JavaDoc fieldName = props[p].getName();
310          propertyMap.put(fieldName, props[p]);
311       }
312
313       boolean trace = log.isTraceEnabled();
314       Iterator JavaDoc keys = beanProps.keySet().iterator();
315       if( trace )
316          log.trace("Mapping properties for bean: "+bean);
317       while( keys.hasNext() )
318       {
319          String JavaDoc name = (String JavaDoc) keys.next();
320          String JavaDoc text = beanProps.getProperty(name);
321          PropertyDescriptor JavaDoc pd = (PropertyDescriptor JavaDoc) propertyMap.get(name);
322          if (pd == null)
323          {
324             /* Try the property name with the first char uppercased to handle
325             a property name like dLQMaxResent whose expected introspected
326             property name would be DLQMaxResent since the JavaBean
327             Introspector would view setDLQMaxResent as the setter for a
328             DLQMaxResent property whose Introspector.decapitalize() method
329             would also return "DLQMaxResent".
330             */

331             if (name.length() > 1)
332             {
333                char first = name.charAt(0);
334                String JavaDoc exName = Character.toUpperCase(first) + name.substring(1);
335                pd = (PropertyDescriptor JavaDoc) propertyMap.get(exName);
336                
337                // Be lenient and check the other way around, e.g. ServerName -> serverName
338
if (pd == null)
339                {
340                   exName = Character.toLowerCase(first) + name.substring(1);
341                   pd = (PropertyDescriptor JavaDoc) propertyMap.get(exName);
342                }
343             }
344
345             if (pd == null)
346             {
347                if (isStrict)
348                {
349                   String JavaDoc msg = "No property found for: "+name+" on JavaBean: "+bean;
350                   throw new IntrospectionException JavaDoc(msg);
351                }
352                else
353                {
354                   // since is not strict, ignore that this property was not found
355
continue;
356                }
357             }
358          }
359          Method JavaDoc setter = pd.getWriteMethod();
360          if( trace )
361             log.trace("Property editor found for: "+name+", editor: "+pd+", setter: "+setter);
362          if (setter != null)
363          {
364             Class JavaDoc ptype = pd.getPropertyType();
365             PropertyEditor JavaDoc editor = PropertyEditorManager.findEditor(ptype);
366             if (editor == null)
367             {
368                if( trace )
369                   log.trace("Failed to find property editor for: "+name);
370             }
371             try
372             {
373                editor.setAsText(text);
374                Object JavaDoc args[] = {editor.getValue()};
375                setter.invoke(bean, args);
376             }
377             catch (Exception JavaDoc e)
378             {
379                if( trace )
380                   log.trace("Failed to write property", e);
381             }
382          }
383       }
384    }
385
386    /**
387     * Gets the package names that will be searched for property editors.
388     *
389     * @return The package names that will be searched for property editors.
390     */

391    public String JavaDoc[] getEditorSearchPath()
392    {
393       return PropertyEditorManager.getEditorSearchPath();
394    }
395
396    /**
397     * Sets the package names that will be searched for property editors.
398     *
399     * @param path The serach path.
400     */

401    public void setEditorSearchPath(final String JavaDoc[] path)
402    {
403       PropertyEditorManager.setEditorSearchPath(path);
404    }
405
406    private static class Initialize implements PrivilegedAction JavaDoc
407    {
408       static Initialize instance = new Initialize();
409
410       public Object JavaDoc run()
411       {
412          String JavaDoc[] currentPath = PropertyEditorManager.getEditorSearchPath();
413          int length = currentPath != null ? currentPath.length : 0;
414          String JavaDoc[] newPath = new String JavaDoc[length+2];
415          System.arraycopy(currentPath, 0, newPath, 2, length);
416          // Put the JBoss editor path first
417
// The default editors are not very flexible
418
newPath[0] = "org.jboss.util.propertyeditor";
419          newPath[1] = "org.jboss.mx.util.propertyeditor";
420          PropertyEditorManager.setEditorSearchPath(newPath);
421    
422          /* Register the editor types that will not be found using the standard
423          class name to editor name algorithm. For example, the type String[] has
424          a name '[Ljava.lang.String;' which does not map to a XXXEditor name.
425          */

426          Class JavaDoc strArrayType = String JavaDoc[].class;
427          PropertyEditorManager.registerEditor(strArrayType, StringArrayEditor.class);
428          Class JavaDoc clsArrayType = Class JavaDoc[].class;
429          PropertyEditorManager.registerEditor(clsArrayType, ClassArrayEditor.class);
430          Class JavaDoc intArrayType = int[].class;
431          PropertyEditorManager.registerEditor(intArrayType, IntArrayEditor.class);
432          Class JavaDoc byteArrayType = byte[].class;
433          PropertyEditorManager.registerEditor(byteArrayType, ByteArrayEditor.class);
434    
435          // There is no default char editor.
436
PropertyEditorManager.registerEditor(Character.TYPE, CharacterEditor.class);
437          
438          try
439          {
440             if (System.getProperty("org.jboss.util.property.disablenull") != null)
441                disableIsNull = true;
442          }
443          catch (Throwable JavaDoc ignored)
444          {
445             log.trace("Error retrieving system property org.jboss.util.property.diablenull", ignored);
446          }
447          return null;
448       }
449    }
450 }
451
Popular Tags