Source Code Cross Referenced for PropertyEditorRegistrySupport.java in  » J2EE » spring-framework-2.0.6 » org » springframework » beans » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.beans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.beans;
018:
019:        import java.beans.PropertyEditor;
020:        import java.io.File;
021:        import java.io.InputStream;
022:        import java.math.BigDecimal;
023:        import java.math.BigInteger;
024:        import java.net.URI;
025:        import java.net.URL;
026:        import java.util.Collection;
027:        import java.util.HashMap;
028:        import java.util.HashSet;
029:        import java.util.Iterator;
030:        import java.util.LinkedList;
031:        import java.util.List;
032:        import java.util.Locale;
033:        import java.util.Map;
034:        import java.util.Properties;
035:        import java.util.Set;
036:        import java.util.SortedMap;
037:        import java.util.SortedSet;
038:        import java.util.regex.Pattern;
039:
040:        import org.springframework.beans.propertyeditors.ByteArrayPropertyEditor;
041:        import org.springframework.beans.propertyeditors.CharArrayPropertyEditor;
042:        import org.springframework.beans.propertyeditors.CharacterEditor;
043:        import org.springframework.beans.propertyeditors.ClassArrayEditor;
044:        import org.springframework.beans.propertyeditors.ClassEditor;
045:        import org.springframework.beans.propertyeditors.CustomBooleanEditor;
046:        import org.springframework.beans.propertyeditors.CustomCollectionEditor;
047:        import org.springframework.beans.propertyeditors.CustomMapEditor;
048:        import org.springframework.beans.propertyeditors.CustomNumberEditor;
049:        import org.springframework.beans.propertyeditors.FileEditor;
050:        import org.springframework.beans.propertyeditors.InputStreamEditor;
051:        import org.springframework.beans.propertyeditors.LocaleEditor;
052:        import org.springframework.beans.propertyeditors.PatternEditor;
053:        import org.springframework.beans.propertyeditors.PropertiesEditor;
054:        import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
055:        import org.springframework.beans.propertyeditors.URIEditor;
056:        import org.springframework.beans.propertyeditors.URLEditor;
057:        import org.springframework.core.CollectionFactory;
058:        import org.springframework.core.JdkVersion;
059:        import org.springframework.core.io.Resource;
060:        import org.springframework.core.io.support.ResourceArrayPropertyEditor;
061:        import org.springframework.util.ClassUtils;
062:
063:        /**
064:         * Base implementation of the {@link PropertyEditorRegistry} interface.
065:         * Provides management of default editors and custom editors.
066:         * Mainly serves as base class for {@link BeanWrapperImpl}.
067:         *
068:         * @author Juergen Hoeller
069:         * @author Rob Harrop
070:         * @since 1.2.6
071:         * @see java.beans.PropertyEditorManager
072:         * @see java.beans.PropertyEditorSupport#setAsText
073:         * @see java.beans.PropertyEditorSupport#setValue
074:         */
075:        public class PropertyEditorRegistrySupport implements 
076:                PropertyEditorRegistry {
077:
078:            private boolean defaultEditorsActive = false;
079:
080:            private boolean configValueEditorsActive = false;
081:
082:            private boolean propertySpecificEditorsRegistered = false;
083:
084:            private Map defaultEditors;
085:
086:            private Map customEditors;
087:
088:            private Set sharedEditors;
089:
090:            private Map customEditorCache;
091:
092:            //---------------------------------------------------------------------
093:            // Management of default editors
094:            //---------------------------------------------------------------------
095:
096:            /**
097:             * Activate the default editors for this registry instance,
098:             * allowing for lazily registering default editors when needed.
099:             */
100:            protected void registerDefaultEditors() {
101:                this .defaultEditorsActive = true;
102:            }
103:
104:            /**
105:             * Activate config value editors which are only intended for configuration purposes,
106:             * such as {@link org.springframework.beans.propertyeditors.StringArrayPropertyEditor}.
107:             * <p>Those editors are not registered by default simply because they are in
108:             * general inappropriate for data binding purposes. Of course, you may register
109:             * them individually in any case, through {@link #registerCustomEditor}.
110:             */
111:            public void useConfigValueEditors() {
112:                this .configValueEditorsActive = true;
113:            }
114:
115:            /**
116:             * Retrieve the default editor for the given property type, if any.
117:             * <p>Lazily registers the default editors, if they are active.
118:             * @param requiredType type of the property
119:             * @return the default editor, or <code>null</code> if none found
120:             * @see #registerDefaultEditors
121:             */
122:            protected PropertyEditor getDefaultEditor(Class requiredType) {
123:                if (!this .defaultEditorsActive) {
124:                    return null;
125:                }
126:                if (this .defaultEditors == null) {
127:                    doRegisterDefaultEditors();
128:                }
129:                return (PropertyEditor) this .defaultEditors.get(requiredType);
130:            }
131:
132:            /**
133:             * Actually register the default editors for this registry instance.
134:             * @see org.springframework.beans.propertyeditors.ByteArrayPropertyEditor
135:             * @see org.springframework.beans.propertyeditors.ClassEditor
136:             * @see org.springframework.beans.propertyeditors.CharacterEditor
137:             * @see org.springframework.beans.propertyeditors.CustomBooleanEditor
138:             * @see org.springframework.beans.propertyeditors.CustomNumberEditor
139:             * @see org.springframework.beans.propertyeditors.CustomCollectionEditor
140:             * @see org.springframework.beans.propertyeditors.CustomMapEditor
141:             * @see org.springframework.beans.propertyeditors.FileEditor
142:             * @see org.springframework.beans.propertyeditors.InputStreamEditor
143:             * @see org.springframework.jndi.JndiTemplateEditor
144:             * @see org.springframework.beans.propertyeditors.LocaleEditor
145:             * @see org.springframework.beans.propertyeditors.PropertiesEditor
146:             * @see org.springframework.beans.PropertyValuesEditor
147:             * @see org.springframework.core.io.support.ResourceArrayPropertyEditor
148:             * @see org.springframework.core.io.ResourceEditor
149:             * @see org.springframework.transaction.interceptor.TransactionAttributeEditor
150:             * @see org.springframework.transaction.interceptor.TransactionAttributeSourceEditor
151:             * @see org.springframework.beans.propertyeditors.URLEditor
152:             */
153:            private void doRegisterDefaultEditors() {
154:                this .defaultEditors = new HashMap(64);
155:
156:                // Simple editors, without parameterization capabilities.
157:                // The JDK does not contain a default editor for any of these target types.
158:                this .defaultEditors.put(Class.class, new ClassEditor());
159:                this .defaultEditors.put(Class[].class, new ClassArrayEditor());
160:                this .defaultEditors.put(File.class, new FileEditor());
161:                this .defaultEditors.put(InputStream.class,
162:                        new InputStreamEditor());
163:                this .defaultEditors.put(Locale.class, new LocaleEditor());
164:                this .defaultEditors.put(Properties.class,
165:                        new PropertiesEditor());
166:                this .defaultEditors.put(Resource[].class,
167:                        new ResourceArrayPropertyEditor());
168:                this .defaultEditors.put(URL.class, new URLEditor());
169:
170:                // Register JDK-1.4-specific editors.
171:                if (JdkVersion.isAtLeastJava14()) {
172:                    this .defaultEditors.put(URI.class, new URIEditor());
173:                    this .defaultEditors.put(Pattern.class, new PatternEditor());
174:                }
175:
176:                // Default instances of collection editors.
177:                // Can be overridden by registering custom instances of those as custom editors.
178:                this .defaultEditors.put(Collection.class,
179:                        new CustomCollectionEditor(Collection.class));
180:                this .defaultEditors.put(Set.class, new CustomCollectionEditor(
181:                        Set.class));
182:                this .defaultEditors.put(SortedSet.class,
183:                        new CustomCollectionEditor(SortedSet.class));
184:                this .defaultEditors.put(List.class, new CustomCollectionEditor(
185:                        List.class));
186:                this .defaultEditors.put(SortedMap.class, new CustomMapEditor(
187:                        SortedMap.class));
188:
189:                // Default editors for primitive arrays.
190:                this .defaultEditors.put(byte[].class,
191:                        new ByteArrayPropertyEditor());
192:                this .defaultEditors.put(char[].class,
193:                        new CharArrayPropertyEditor());
194:
195:                // The JDK does not contain a default editor for char!
196:                this .defaultEditors.put(char.class, new CharacterEditor(false));
197:                this .defaultEditors.put(Character.class, new CharacterEditor(
198:                        true));
199:
200:                // Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
201:                this .defaultEditors.put(boolean.class, new CustomBooleanEditor(
202:                        false));
203:                this .defaultEditors.put(Boolean.class, new CustomBooleanEditor(
204:                        true));
205:
206:                // The JDK does not contain default editors for number wrapper types!
207:                // Override JDK primitive number editors with our own CustomNumberEditor.
208:                this .defaultEditors.put(byte.class, new CustomNumberEditor(
209:                        Byte.class, false));
210:                this .defaultEditors.put(Byte.class, new CustomNumberEditor(
211:                        Byte.class, true));
212:                this .defaultEditors.put(short.class, new CustomNumberEditor(
213:                        Short.class, false));
214:                this .defaultEditors.put(Short.class, new CustomNumberEditor(
215:                        Short.class, true));
216:                this .defaultEditors.put(int.class, new CustomNumberEditor(
217:                        Integer.class, false));
218:                this .defaultEditors.put(Integer.class, new CustomNumberEditor(
219:                        Integer.class, true));
220:                this .defaultEditors.put(long.class, new CustomNumberEditor(
221:                        Long.class, false));
222:                this .defaultEditors.put(Long.class, new CustomNumberEditor(
223:                        Long.class, true));
224:                this .defaultEditors.put(float.class, new CustomNumberEditor(
225:                        Float.class, false));
226:                this .defaultEditors.put(Float.class, new CustomNumberEditor(
227:                        Float.class, true));
228:                this .defaultEditors.put(double.class, new CustomNumberEditor(
229:                        Double.class, false));
230:                this .defaultEditors.put(Double.class, new CustomNumberEditor(
231:                        Double.class, true));
232:                this .defaultEditors.put(BigDecimal.class,
233:                        new CustomNumberEditor(BigDecimal.class, true));
234:                this .defaultEditors.put(BigInteger.class,
235:                        new CustomNumberEditor(BigInteger.class, true));
236:
237:                // Only register config value editors if explicitly requested.
238:                if (this .configValueEditorsActive) {
239:                    this .defaultEditors.put(String[].class,
240:                            new StringArrayPropertyEditor());
241:                }
242:            }
243:
244:            /**
245:             * Copy the default editors registered in this instance to the given target registry.
246:             * @param target the target registry to copy to
247:             */
248:            protected void copyDefaultEditorsTo(
249:                    PropertyEditorRegistrySupport target) {
250:                target.defaultEditors = this .defaultEditors;
251:                target.defaultEditorsActive = this .defaultEditorsActive;
252:                target.configValueEditorsActive = this .configValueEditorsActive;
253:            }
254:
255:            //---------------------------------------------------------------------
256:            // Management of custom editors
257:            //---------------------------------------------------------------------
258:
259:            public void registerCustomEditor(Class requiredType,
260:                    PropertyEditor propertyEditor) {
261:                registerCustomEditor(requiredType, null, propertyEditor);
262:            }
263:
264:            public void registerCustomEditor(Class requiredType,
265:                    String propertyPath, PropertyEditor propertyEditor) {
266:                if (requiredType == null && propertyPath == null) {
267:                    throw new IllegalArgumentException(
268:                            "Either requiredType or propertyPath is required");
269:                }
270:                if (this .customEditors == null) {
271:                    this .customEditors = CollectionFactory
272:                            .createLinkedMapIfPossible(16);
273:                }
274:                if (propertyPath != null) {
275:                    this .customEditors
276:                            .put(propertyPath, new CustomEditorHolder(
277:                                    propertyEditor, requiredType));
278:                    this .propertySpecificEditorsRegistered = true;
279:                } else {
280:                    this .customEditors.put(requiredType, propertyEditor);
281:                    this .customEditorCache = null;
282:                }
283:            }
284:
285:            /**
286:             * Register the given custom property editor for all properties
287:             * of the given type, indicating that the given instance is a
288:             * shared editor that might be used concurrently.
289:             * @param requiredType the type of the property
290:             * @param propertyEditor the shared editor to register
291:             */
292:            public void registerSharedEditor(Class requiredType,
293:                    PropertyEditor propertyEditor) {
294:                registerCustomEditor(requiredType, null, propertyEditor);
295:                if (this .sharedEditors == null) {
296:                    this .sharedEditors = new HashSet();
297:                }
298:                this .sharedEditors.add(propertyEditor);
299:            }
300:
301:            /**
302:             * Check whether the given editor instance is a shared editor, that is,
303:             * whether the given editor instance might be used concurrently.
304:             * @param propertyEditor the editor instance to check
305:             * @return whether the editor is a shared instance
306:             */
307:            public boolean isSharedEditor(PropertyEditor propertyEditor) {
308:                return (this .sharedEditors != null && this .sharedEditors
309:                        .contains(propertyEditor));
310:            }
311:
312:            public PropertyEditor findCustomEditor(Class requiredType,
313:                    String propertyPath) {
314:                if (this .customEditors == null) {
315:                    return null;
316:                }
317:                Class requiredTypeToUse = requiredType;
318:                if (propertyPath != null) {
319:                    if (this .propertySpecificEditorsRegistered) {
320:                        // Check property-specific editor first.
321:                        PropertyEditor editor = getCustomEditor(propertyPath,
322:                                requiredType);
323:                        if (editor == null) {
324:                            List strippedPaths = new LinkedList();
325:                            addStrippedPropertyPaths(strippedPaths, "",
326:                                    propertyPath);
327:                            for (Iterator it = strippedPaths.iterator(); it
328:                                    .hasNext()
329:                                    && editor == null;) {
330:                                String strippedPath = (String) it.next();
331:                                editor = getCustomEditor(strippedPath,
332:                                        requiredType);
333:                            }
334:                        }
335:                        if (editor != null) {
336:                            return editor;
337:                        }
338:                    }
339:                    if (requiredType == null) {
340:                        requiredTypeToUse = getPropertyType(propertyPath);
341:                    }
342:                }
343:                // No property-specific editor -> check type-specific editor.
344:                return getCustomEditor(requiredTypeToUse);
345:            }
346:
347:            /**
348:             * Determine whether this registry contains a custom editor
349:             * for the specified array/collection element.
350:             * @param elementType the target type of the element
351:             * (can be <code>null</code> if not known)
352:             * @param propertyPath the property path (typically of the array/collection;
353:             * can be <code>null</code> if not known)
354:             * @return whether a matching custom editor has been found
355:             */
356:            public boolean hasCustomEditorForElement(Class elementType,
357:                    String propertyPath) {
358:                if (this .customEditors == null) {
359:                    return false;
360:                }
361:                if (propertyPath != null
362:                        && this .propertySpecificEditorsRegistered) {
363:                    for (Iterator it = this .customEditors.entrySet().iterator(); it
364:                            .hasNext();) {
365:                        Map.Entry entry = (Map.Entry) it.next();
366:                        if (entry.getKey() instanceof  String) {
367:                            String regPath = (String) entry.getKey();
368:                            if (PropertyAccessorUtils.matchesProperty(regPath,
369:                                    propertyPath)) {
370:                                CustomEditorHolder editorHolder = (CustomEditorHolder) entry
371:                                        .getValue();
372:                                if (editorHolder.getPropertyEditor(elementType) != null) {
373:                                    return true;
374:                                }
375:                            }
376:                        }
377:                    }
378:                }
379:                // No property-specific editor -> check type-specific editor.
380:                return (elementType != null && this .customEditors
381:                        .containsKey(elementType));
382:            }
383:
384:            /**
385:             * Determine the property type for the given property path.
386:             * <p>Called by {@link #findCustomEditor} if no required type has been specified,
387:             * to be able to find a type-specific editor even if just given a property path.
388:             * <p>The default implementation always returns <code>null</code>.
389:             * BeanWrapperImpl overrides this with the standard <code>getPropertyType</code>
390:             * method as defined by the BeanWrapper interface.
391:             * @param propertyPath the property path to determine the type for
392:             * @return the type of the property, or <code>null</code> if not determinable
393:             * @see BeanWrapper#getPropertyType(String)
394:             */
395:            protected Class getPropertyType(String propertyPath) {
396:                return null;
397:            }
398:
399:            /**
400:             * Get custom editor that has been registered for the given property.
401:             * @param propertyName the property path to look for
402:             * @param requiredType the type to look for
403:             * @return the custom editor, or <code>null</code> if none specific for this property
404:             */
405:            private PropertyEditor getCustomEditor(String propertyName,
406:                    Class requiredType) {
407:                CustomEditorHolder holder = (CustomEditorHolder) this .customEditors
408:                        .get(propertyName);
409:                return (holder != null ? holder.getPropertyEditor(requiredType)
410:                        : null);
411:            }
412:
413:            /**
414:             * Get custom editor for the given type. If no direct match found,
415:             * try custom editor for superclass (which will in any case be able
416:             * to render a value as String via <code>getAsText</code>).
417:             * @param requiredType the type to look for
418:             * @return the custom editor, or <code>null</code> if none found for this type
419:             * @see java.beans.PropertyEditor#getAsText()
420:             */
421:            private PropertyEditor getCustomEditor(Class requiredType) {
422:                if (requiredType == null) {
423:                    return null;
424:                }
425:                // Check directly registered editor for type.
426:                PropertyEditor editor = (PropertyEditor) this .customEditors
427:                        .get(requiredType);
428:                if (editor == null) {
429:                    // Check cached editor for type, registered for superclass or interface.
430:                    if (this .customEditorCache != null) {
431:                        editor = (PropertyEditor) this .customEditorCache
432:                                .get(requiredType);
433:                    }
434:                    if (editor == null) {
435:                        // Find editor for superclass or interface.
436:                        for (Iterator it = this .customEditors.keySet()
437:                                .iterator(); it.hasNext() && editor == null;) {
438:                            Object key = it.next();
439:                            if (key instanceof  Class
440:                                    && ((Class) key)
441:                                            .isAssignableFrom(requiredType)) {
442:                                editor = (PropertyEditor) this .customEditors
443:                                        .get(key);
444:                                // Cache editor for search type, to avoid the overhead
445:                                // of repeated assignable-from checks.
446:                                if (this .customEditorCache == null) {
447:                                    this .customEditorCache = new HashMap();
448:                                }
449:                                this .customEditorCache
450:                                        .put(requiredType, editor);
451:                            }
452:                        }
453:                    }
454:                }
455:                return editor;
456:            }
457:
458:            /**
459:             * Guess the property type of the specified property from the registered
460:             * custom editors (provided that they were registered for a specific type).
461:             * @param propertyName the name of the property
462:             * @return the property type, or <code>null</code> if not determinable
463:             */
464:            protected Class guessPropertyTypeFromEditors(String propertyName) {
465:                if (this .customEditors != null) {
466:                    CustomEditorHolder editorHolder = (CustomEditorHolder) this .customEditors
467:                            .get(propertyName);
468:                    if (editorHolder == null) {
469:                        List strippedPaths = new LinkedList();
470:                        addStrippedPropertyPaths(strippedPaths, "",
471:                                propertyName);
472:                        for (Iterator it = strippedPaths.iterator(); it
473:                                .hasNext()
474:                                && editorHolder == null;) {
475:                            String strippedName = (String) it.next();
476:                            editorHolder = (CustomEditorHolder) this .customEditors
477:                                    .get(strippedName);
478:                        }
479:                    }
480:                    if (editorHolder != null) {
481:                        return editorHolder.getRegisteredType();
482:                    }
483:                }
484:                return null;
485:            }
486:
487:            /**
488:             * Copy the custom editors registered in this instance to the given target registry.
489:             * @param target the target registry to copy to
490:             * @param nestedProperty the nested property path of the target registry, if any.
491:             * If this is non-null, only editors registered for a path below this nested property
492:             * will be copied.
493:             */
494:            protected void copyCustomEditorsTo(PropertyEditorRegistry target,
495:                    String nestedProperty) {
496:                String actualPropertyName = (nestedProperty != null ? PropertyAccessorUtils
497:                        .getPropertyName(nestedProperty)
498:                        : null);
499:                if (this .customEditors != null) {
500:                    for (Iterator it = this .customEditors.entrySet().iterator(); it
501:                            .hasNext();) {
502:                        Map.Entry entry = (Map.Entry) it.next();
503:                        if (entry.getKey() instanceof  Class) {
504:                            Class requiredType = (Class) entry.getKey();
505:                            PropertyEditor editor = (PropertyEditor) entry
506:                                    .getValue();
507:                            target.registerCustomEditor(requiredType, editor);
508:                        } else if (entry.getKey() instanceof  String
509:                                & nestedProperty != null) {
510:                            String editorPath = (String) entry.getKey();
511:                            int pos = PropertyAccessorUtils
512:                                    .getFirstNestedPropertySeparatorIndex(editorPath);
513:                            if (pos != -1) {
514:                                String editorNestedProperty = editorPath
515:                                        .substring(0, pos);
516:                                String editorNestedPath = editorPath
517:                                        .substring(pos + 1);
518:                                if (editorNestedProperty.equals(nestedProperty)
519:                                        || editorNestedProperty
520:                                                .equals(actualPropertyName)) {
521:                                    CustomEditorHolder editorHolder = (CustomEditorHolder) entry
522:                                            .getValue();
523:                                    target.registerCustomEditor(editorHolder
524:                                            .getRegisteredType(),
525:                                            editorNestedPath, editorHolder
526:                                                    .getPropertyEditor());
527:                                }
528:                            }
529:                        }
530:                    }
531:                }
532:            }
533:
534:            /**
535:             * Add property paths with all variations of stripped keys and/or indexes.
536:             * Invokes itself recursively with nested paths.
537:             * @param strippedPaths the result list to add to
538:             * @param nestedPath the current nested path
539:             * @param propertyPath the property path to check for keys/indexes to strip
540:             */
541:            private void addStrippedPropertyPaths(List strippedPaths,
542:                    String nestedPath, String propertyPath) {
543:                int startIndex = propertyPath
544:                        .indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR);
545:                if (startIndex != -1) {
546:                    int endIndex = propertyPath
547:                            .indexOf(PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR);
548:                    if (endIndex != -1) {
549:                        String prefix = propertyPath.substring(0, startIndex);
550:                        String key = propertyPath.substring(startIndex,
551:                                endIndex + 1);
552:                        String suffix = propertyPath.substring(endIndex + 1,
553:                                propertyPath.length());
554:                        // Strip the first key.
555:                        strippedPaths.add(nestedPath + prefix + suffix);
556:                        // Search for further keys to strip, with the first key stripped.
557:                        addStrippedPropertyPaths(strippedPaths, nestedPath
558:                                + prefix, suffix);
559:                        // Search for further keys to strip, with the first key not stripped.
560:                        addStrippedPropertyPaths(strippedPaths, nestedPath
561:                                + prefix + key, suffix);
562:                    }
563:                }
564:            }
565:
566:            /**
567:             * Holder for a registered custom editor with property name.
568:             * Keeps the PropertyEditor itself plus the type it was registered for.
569:             */
570:            private static class CustomEditorHolder {
571:
572:                private final PropertyEditor propertyEditor;
573:
574:                private final Class registeredType;
575:
576:                private CustomEditorHolder(PropertyEditor propertyEditor,
577:                        Class registeredType) {
578:                    this .propertyEditor = propertyEditor;
579:                    this .registeredType = registeredType;
580:                }
581:
582:                private PropertyEditor getPropertyEditor() {
583:                    return this .propertyEditor;
584:                }
585:
586:                private Class getRegisteredType() {
587:                    return this .registeredType;
588:                }
589:
590:                private PropertyEditor getPropertyEditor(Class requiredType) {
591:                    // Special case: If no required type specified, which usually only happens for
592:                    // Collection elements, or required type is not assignable to registered type,
593:                    // which usually only happens for generic properties of type Object -
594:                    // then return PropertyEditor if not registered for Collection or array type.
595:                    // (If not registered for Collection or array, it is assumed to be intended
596:                    // for elements.)
597:                    if (this .registeredType == null
598:                            || (requiredType != null && (ClassUtils
599:                                    .isAssignable(this .registeredType,
600:                                            requiredType) || ClassUtils
601:                                    .isAssignable(requiredType,
602:                                            this .registeredType)))
603:                            || (requiredType == null && (!Collection.class
604:                                    .isAssignableFrom(this.registeredType) && !this.registeredType
605:                                    .isArray()))) {
606:                        return this.propertyEditor;
607:                    } else {
608:                        return null;
609:                    }
610:                }
611:            }
612:
613:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.