Source Code Cross Referenced for MappedPropertyDescriptor.java in  » Workflow-Engines » OSWorkflow » com » opensymphony » workflow » designer » beanutils » 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 » Workflow Engines » OSWorkflow » com.opensymphony.workflow.designer.beanutils 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * The Apache Software License, Version 1.1
003:         *
004:         * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
005:         * reserved.
006:         *
007:         * Redistribution and use in source and binary forms, with or without
008:         * modification, are permitted provided that the following conditions
009:         * are met:
010:         *
011:         * 1. Redistributions of source code must retain the above copyright
012:         *    notice, this list of conditions and the following disclaimer.
013:         *
014:         * 2. Redistributions in binary form must reproduce the above copyright
015:         *    notice, this list of conditions and the following disclaimer in
016:         *    the documentation and/or other materials provided with the
017:         *    distribution.
018:         *
019:         * 3. The end-user documentation included with the redistribution,
020:         *    if any, must include the following acknowledgement:
021:         *       "This product includes software developed by the
022:         *        Apache Software Foundation (http://www.apache.org/)."
023:         *    Alternately, this acknowledgement may appear in the software itself,
024:         *    if and wherever such third-party acknowledgements normally appear.
025:         *
026:         * 4. The names "Apache", "The Jakarta Project", "Commons", and "Apache Software
027:         *    Foundation" must not be used to endorse or promote products derived
028:         *    from this software without prior written permission. For written
029:         *    permission, please contact apache@apache.org.
030:         *
031:         * 5. Products derived from this software may not be called "Apache",
032:         *    "Apache" nor may "Apache" appear in their names without prior
033:         *    written permission of the Apache Software Foundation.
034:         *
035:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046:         * SUCH DAMAGE.
047:         * ====================================================================
048:         *
049:         * This software consists of voluntary contributions made by many
050:         * individuals on behalf of the Apache Software Foundation.  For more
051:         * information on the Apache Software Foundation, please see
052:         * <http://www.apache.org/>.
053:         *
054:         */
055:
056:        package com.opensymphony.workflow.designer.beanutils;
057:
058:        import java.beans.IntrospectionException;
059:        import java.beans.PropertyDescriptor;
060:        import java.lang.reflect.Method;
061:        import java.lang.reflect.Modifier;
062:        import java.security.AccessController;
063:        import java.security.PrivilegedAction;
064:
065:        /**
066:         * A MappedPropertyDescriptor describes one mapped property.
067:         * Mapped properties are multivalued properties like indexed properties
068:         * but that are accessed with a String key instead of an index.
069:         * Such property values are typically stored in a Map collection.
070:         * For this class to work properly, a mapped value must have
071:         * getter and setter methods of the form
072:         * <p><code>get<strong>Property</strong>(String key)<code> and
073:         * <p><code>set&ltProperty&gt(String key, Object value)<code>,
074:         * <p>where <code><strong>Property</strong></code> must be replaced
075:         * by the name of the property.
076:         *
077:         * @author Rey Fran�ois
078:         * @author Gregor Ra�man
079:         * @see java.beans.PropertyDescriptor
080:         */
081:
082:        public class MappedPropertyDescriptor extends PropertyDescriptor {
083:            // ----------------------------------------------------- Instance Variables
084:
085:            /** The underlying data type of the property we are describing. */
086:            private Class mappedPropertyType;
087:
088:            /** The reader method for this property (if any). */
089:            private Method mappedReadMethod;
090:
091:            /** The writer method for this property (if any). */
092:            private Method mappedWriteMethod;
093:
094:            /** The parameter types array for the reader method signature. */
095:            private static final Class[] stringClassArray = new Class[] { String.class };
096:
097:            // ----------------------------------------------------------- Constructors
098:
099:            /**
100:             * Constructs a MappedPropertyDescriptor for a property that follows
101:             * the standard Java convention by having getFoo and setFoo
102:             * accessor methods, with the addition of a String parameter (the key).
103:             * Thus if the argument name is "fred", it will
104:             * assume that the writer method is "setFred" and the reader method
105:             * is "getFred".  Note that the property name should start with a lower
106:             * case character, which will be capitalized in the method names.
107:             *
108:             * @param propertyName The programmatic name of the property.
109:             * @param beanClass    The Class object for the target bean.  For
110:             *                     example sun.beans.OurButton.class.
111:             * @throws IntrospectionException if an exception occurs during
112:             *                                introspection.
113:             */
114:            public MappedPropertyDescriptor(String propertyName, Class beanClass)
115:                    throws IntrospectionException {
116:
117:                super (propertyName, null, null);
118:
119:                if (propertyName == null || propertyName.length() == 0) {
120:                    throw new IntrospectionException("bad property name: "
121:                            + propertyName + " on class: "
122:                            + beanClass.getClass().getName());
123:                }
124:
125:                setName(propertyName);
126:                String base = capitalizePropertyName(propertyName);
127:
128:                // Look for mapped read method and matching write method
129:                try {
130:                    mappedReadMethod = findMethod(beanClass, "get" + base, 1,
131:                            stringClassArray);
132:                    Class params[] = { String.class,
133:                            mappedReadMethod.getReturnType() };
134:                    mappedWriteMethod = findMethod(beanClass, "set" + base, 2,
135:                            params);
136:                } catch (IntrospectionException e) {
137:                    ;
138:                }
139:
140:                // If there's no read method, then look for just a write method
141:                if (mappedReadMethod == null) {
142:                    mappedWriteMethod = findMethod(beanClass, "set" + base, 2);
143:                }
144:
145:                if ((mappedReadMethod == null) && (mappedWriteMethod == null)) {
146:                    throw new IntrospectionException("Property '"
147:                            + propertyName + "' not found on "
148:                            + beanClass.getName());
149:                }
150:
151:                findMappedPropertyType();
152:            }
153:
154:            /**
155:             * This constructor takes the name of a mapped property, and method
156:             * names for reading and writing the property.
157:             *
158:             * @param propertyName     The programmatic name of the property.
159:             * @param beanClass        The Class object for the target bean.  For
160:             *                         example sun.beans.OurButton.class.
161:             * @param mappedGetterName The name of the method used for
162:             *                         reading one of the property values.  May be null if the
163:             *                         property is write-only.
164:             * @param mappedSetterName The name of the method used for writing
165:             *                         one of the property values.  May be null if the property is
166:             *                         read-only.
167:             * @throws IntrospectionException if an exception occurs during
168:             *                                introspection.
169:             */
170:            public MappedPropertyDescriptor(String propertyName,
171:                    Class beanClass, String mappedGetterName,
172:                    String mappedSetterName) throws IntrospectionException {
173:
174:                super (propertyName, null, null);
175:
176:                if (propertyName == null || propertyName.length() == 0) {
177:                    throw new IntrospectionException("bad property name: "
178:                            + propertyName);
179:                }
180:                setName(propertyName);
181:
182:                // search the mapped get and set methods
183:                mappedReadMethod = findMethod(beanClass, mappedGetterName, 1,
184:                        stringClassArray);
185:
186:                if (mappedReadMethod != null) {
187:                    Class params[] = { String.class,
188:                            mappedReadMethod.getReturnType() };
189:                    mappedWriteMethod = findMethod(beanClass, mappedSetterName,
190:                            2, params);
191:                } else {
192:                    mappedWriteMethod = findMethod(beanClass, mappedSetterName,
193:                            2);
194:                }
195:
196:                findMappedPropertyType();
197:            }
198:
199:            /**
200:             * This constructor takes the name of a mapped property, and Method
201:             * objects for reading and writing the property.
202:             *
203:             * @param propertyName The programmatic name of the property.
204:             * @param mappedGetter The method used for reading one of
205:             *                     the property values.  May be be null if the property
206:             *                     is write-only.
207:             * @param mappedSetter The method used for writing one the
208:             *                     property values.  May be null if the property is read-only.
209:             * @throws IntrospectionException if an exception occurs during
210:             *                                introspection.
211:             */
212:            public MappedPropertyDescriptor(String propertyName,
213:                    Method mappedGetter, Method mappedSetter)
214:                    throws IntrospectionException {
215:
216:                super (propertyName, mappedGetter, mappedSetter);
217:
218:                if (propertyName == null || propertyName.length() == 0) {
219:                    throw new IntrospectionException("bad property name: "
220:                            + propertyName);
221:                }
222:
223:                setName(propertyName);
224:                mappedReadMethod = mappedGetter;
225:                mappedWriteMethod = mappedSetter;
226:                findMappedPropertyType();
227:            }
228:
229:            // -------------------------------------------------------- Public Methods
230:
231:            /**
232:             * Gets the Class object for the property values.
233:             *
234:             * @return The Java type info for the property values.  Note that
235:             *         the "Class" object may describe a built-in Java type such as "int".
236:             *         The result may be "null" if this is a mapped property that
237:             *         does not support non-keyed access.
238:             *         <p/>
239:             *         This is the type that will be returned by the mappedReadMethod.
240:             */
241:            public Class getMappedPropertyType() {
242:                return mappedPropertyType;
243:            }
244:
245:            /**
246:             * Gets the method that should be used to read one of the property value.
247:             *
248:             * @return The method that should be used to read the property value.
249:             *         May return null if the property can't be read.
250:             */
251:            public Method getMappedReadMethod() {
252:                return mappedReadMethod;
253:            }
254:
255:            /**
256:             * Sets the method that should be used to read one of the property value.
257:             *
258:             * @param mappedGetter The new getter method.
259:             */
260:            public void setMappedReadMethod(Method mappedGetter)
261:                    throws IntrospectionException {
262:                mappedReadMethod = mappedGetter;
263:                findMappedPropertyType();
264:            }
265:
266:            /**
267:             * Gets the method that should be used to write one of the property value.
268:             *
269:             * @return The method that should be used to write one of the property value.
270:             *         May return null if the property can't be written.
271:             */
272:            public Method getMappedWriteMethod() {
273:                return mappedWriteMethod;
274:            }
275:
276:            /**
277:             * Sets the method that should be used to write the property value.
278:             *
279:             * @param mappedSetter The new setter method.
280:             */
281:            public void setMappedWriteMethod(Method mappedSetter)
282:                    throws IntrospectionException {
283:                mappedWriteMethod = mappedSetter;
284:                findMappedPropertyType();
285:            }
286:
287:            // ------------------------------------------------------- Private Methods
288:
289:            /**
290:             * Introspect our bean class to identify the corresponding getter
291:             * and setter methods.
292:             */
293:            private void findMappedPropertyType() throws IntrospectionException {
294:                try {
295:                    mappedPropertyType = null;
296:                    if (mappedReadMethod != null) {
297:                        if (mappedReadMethod.getParameterTypes().length != 1) {
298:                            throw new IntrospectionException(
299:                                    "bad mapped read method arg count");
300:                        }
301:                        mappedPropertyType = mappedReadMethod.getReturnType();
302:                        if (mappedPropertyType == Void.TYPE) {
303:                            throw new IntrospectionException(
304:                                    "mapped read method "
305:                                            + mappedReadMethod.getName()
306:                                            + " returns void");
307:                        }
308:                    }
309:
310:                    if (mappedWriteMethod != null) {
311:                        Class params[] = mappedWriteMethod.getParameterTypes();
312:                        if (params.length != 2) {
313:                            throw new IntrospectionException(
314:                                    "bad mapped write method arg count");
315:                        }
316:                        if (mappedPropertyType != null
317:                                && mappedPropertyType != params[1]) {
318:                            throw new IntrospectionException(
319:                                    "type mismatch between mapped read and write methods");
320:                        }
321:                        mappedPropertyType = params[1];
322:                    }
323:                } catch (IntrospectionException ex) {
324:                    throw ex;
325:                }
326:            }
327:
328:            /**
329:             * Return a capitalized version of the specified property name.
330:             *
331:             * @param s The property name
332:             */
333:            private static String capitalizePropertyName(String s) {
334:                if (s.length() == 0) {
335:                    return s;
336:                }
337:
338:                char chars[] = s.toCharArray();
339:                chars[0] = Character.toUpperCase(chars[0]);
340:                return new String(chars);
341:            }
342:
343:            //======================================================================
344:            // Package private support methods (copied from java.beans.Introspector).
345:            //======================================================================
346:
347:            // Cache of Class.getDeclaredMethods:
348:            private static java.util.Hashtable declaredMethodCache = new java.util.Hashtable();
349:
350:            /*
351:             * Internal method to return *public* methods within a class.
352:             */
353:            private static synchronized Method[] getPublicDeclaredMethods(
354:                    Class clz) {
355:                // Looking up Class.getDeclaredMethods is relatively expensive,
356:                // so we cache the results.
357:                final Class fclz = clz;
358:                Method[] result = (Method[]) declaredMethodCache.get(fclz);
359:                if (result != null) {
360:                    return result;
361:                }
362:
363:                // We have to raise privilege for getDeclaredMethods
364:                result = (Method[]) AccessController
365:                        .doPrivileged(new PrivilegedAction() {
366:                            public Object run() {
367:                                return fclz.getDeclaredMethods();
368:                            }
369:                        });
370:
371:                // Null out any non-public methods.
372:                for (int i = 0; i < result.length; i++) {
373:                    Method method = result[i];
374:                    int mods = method.getModifiers();
375:                    if (!Modifier.isPublic(mods)) {
376:                        result[i] = null;
377:                    }
378:                }
379:
380:                // Add it to the cache.
381:                declaredMethodCache.put(clz, result);
382:                return result;
383:            }
384:
385:            /**
386:             * Internal support for finding a target methodName on a given class.
387:             */
388:            private static Method internalFindMethod(Class start,
389:                    String methodName, int argCount) {
390:                // For overridden methods we need to find the most derived version.
391:                // So we start with the given class and walk up the superclass chain.
392:                for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
393:                    Method methods[] = getPublicDeclaredMethods(cl);
394:                    for (int i = 0; i < methods.length; i++) {
395:                        Method method = methods[i];
396:                        if (method == null) {
397:                            continue;
398:                        }
399:                        // skip static methods.
400:                        int mods = method.getModifiers();
401:                        if (Modifier.isStatic(mods)) {
402:                            continue;
403:                        }
404:                        if (method.getName().equals(methodName)
405:                                && method.getParameterTypes().length == argCount) {
406:                            return method;
407:                        }
408:                    }
409:                }
410:
411:                // Now check any inherited interfaces.  This is necessary both when
412:                // the argument class is itself an interface, and when the argument
413:                // class is an abstract class.
414:                Class ifcs[] = start.getInterfaces();
415:                for (int i = 0; i < ifcs.length; i++) {
416:                    Method m = internalFindMethod(ifcs[i], methodName, argCount);
417:                    if (m != null) {
418:                        return m;
419:                    }
420:                }
421:
422:                return null;
423:            }
424:
425:            /**
426:             * Internal support for finding a target methodName with a given
427:             * parameter list on a given class.
428:             */
429:            private static Method internalFindMethod(Class start,
430:                    String methodName, int argCount, Class args[]) {
431:                // For overriden methods we need to find the most derived version.
432:                // So we start with the given class and walk up the superclass chain.
433:                for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
434:                    Method methods[] = getPublicDeclaredMethods(cl);
435:                    for (int i = 0; i < methods.length; i++) {
436:                        Method method = methods[i];
437:                        if (method == null) {
438:                            continue;
439:                        }
440:                        // skip static methods.
441:                        int mods = method.getModifiers();
442:                        if (Modifier.isStatic(mods)) {
443:                            continue;
444:                        }
445:                        // make sure method signature matches.
446:                        Class params[] = method.getParameterTypes();
447:                        if (method.getName().equals(methodName)
448:                                && params.length == argCount) {
449:                            boolean different = false;
450:                            if (argCount > 0) {
451:                                for (int j = 0; j < argCount; j++) {
452:                                    if (params[j] != args[j]) {
453:                                        different = true;
454:                                        continue;
455:                                    }
456:                                }
457:                                if (different) {
458:                                    continue;
459:                                }
460:                            }
461:                            return method;
462:                        }
463:                    }
464:                }
465:
466:                // Now check any inherited interfaces.  This is necessary both when
467:                // the argument class is itself an interface, and when the argument
468:                // class is an abstract class.
469:                Class ifcs[] = start.getInterfaces();
470:                for (int i = 0; i < ifcs.length; i++) {
471:                    Method m = internalFindMethod(ifcs[i], methodName, argCount);
472:                    if (m != null) {
473:                        return m;
474:                    }
475:                }
476:
477:                return null;
478:            }
479:
480:            /**
481:             * Find a target methodName on a given class.
482:             */
483:            static Method findMethod(Class cls, String methodName, int argCount)
484:                    throws IntrospectionException {
485:                if (methodName == null) {
486:                    return null;
487:                }
488:
489:                Method m = internalFindMethod(cls, methodName, argCount);
490:                if (m != null) {
491:                    return m;
492:                }
493:
494:                // We failed to find a suitable method
495:                throw new IntrospectionException("No method \"" + methodName
496:                        + "\" with " + argCount + " arg(s)");
497:            }
498:
499:            /**
500:             * Find a target methodName with specific parameter list on a given class.
501:             */
502:            static Method findMethod(Class cls, String methodName,
503:                    int argCount, Class args[]) throws IntrospectionException {
504:                if (methodName == null) {
505:                    return null;
506:                }
507:
508:                Method m = internalFindMethod(cls, methodName, argCount, args);
509:                if (m != null) {
510:                    return m;
511:                }
512:
513:                // We failed to find a suitable method
514:                throw new IntrospectionException("No method \"" + methodName
515:                        + "\" with " + argCount + " arg(s) of matching types.");
516:            }
517:
518:            /**
519:             * Return true if class a is either equivalent to class b, or
520:             * if class a is a subclass of class b, ie if a either "extends"
521:             * or "implements" b.
522:             * Note tht either or both "Class" objects may represent interfaces.
523:             */
524:            static boolean isSubclass(Class a, Class b) {
525:                // We rely on the fact that for any given java class or
526:                // primtitive type there is a unqiue Class object, so
527:                // we can use object equivalence in the comparisons.
528:                if (a == b) {
529:                    return true;
530:                }
531:
532:                if (a == null || b == null) {
533:                    return false;
534:                }
535:
536:                for (Class x = a; x != null; x = x.getSuperclass()) {
537:                    if (x == b) {
538:                        return true;
539:                    }
540:
541:                    if (b.isInterface()) {
542:                        Class interfaces[] = x.getInterfaces();
543:                        for (int i = 0; i < interfaces.length; i++) {
544:                            if (isSubclass(interfaces[i], b)) {
545:                                return true;
546:                            }
547:                        }
548:                    }
549:                }
550:
551:                return false;
552:            }
553:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.