View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.integration.beans;
21  
22  import java.beans.PropertyEditor;
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Properties;
27  import java.util.Set;
28  
29  /**
30   * A factory that creates a new {@link PropertyEditor} which is appropriate for
31   * the specified object or class. 
32   * 
33   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
34   */
35  public final class PropertyEditorFactory {
36      private PropertyEditorFactory() {
37      }
38  
39      /**
40       * Creates a new instance of editor, depending on the given object's type
41       * 
42       * @param object The object we need an editor to be created for
43       * @return The created editor
44       */
45      @SuppressWarnings("unchecked")
46      public static PropertyEditor getInstance(Object object) {
47          if (object == null) {
48              return new NullEditor();
49          }
50  
51          if (object instanceof Collection<?>) {
52              Class<?> elementType = null;
53              
54              for (Object e : (Collection<Object>) object) {
55                  if (e != null) {
56                      elementType = e.getClass();
57                      
58                      break;
59                  }
60              }
61  
62              if (elementType != null) {
63                  if (object instanceof Set) {
64                      return new SetEditor(elementType);
65                  }
66  
67                  if (object instanceof List) {
68                      return new ListEditor(elementType);
69                  }
70  
71                  return new CollectionEditor(elementType);
72              }
73          }
74  
75          if (object instanceof Map) {
76              Class<?> keyType = null;
77              Class<?> valueType = null;
78              
79              for (Object entry : ((Map<?,?>) object).entrySet()) {
80                  Map.Entry<?,?> e = (Map.Entry<?,?>) entry;
81                  
82                  if ((e.getKey() != null) && (e.getValue() != null)) {
83                      keyType = e.getKey().getClass();
84                      valueType = e.getValue().getClass();
85                      
86                      break;
87                  }
88              }
89  
90              if ((keyType != null) && (valueType != null)) {
91                  return new MapEditor(keyType, valueType);
92              }
93          }
94  
95          return getInstance(object.getClass());
96      }
97  
98      /**
99       * Creates a new instance of editor, depending on the given type
100      * 
101      * @param type The type of editor to create
102      * @return The created editor
103      */
104     public static PropertyEditor getInstance(Class<?> type) {
105         if (type == null) {
106             throw new IllegalArgumentException("type");
107         }
108 
109         if (type.isEnum()) {
110             return new EnumEditor(type);
111         }
112 
113         if (type.isArray()) {
114             return new ArrayEditor(type.getComponentType());
115         }
116 
117         if (Collection.class.isAssignableFrom(type)) {
118             if (Set.class.isAssignableFrom(type)) {
119                 return new SetEditor(String.class);
120             }
121 
122             if (List.class.isAssignableFrom(type)) {
123                 return new ListEditor(String.class);
124             }
125 
126             return new CollectionEditor(String.class);
127         }
128 
129         if (Map.class.isAssignableFrom(type)) {
130             return new MapEditor(String.class, String.class);
131         }
132 
133         if (Properties.class.isAssignableFrom(type)) {
134             return new PropertiesEditor();
135         }
136 
137         try {
138             return (PropertyEditor) PropertyEditorFactory.class
139                     .getClassLoader()
140                     .loadClass(
141                             PropertyEditorFactory.class.getPackage().getName() + '.' + 
142                             filterPrimitiveType(type).getSimpleName() + "Editor")
143                     .newInstance();
144         } catch (Exception e) {
145             return null;
146         }
147     }
148 
149     private static Class<?> filterPrimitiveType(Class<?> type) {
150         if (type.isPrimitive()) {
151             if (type == boolean.class) {
152                 return Boolean.class;
153             }
154             
155             if (type == byte.class) {
156                 return Byte.class;
157             }
158             
159             if (type == char.class) {
160                 return Character.class;
161             }
162             
163             if (type == double.class) {
164                 return Double.class;
165             }
166             
167             if (type == float.class) {
168                 return Float.class;
169             }
170             
171             if (type == int.class) {
172                 return Integer.class;
173             }
174             
175             if (type == long.class) {
176                 return Long.class;
177             }
178             
179             if (type == short.class) {
180                 return Short.class;
181             }
182         }
183         
184         return type;
185     }
186 }