Source Code Cross Referenced for MethodAnalyser.java in  » Web-Framework » RSF » uk » org » ponder » saxalizer » 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 » Web Framework » RSF » uk.org.ponder.saxalizer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package uk.org.ponder.saxalizer;
002:
003:        import java.util.ArrayList;
004:        import java.util.Collections;
005:        import java.util.Enumeration;
006:        import java.util.Map;
007:
008:        import uk.org.ponder.arrayutil.ArrayEnumeration;
009:        import uk.org.ponder.beanutil.BeanLocator;
010:        import uk.org.ponder.beanutil.PropertyAccessor;
011:        import uk.org.ponder.beanutil.WriteableBeanLocator;
012:        import uk.org.ponder.beanutil.support.BeanLocatorPropertyAccessor;
013:        import uk.org.ponder.beanutil.support.IndexedPropertyAccessor;
014:        import uk.org.ponder.beanutil.support.MapPropertyAccessor;
015:        import uk.org.ponder.errorutil.PropertyException;
016:        import uk.org.ponder.reflect.ClassGetter;
017:        import uk.org.ponder.saxalizer.mapping.SAXalizerMapperEntry;
018:        import uk.org.ponder.util.Logger;
019:        import uk.org.ponder.util.UniversalRuntimeException;
020:
021:        /**
022:         * One instance of a MethodAnalyser is stored for each SAXalizable class that
023:         * the SAXalizer discovers; this instance is returned when a call is made to
024:         * <code>getMethodAnalyser</code> with an object of the SAXalizable class as
025:         * argument. MethodAnalysers are cached in a static hashtable indexed by the
026:         * SAXalizable class.
027:         * <p>
028:         * Some "bean-sense" has been retroactively blown into this class, which dates
029:         * from the dinosaur SAXalizer days of 2000, with the retrofit of the
030:         * <code>PropertyAccessor</code> interface. Its structure still needs a little
031:         * work though, since it still maintains separate collections for "tag" and
032:         * "attribute" methods &c.
033:         */
034:        public class MethodAnalyser implements  PropertyAccessor {
035:            public Class targetclass;
036:            /**
037:             * Each of the four types of SAXAccessMethods supported, being get and set
038:             * methods for subtags and attributes.
039:             */
040:            public SAXAccessMethodHash tagmethods;
041:            public SAXAccessMethodHash attrmethods;
042:            public SAXAccessMethod bodymethod;
043:            /** A flat array of ALL accessors for the target class. This will be the most
044:             * efficient means of using introspection information, and is populated on
045:             * construction of this MethodAnalyser.
046:             */
047:            public SAXAccessMethod[] allgetters;
048:
049:            private void assembleGetters() {
050:                ArrayList accumulate = new ArrayList();
051:                for (SAMIterator tagget = tagmethods.getGetEnumeration(); tagget
052:                        .valid(); tagget.next()) {
053:                    accumulate.add(tagget.get());
054:                }
055:                for (SAMIterator tagget = attrmethods.getGetEnumeration(); tagget
056:                        .valid(); tagget.next()) {
057:                    accumulate.add(tagget.get());
058:                }
059:                if (bodymethod != null) {
060:                    accumulate.add(allgetters);
061:                }
062:                allgetters = new SAXAccessMethod[accumulate.size()];
063:                for (int i = 0; i < accumulate.size(); ++i) {
064:                    allgetters[i] = (SAXAccessMethod) accumulate.get(i);
065:                }
066:            }
067:
068:            public AccessMethod getAccessMethod(String tagname) {
069:                SAXAccessMethod method = tagmethods.get(tagname);
070:                if (method == null) {
071:                    method = attrmethods.get(tagname);
072:                }
073:                if (method == null
074:                        && WriteableBeanLocator.class
075:                                .isAssignableFrom(targetclass)) {
076:                    return new WBLAccessMethod(WriteableBeanLocator.class,
077:                            tagname);
078:                }
079:                return method;
080:            }
081:
082:            // ****** Begin implementation of PropertyAccessor interface
083:            public boolean canSet(String name) {
084:                AccessMethod accessmethod = getAccessMethod(name);
085:                return accessmethod == null ? false : accessmethod.canSet();
086:            }
087:
088:            public void setProperty(Object parent, String name, Object value) {
089:                AccessMethod accessmethod = getAccessMethod(name);
090:                if (accessmethod == null) {
091:                    throw UniversalRuntimeException.accumulate(
092:                            new PropertyException(), "Property " + name
093:                                    + " of object " + parent.getClass()
094:                                    + " not found");
095:                } else if (!accessmethod.canSet()) {
096:                    throw UniversalRuntimeException.accumulate(
097:                            new PropertyException(), "Property " + name
098:                                    + " of object " + parent.getClass()
099:                                    + " is not writeable");
100:                }
101:                accessmethod.setChildObject(parent, value);
102:            }
103:
104:            public void unlink(Object parent, String name) {
105:                AccessMethod accessmethod = getAccessMethod(name);
106:                if (accessmethod == null) {
107:                    throw UniversalRuntimeException.accumulate(
108:                            new PropertyException(), "Property " + name
109:                                    + " of object " + parent.getClass()
110:                                    + " not found");
111:                }
112:                accessmethod.setChildObject(parent, null);
113:            }
114:
115:            public boolean canGet(String name) {
116:                AccessMethod accessmethod = getAccessMethod(name);
117:                return accessmethod == null ? false : accessmethod.canGet();
118:            }
119:
120:            public Object getProperty(Object parent, String name) {
121:                AccessMethod accessmethod = getAccessMethod(name);
122:                if (accessmethod == null) {
123:                    throw UniversalRuntimeException.accumulate(
124:                            new PropertyException(), "Property " + name
125:                                    + " of object " + parent.getClass()
126:                                    + " not found");
127:                }
128:                return accessmethod.getChildObject(parent);
129:            }
130:
131:            public Class getPropertyType(Object parent, String name) {
132:                AccessMethod accessmethod = getAccessMethod(name);
133:                if (accessmethod == null) {
134:                    throw UniversalRuntimeException.accumulate(
135:                            new PropertyException(), "Property " + name
136:                                    + " of " + targetclass + " not found ");
137:                }
138:                return accessmethod.getAccessedType();
139:            }
140:
141:            public boolean isMultiple(Object parent, String name) {
142:                AccessMethod accessmethod = getAccessMethod(name);
143:                if (accessmethod == null) {
144:                    throw UniversalRuntimeException.accumulate(
145:                            new PropertyException(), "Property " + name
146:                                    + " of " + targetclass + " not found");
147:                }
148:                return accessmethod.isDenumerable();
149:            }
150:
151:            // ****** End implementation of PropertyAccessor interface.
152:            /**
153:             * Given an object to be serialised/deserialised, return a MethodAnalyser
154:             * object containing a hash of Method and Field accessors. The
155:             * <code>context</code> stores a hash of these analysers so they are only
156:             * ever computed once per context per object class analysed.
157:             * 
158:             * @param o Either an object instance to be investigated, or an object class.
159:             *          If a class is specified and no analyser is registered, a new
160:             *          object will be created using newInstance() to be queried.
161:             */
162:
163:            static MethodAnalyser constructMethodAnalyser(Class objclass,
164:                    SAXalizerMappingContext context) {
165:
166:                SAXalizerMapperEntry entry = context.mapper.byClass(objclass);
167:                try {
168:                    MethodAnalyser togo = new MethodAnalyser(objclass, entry,
169:                            context);
170:                    return togo;
171:                } catch (Exception e) {
172:                    throw UniversalRuntimeException.accumulate(e,
173:                            "Error constructing method analyser for "
174:                                    + objclass);
175:                }
176:            }
177:
178:            public static PropertyAccessor getPropertyAccessor(Object o,
179:                    SAXalizerMappingContext context) {
180:                if (o instanceof  BeanLocator) {
181:                    return BeanLocatorPropertyAccessor.instance;
182:                } else if (o instanceof  Map) {
183:                    return MapPropertyAccessor.instance;
184:                } else if (IndexedPropertyAccessor.isIndexed(o.getClass())) {
185:                    return context.getIndexedPropertyAccessor();
186:                } else
187:                    return context.getAnalyser(o.getClass());
188:            }
189:
190:            private void condenseMethods(SAMSList existingmethods,
191:                    Enumeration newmethods, String xmlform) {
192:                while (newmethods.hasMoreElements()) {
193:                    SAXAccessMethodSpec nextentry = (SAXAccessMethodSpec) newmethods
194:                            .nextElement();
195:                    // fuse together any pairs of methods that refer to the same tag/property
196:                    // name(xmlname)
197:                    // as getters and setters.
198:                    if (nextentry.xmlform.equals(xmlform)) {
199:                        SAXAccessMethodSpec previous = existingmethods
200:                                .byXMLName(nextentry.xmlname);
201:                        if (previous != null) {
202:                            SAXAccessMethodSpec setmethod = null;
203:                            if (previous.setmethodname != null)
204:                                setmethod = previous;
205:                            if (nextentry.setmethodname != null) {
206:                                if (setmethod != null) {
207:                                    throw new UniversalRuntimeException(
208:                                            "Duplicate set method specification for tag "
209:                                                    + previous.xmlname
210:                                                    + " with java type "
211:                                                    + previous.clazz);
212:                                }
213:                                setmethod = nextentry;
214:                                previous.setmethodname = nextentry.setmethodname;
215:                            }
216:                            if (setmethod == null) {
217:                                throw new UniversalRuntimeException(
218:                                        "Neither of specifications " + previous
219:                                                + " and " + nextentry
220:                                                + " defines a set method");
221:                            }
222:                            // The "set" method will in general have a more precise argument type.
223:                            previous.clazz = setmethod.clazz;
224:                            if (nextentry.getmethodname != null) {
225:                                previous.getmethodname = nextentry.getmethodname;
226:                            }
227:                        } else {
228:                            existingmethods.add(nextentry);
229:                        }
230:                    }
231:                }
232:            }
233:
234:            SAXAccessMethodSpec bodymethodspec = null;
235:
236:            public void checkBodyMethodSpec(SAXAccessMethodSpec bodymethodspec) {
237:                if (bodymethodspec.xmlform.equals(SAXAccessMethodSpec.XML_BODY)) {
238:                    if (this .bodymethodspec != null) {
239:                        throw new UniversalRuntimeException(
240:                                "Duplicate body method spec " + bodymethodspec);
241:                    }
242:                    this .bodymethodspec = bodymethodspec;
243:                }
244:            }
245:
246:            // Note that these two methods have side-effect on bodymethodspec
247:            private void absorbSAMSArray(SAXAccessMethodSpec[] setmethods,
248:                    SAMSList tagMethods, SAMSList attrMethods) {
249:                condenseMethods(tagMethods, new ArrayEnumeration(setmethods),
250:                        SAXAccessMethodSpec.XML_TAG);
251:                condenseMethods(attrMethods, new ArrayEnumeration(setmethods),
252:                        SAXAccessMethodSpec.XML_ATTRIBUTE);
253:                if (setmethods != null) {
254:                    for (int i = 0; i < setmethods.length; ++i) {
255:                        checkBodyMethodSpec(setmethods[i]);
256:                    }
257:                }
258:            }
259:
260:            private void absorbSAMSList(SAXalizerMapperEntry entry,
261:                    SAMSList tagMethods, SAMSList attrMethods) {
262:                condenseMethods(tagMethods, Collections.enumeration(entry
263:                        .getSAMSList()), SAXAccessMethodSpec.XML_TAG);
264:                condenseMethods(attrMethods, Collections.enumeration(entry
265:                        .getSAMSList()), SAXAccessMethodSpec.XML_ATTRIBUTE);
266:                for (int i = 0; i < entry.size(); ++i) {
267:                    checkBodyMethodSpec(entry.specAt(i));
268:                }
269:            }
270:
271:            /**
272:             * This constructor locates SAXAccessMethodSpec objects for objects of the
273:             * supplied class from all available static and dynamic sources, sorts them
274:             * into tag and attribute methods while condensing together set and get
275:             * specifications into single entries, and returns a MethodAnalyser object
276:             * with the specs resolved into Method and Field accessors ready for use.
277:             * 
278:             * @param objclass The class of the object to be inspected.
279:             * @param o Either the object to be inspected for accessors, or its class in
280:             *          the case construction is to be deferred until the last possible
281:             *          moment (it implements SAXalizable &c)
282:             * @param entry A SAXalizerMapperEntry object already determined from dynamic
283:             *          sources.
284:             * @param context The global mapping context.
285:             */
286:            MethodAnalyser(Class objclass, SAXalizerMapperEntry entry,
287:                    SAXalizerMappingContext context) {
288:                targetclass = objclass;
289:                bodymethodspec = null;
290:                SAMSList tagMethods = new SAMSList();
291:                SAMSList attrMethods = new SAMSList();
292:                boolean defaultinferrible = context.inferrer != null
293:                        && (context.inferrer.isDefaultInferrible(objclass) || entry != null
294:                                && entry.defaultible);
295:                // source 1: dynamic info from mapper file takes precendence
296:                if (entry != null) {
297:                    // do not absorb entry if defaultinferrible, since it will be done again
298:                    // later.
299:                    if (!defaultinferrible) {
300:                        absorbSAMSList(entry, tagMethods, attrMethods);
301:                    }
302:                } else {
303:                    if (SAXalizable.class.isAssignableFrom(objclass)
304:                            || SAXalizableAttrs.class
305:                                    .isAssignableFrom(objclass)
306:                            || DeSAXalizable.class.isAssignableFrom(objclass)
307:                            || DeSAXalizableAttrs.class
308:                                    .isAssignableFrom(objclass)) {
309:                        // this branch will become gradually more deprecated - info should move
310:                        // into mapping files or else be default.
311:                        Object o = ClassGetter.construct(objclass);
312:                        // source 2: static info from interfaces is second choice
313:                        // System.out.println("MethodAnalyser called for object "+o);
314:                        if (o instanceof  SAXalizable) {
315:                            SAXalizable so = (SAXalizable) o;
316:                            SAXAccessMethodSpec[] setMethods = so
317:                                    .getSAXSetMethods();
318:                            SAXAccessMethodSpec.convertToSetSpec(setMethods);
319:                            absorbSAMSArray(setMethods, tagMethods, attrMethods);
320:                        }
321:                        if (o instanceof  SAXalizableAttrs) { // now do the same for attributes
322:                            SAXalizableAttrs sao = (SAXalizableAttrs) o;
323:                            SAXAccessMethodSpec[] setAttrMethods = sao
324:                                    .getSAXSetAttrMethods();
325:                            if (setAttrMethods != null) {
326:                                Logger.println("MethodAnalyser found "
327:                                        + setAttrMethods.length
328:                                        + " setattr methods for "
329:                                        + o.getClass(),
330:                                        Logger.DEBUG_INFORMATIONAL);
331:                            }
332:                            SAXAccessMethodSpec
333:                                    .convertToAttrSpec(setAttrMethods);
334:                            SAXAccessMethodSpec
335:                                    .convertToSetSpec(setAttrMethods);
336:                            absorbSAMSArray(setAttrMethods, tagMethods,
337:                                    attrMethods);
338:                        }
339:                        if (o instanceof  DeSAXalizable) {
340:                            // construct array of SAXAccessMethods for DeSAXalizable objects
341:                            DeSAXalizable doz = (DeSAXalizable) o;
342:                            SAXAccessMethodSpec[] getMethods = doz
343:                                    .getSAXGetMethods();
344:                            absorbSAMSArray(getMethods, tagMethods, attrMethods);
345:                        }
346:                        if (o instanceof  DeSAXalizableAttrs) { // now do the same for
347:                            // attributes
348:                            DeSAXalizableAttrs sao = (DeSAXalizableAttrs) o;
349:                            SAXAccessMethodSpec[] getAttrMethods = sao
350:                                    .getSAXGetAttrMethods();
351:                            if (getAttrMethods != null) {
352:                                SAXAccessMethodSpec
353:                                        .convertToAttrSpec(getAttrMethods);
354:                                Logger.println("MethodAnalyser found "
355:                                        + getAttrMethods.length
356:                                        + " getattr methods for " + o,
357:                                        Logger.DEBUG_INFORMATIONAL);
358:                            }
359:                            absorbSAMSArray(getAttrMethods, tagMethods,
360:                                    attrMethods);
361:                        }
362:                    }
363:                }
364:                // Source 3: if no accessors have so far been discovered, try to infer some
365:                // using an inferrer if one is set.
366:                if (context.inferrer != null
367:                        && (tagMethods.size() == 0 && attrMethods.size() == 0)
368:                        || defaultinferrible) {
369:                    entry = context.inferrer.inferEntry(objclass, entry);
370:                    absorbSAMSList(entry, tagMethods, attrMethods);
371:                }
372:
373:                tagmethods = new SAXAccessMethodHash(tagMethods, objclass);
374:                attrmethods = new SAXAccessMethodHash(attrMethods, objclass);
375:                if (bodymethodspec != null) {
376:                    bodymethod = new SAXAccessMethod(bodymethodspec, objclass);
377:                }
378:                bodymethodspec = null;
379:                assembleGetters();
380:            }
381:
382:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.