Source Code Cross Referenced for Introspector.java in  » Apache-Harmony-Java-SE » java-package » java » 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 » Apache Harmony Java SE » java package » java.beans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package java.beans;
019:
020:        import java.util.Collections;
021:        import java.util.Map;
022:        import java.util.WeakHashMap;
023:
024:        /**
025:         * The <code>Introspector</code> is a utility for developers to figure out
026:         * which properties, events, and methods a JavaBean supports.
027:         * <p>
028:         * The <code>Introspector</code> class walks over the class/superclass chain
029:         * of the target bean class. At each level it checks if there is a matching
030:         * <code>BeanInfo</code> class which provides explicit information about the
031:         * bean, and if so uses that explicit information. Otherwise it uses the low
032:         * level reflection APIs to study the target class and uses design patterns to
033:         * analyze its behaviour and then proceeds to continue the introspection with
034:         * its baseclass.
035:         * </p>
036:         * <p>
037:         * To look for the explicit information of a bean:
038:         * </p>
039:         * <ol>
040:         * <li>The <code>Introspector</code> appends "BeanInfo" to the qualified name
041:         * of the bean class, try to use the new class as the "BeanInfo" class. If the
042:         * "BeanInfo" class exsits and returns non-null value when queried for explicit
043:         * information, use the explicit information</li>
044:         * <li>If the first step fails, the <code>Introspector</code> will extract a
045:         * simple class name of the bean class by removing the package name from the
046:         * qualified name of the bean class, append "BeanInfo" to it. And look for the
047:         * simple class name in the packages defined in the "BeanInfo" search path (The
048:         * default "BeanInfo" search path is <code>sun.beans.infos</code>). If it
049:         * finds a "BeanInfo" class and the "BeanInfo" class returns non-null value when
050:         * queried for explicit information, use the explicit information</li>
051:         * </ol>
052:         * 
053:         */
054:        //ScrollPane cannot be introspected correctly
055:        public class Introspector extends java.lang.Object {
056:
057:            // Public fields
058:            /**
059:             * Constant values to indicate that the <code>Introspector</code> will
060:             * ignore all <code>BeanInfo</code> class.
061:             */
062:            public static final int IGNORE_ALL_BEANINFO = 3;
063:
064:            /**
065:             * Constant values to indicate that the <code>Introspector</code> will
066:             * ignore the <code>BeanInfo</code> class of the current bean class.
067:             */
068:            public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
069:
070:            /**
071:             * Constant values to indicate that the <code>Introspector</code> will use
072:             * all <code>BeanInfo</code> class which have been found. This is the default one.
073:             */
074:            public static final int USE_ALL_BEANINFO = 1;
075:
076:            // Default search path for BeanInfo classes
077:            private static final String DEFAULT_BEANINFO_SEARCHPATH = "sun.beans.infos"; //$NON-NLS-1$
078:
079:            // The search path to use to find BeanInfo classes
080:            // - an array of package names that are used in turn
081:            private static String[] searchPath = { DEFAULT_BEANINFO_SEARCHPATH };
082:
083:            // The cache to store Bean Info objects that have been found or created
084:            private static final int DEFAULT_CAPACITY = 128;
085:
086:            private static Map<Class<?>, StandardBeanInfo> theCache = Collections
087:                    .synchronizedMap(new WeakHashMap<Class<?>, StandardBeanInfo>(
088:                            DEFAULT_CAPACITY));
089:
090:            private Introspector() {
091:                super ();
092:            }
093:
094:            /**
095:             * Decapitalizes a given string according to the rule:
096:             * <ul>
097:             * <li>If the first or only character is Upper Case, it is made Lower Case
098:             * <li>UNLESS the second character is also Upper Case, when the String is
099:             * returned unchanged <eul>
100:             * 
101:             * @param name -
102:             *            the String to decapitalize
103:             * @return the decapitalized version of the String
104:             */
105:            public static String decapitalize(String name) {
106:
107:                if (name == null)
108:                    return null;
109:                // The rule for decapitalize is that:
110:                // If the first letter of the string is Upper Case, make it lower case
111:                // UNLESS the second letter of the string is also Upper Case, in which case no
112:                // changes are made.
113:                if (name.length() == 0
114:                        || (name.length() > 1 && Character.isUpperCase(name
115:                                .charAt(1)))) {
116:                    return name;
117:                }
118:
119:                char[] chars = name.toCharArray();
120:                chars[0] = Character.toLowerCase(chars[0]);
121:                return new String(chars);
122:            }
123:
124:            /**
125:             * Flushes all <code>BeanInfo</code> caches.
126:             *  
127:             */
128:            public static void flushCaches() {
129:                // Flush the cache by throwing away the cache HashMap and creating a
130:                // new empty one
131:                theCache.clear();
132:            }
133:
134:            /**
135:             * Flushes the <code>BeanInfo</code> caches of the specified bean class
136:             * 
137:             * @param clazz
138:             *            the specified bean class
139:             */
140:            public static void flushFromCaches(Class<?> clazz) {
141:                if (clazz == null) {
142:                    throw new NullPointerException();
143:                }
144:                theCache.remove(clazz);
145:            }
146:
147:            /**
148:             * Gets the <code>BeanInfo</code> object which contains the information of
149:             * the properties, events and methods of the specified bean class.
150:             * 
151:             * <p>
152:             * The <code>Introspector</code> will cache the <code>BeanInfo</code>
153:             * object. Subsequent calls to this method will be answered with the cached
154:             * data.
155:             * </p>
156:             * 
157:             * @param beanClass
158:             *            the specified bean class.
159:             * @return the <code>BeanInfo</code> of the bean class.
160:             * @throws IntrospectionException
161:             */
162:            public static BeanInfo getBeanInfo(Class<?> beanClass)
163:                    throws IntrospectionException {
164:                StandardBeanInfo beanInfo = theCache.get(beanClass);
165:                if (beanInfo == null) {
166:                    beanInfo = getBeanInfoImplAndInit(beanClass, null,
167:                            USE_ALL_BEANINFO);
168:                    theCache.put(beanClass, beanInfo);
169:                }
170:                return beanInfo;
171:            }
172:
173:            /**
174:             * Gets the <code>BeanInfo</code> object which contains the information of
175:             * the properties, events and methods of the specified bean class. It will
176:             * not introspect the "stopclass" and its super class.
177:             * 
178:             * <p>
179:             * The <code>Introspector</code> will cache the <code>BeanInfo</code>
180:             * object. Subsequent calls to this method will be answered with the cached
181:             * data.
182:             * </p>
183:             * 
184:             * @param beanClass
185:             *            the specified beanClass.
186:             * @param stopClass
187:             *            the sopt class which should be super class of the bean class.
188:             *            May be null.
189:             * @return the <code>BeanInfo</code> of the bean class.
190:             * @throws IntrospectionException
191:             */
192:            public static BeanInfo getBeanInfo(Class<?> beanClass,
193:                    Class<?> stopClass) throws IntrospectionException {
194:                if (stopClass == null) {
195:                    //try to use cache
196:                    return getBeanInfo(beanClass);
197:                }
198:                return getBeanInfoImplAndInit(beanClass, stopClass,
199:                        USE_ALL_BEANINFO);
200:            }
201:
202:            /**
203:             * Gets the <code>BeanInfo</code> object which contains the information of
204:             * the properties, events and methods of the specified bean class.
205:             * <ol>
206:             * <li>If <code>flag==IGNORE_ALL_BEANINFO</code>, the
207:             * <code>Introspector</code> will ignore all <code>BeanInfo</code>
208:             * class.</li>
209:             * <li>If <code>flag==IGNORE_IMMEDIATE_BEANINFO</code>, the
210:             * <code>Introspector</code> will ignore the <code>BeanInfo</code> class
211:             * of the current bean class.</li>
212:             * <li>If <code>flag==USE_ALL_BEANINFO</code>, the
213:             * <code>Introspector</code> will use all <code>BeanInfo</code> class
214:             * which have been found.</li>
215:             * </ol>
216:             * <p>
217:             * The <code>Introspector</code> will cache the <code>BeanInfo</code>
218:             * object. Subsequent calls to this method will be answered with the cached
219:             * data.
220:             * </p>
221:             * 
222:             * @param beanClass
223:             *            the specified bean class.
224:             * @param flags
225:             *            the flag to control the usage of the explicit
226:             *            <code>BeanInfo</code> class.
227:             * @return the <code>BeanInfo</code> of the bean class.
228:             * @throws IntrospectionException
229:             */
230:            public static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
231:                    throws IntrospectionException {
232:                if (flags == USE_ALL_BEANINFO) {
233:                    //try to use cache            
234:                    return getBeanInfo(beanClass);
235:                }
236:                return getBeanInfoImplAndInit(beanClass, null, flags);
237:            }
238:
239:            /**
240:             * Gets an array of search packages.
241:             * 
242:             * @return an array of search packages.
243:             */
244:            public static String[] getBeanInfoSearchPath() {
245:                String[] path = new String[searchPath.length];
246:                System.arraycopy(searchPath, 0, path, 0, searchPath.length);
247:                return path;
248:            }
249:
250:            /**
251:             * Sets the search packages.
252:             * 
253:             * @param path the new search packages to be set.
254:             */
255:            public static void setBeanInfoSearchPath(String[] path) {
256:                if (System.getSecurityManager() != null) {
257:                    System.getSecurityManager().checkPropertiesAccess();
258:                }
259:                searchPath = path;
260:            }
261:
262:            private static StandardBeanInfo getBeanInfoImpl(Class<?> beanClass,
263:                    Class<?> stopClass, int flags)
264:                    throws IntrospectionException {
265:                BeanInfo explicitInfo = null;
266:                if (flags == USE_ALL_BEANINFO) {
267:                    explicitInfo = getExplicitBeanInfo(beanClass);
268:                }
269:                StandardBeanInfo beanInfo = new StandardBeanInfo(beanClass,
270:                        explicitInfo, stopClass);
271:
272:                if (beanInfo.additionalBeanInfo != null) {
273:                    for (int i = beanInfo.additionalBeanInfo.length - 1; i >= 0; i--) {
274:                        BeanInfo info = beanInfo.additionalBeanInfo[i];
275:                        beanInfo.mergeBeanInfo(info, true);
276:                    }
277:                }
278:
279:                // recursive get beaninfo for super classes
280:                Class<?> beanSuperClass = beanClass.getSuperclass();
281:                if (beanSuperClass != stopClass) {
282:                    if (beanSuperClass == null)
283:                        throw new IntrospectionException(
284:                                "Stop class is not super class of bean class"); //$NON-NLS-1$
285:                    int super flags = flags == IGNORE_IMMEDIATE_BEANINFO ? USE_ALL_BEANINFO
286:                            : flags;
287:                    BeanInfo super BeanInfo = getBeanInfoImpl(beanSuperClass,
288:                            stopClass, super flags);
289:                    if (super BeanInfo != null) {
290:                        beanInfo.mergeBeanInfo(super BeanInfo, false);
291:                    }
292:                }
293:                return beanInfo;
294:            }
295:
296:            private static BeanInfo getExplicitBeanInfo(Class<?> beanClass) {
297:                BeanInfo theBeanInfo = null;
298:                String beanInfoClassName = beanClass.getName() + "BeanInfo"; //$NON-NLS-1$
299:                try {
300:                    theBeanInfo = loadBeanInfo(beanInfoClassName, beanClass);
301:                    return theBeanInfo;
302:                } catch (Exception e) {
303:                    //fall through
304:                }
305:                int index = beanInfoClassName.lastIndexOf('.');
306:                String beanInfoName = index >= 0 ? beanInfoClassName
307:                        .substring(index + 1) : beanInfoClassName;
308:                for (int i = 0; i < searchPath.length; i++) {
309:                    beanInfoClassName = searchPath[i] + "." + beanInfoName; //$NON-NLS-1$
310:                    try {
311:                        theBeanInfo = loadBeanInfo(beanInfoClassName, beanClass);
312:                        break;
313:                    } catch (Exception e) {
314:                        //ignore, try next one
315:                    }
316:                }
317:                return theBeanInfo;
318:            }
319:
320:            /*
321:             * Method which attempts to instantiate a BeanInfo object of the supplied
322:             * classname
323:             * 
324:             * @param theBeanInfoClassName -
325:             *            the Class Name of the class of which the BeanInfo is an
326:             *            instance
327:             * @param classLoader
328:             * @return A BeanInfo object which is an instance of the Class named
329:             *         theBeanInfoClassName null if the Class does not exist or if there
330:             *         are problems instantiating the instance
331:             */
332:            private static BeanInfo loadBeanInfo(String beanInfoClassName,
333:                    Class<?> beanClass) throws Exception {
334:                try {
335:                    ClassLoader cl = beanClass.getClassLoader();
336:                    if (cl != null) {
337:                        return (BeanInfo) Class.forName(beanInfoClassName,
338:                                true, beanClass.getClassLoader()).newInstance();
339:                    }
340:                } catch (Exception e) {
341:                    // fall through
342:                }
343:                try {
344:                    return (BeanInfo) Class.forName(beanInfoClassName, true,
345:                            ClassLoader.getSystemClassLoader()).newInstance();
346:                } catch (Exception e) {
347:                    // fall through
348:                }
349:                return (BeanInfo) Class.forName(beanInfoClassName, true,
350:                        Thread.currentThread().getContextClassLoader())
351:                        .newInstance();
352:            }
353:
354:            private static StandardBeanInfo getBeanInfoImplAndInit(
355:                    Class<?> beanClass, Class<?> stopClass, int flag)
356:                    throws IntrospectionException {
357:                StandardBeanInfo standardBeanInfo = getBeanInfoImpl(beanClass,
358:                        stopClass, flag);
359:                standardBeanInfo.init();
360:                return standardBeanInfo;
361:            }
362:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.