Source Code Cross Referenced for BoundClass.java in  » XML » jibx-1.1.5 » org » jibx » binding » classes » 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 » XML » jibx 1.1.5 » org.jibx.binding.classes 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2003-2005, Dennis M. Sosnoski All rights reserved.
003:         * 
004:         * Redistribution and use in source and binary forms, with or without
005:         * modification, are permitted provided that the following conditions are met:
006:         * 
007:         * Redistributions of source code must retain the above copyright notice, this
008:         * list of conditions and the following disclaimer. Redistributions in binary
009:         * form must reproduce the above copyright notice, this list of conditions and
010:         * the following disclaimer in the documentation and/or other materials provided
011:         * with the distribution. Neither the name of JiBX nor the names of its
012:         * contributors may be used to endorse or promote products derived from this
013:         * software without specific prior written permission.
014:         * 
015:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
016:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
017:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
018:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
019:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
020:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
021:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
022:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
023:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
024:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
025:         * POSSIBILITY OF SUCH DAMAGE.
026:         */
027:
028:        package org.jibx.binding.classes;
029:
030:        import java.io.File;
031:        import java.util.HashMap;
032:
033:        import org.apache.bcel.Constants;
034:        import org.apache.bcel.classfile.Utility;
035:        import org.apache.bcel.generic.Type;
036:
037:        import org.jibx.binding.def.BindingDefinition;
038:        import org.jibx.runtime.JiBXException;
039:
040:        /**
041:         * Bound class handler. Each instance controls and organizes information for a
042:         * class included in one or more binding definitions.
043:         * 
044:         * @author Dennis M. Sosnoski
045:         * @version 1.0
046:         */
047:
048:        public class BoundClass {
049:            //
050:            // Constants and such related to code generation.
051:
052:            /** Class used for code munging when no specific class available. */
053:            private static final String GENERIC_MUNGE_CLASS = BindingDefinition.GENERATE_PREFIX
054:                    + "MungeAdapter";
055:
056:            /** Prefix used for access methods. */
057:            private static final String ACCESS_PREFIX = BindingDefinition.GENERATE_PREFIX
058:                    + "access_";
059:
060:            /** Empty argument type array. */
061:            private static final Type[] EMPTY_TYPE_ARGS = {};
062:
063:            //
064:            // Static data.
065:
066:            /**
067:             * Map from bound class name (or bound and munged combination) to binding
068:             * information.
069:             */
070:            private static HashMap s_nameMap;
071:
072:            /** Package of first modifiable class. */
073:            private static String s_modifyPackage;
074:
075:            /** Root for package of first modifiable class. */
076:            private static File s_modifyRoot;
077:
078:            /** Class used for code generation proxy with unmodifiable classes. */
079:            private static MungedClass s_genericMunge;
080:
081:            //
082:            // Actual instance data.
083:
084:            /** Bound class file information. */
085:            private final ClassFile m_boundClass;
086:
087:            /** Class receiving code generated for target class. */
088:            private final MungedClass m_mungedClass;
089:
090:            /**
091:             * Map from field or method to load access method (lazy create,
092:             * <code>null</code> if not used).
093:             */
094:            private HashMap m_loadMap;
095:
096:            /**
097:             * Map from field or method to store access method (lazy create,
098:             * <code>null</code> if not used).
099:             */
100:            private HashMap m_storeMap;
101:
102:            /**
103:             * Constructor.
104:             * 
105:             * @param bound target class file information
106:             * @param munge class file for class hosting generated code
107:             */
108:
109:            private BoundClass(ClassFile bound, MungedClass munge) {
110:                m_boundClass = bound;
111:                m_mungedClass = munge;
112:            }
113:
114:            /**
115:             * Get bound class file information.
116:             * 
117:             * @return class file information for bound class
118:             */
119:
120:            public ClassFile getClassFile() {
121:                return m_boundClass;
122:            }
123:
124:            /**
125:             * Get bound class file name.
126:             * 
127:             * @return name of bound class
128:             */
129:
130:            public String getClassName() {
131:                return m_boundClass.getName();
132:            }
133:
134:            /**
135:             * Get munged class file information.
136:             * 
137:             * @return class file information for class being modified
138:             */
139:
140:            public ClassFile getMungedFile() {
141:                return m_mungedClass.getClassFile();
142:            }
143:
144:            /**
145:             * Check if class being changed directly.
146:             * 
147:             * @return <code>true</code> if bound class is being modified,
148:             * <code>false</code> if using a surrogate
149:             */
150:
151:            public boolean isDirectAccess() {
152:                return m_boundClass == m_mungedClass.getClassFile();
153:            }
154:
155:            /**
156:             * Get load access method for member of this class. If the access method
157:             * does not already exist it's created by this call. If the access method
158:             * does exist but without access from the context class, the access
159:             * permission on the method is broadened (from package to protected or
160:             * public, or from protected to public).
161:             * 
162:             * @param item field or method to be accessed
163:             * @param from context class from which access is required
164:             * @return the item itself if it's accessible from the required context, an
165:             * access method that is accessible if the item is not itself
166:             * @throws JiBXException on configuration error
167:             */
168:
169:            public ClassItem getLoadMethod(ClassItem item, ClassFile from)
170:                    throws JiBXException {
171:
172:                // initialize tracking information for access methods if first time
173:                if (m_loadMap == null) {
174:                    m_loadMap = new HashMap();
175:                }
176:
177:                // check if a new access method needed
178:                BindingMethod method = (BindingMethod) m_loadMap.get(item);
179:                if (method == null) {
180:
181:                    // set up for constructing new method
182:                    String name = ACCESS_PREFIX + "load_" + item.getName();
183:                    ClassFile cf = item.getClassFile();
184:                    Type type = Type.getType(Utility.getSignature(item
185:                            .getTypeName()));
186:                    MethodBuilder mb = new ExceptionMethodBuilder(name, type,
187:                            EMPTY_TYPE_ARGS, cf, (short) 0);
188:
189:                    // add the actual access method code
190:                    mb.appendLoadLocal(0);
191:                    if (item.isMethod()) {
192:                        mb.addMethodExceptions(item);
193:                        mb.appendCall(item);
194:                    } else {
195:                        mb.appendGetField(item);
196:                    }
197:                    mb.appendReturn(type);
198:
199:                    // track unique instance of this method
200:                    method = m_mungedClass.getUniqueMethod(mb, true);
201:                    m_loadMap.put(item, method);
202:                }
203:
204:                // make sure method is accessible
205:                method.makeAccessible(from);
206:                return method.getItem();
207:            }
208:
209:            /**
210:             * Get store access method for member of this class. If the access method
211:             * does not already exist it's created by this call. If the access method
212:             * does exist but without access from the context class, the access
213:             * permission on the method is broadened (from package to protected or
214:             * public, or from protected to public).
215:             * 
216:             * @param item field or method to be accessed
217:             * @param from context class from which access is required
218:             * @return the item itself if it's accessible from the required context, an
219:             * access method that is accessible if the item is not itself
220:             * @throws JiBXException on configuration error
221:             */
222:
223:            public ClassItem getStoreMethod(ClassItem item, ClassFile from)
224:                    throws JiBXException {
225:
226:                // initialize tracking information for access methods if first time
227:                if (m_storeMap == null) {
228:                    m_storeMap = new HashMap();
229:                }
230:
231:                // check if a new access method needed
232:                BindingMethod method = (BindingMethod) m_storeMap.get(item);
233:                if (method == null) {
234:
235:                    // set up for constructing new method
236:                    String name = ACCESS_PREFIX + "store_" + item.getName();
237:                    ClassFile cf = item.getClassFile();
238:                    Type type;
239:                    if (item.isMethod()) {
240:                        String sig = item.getSignature();
241:                        int start = sig.indexOf('(');
242:                        int end = sig.indexOf(')');
243:                        type = Type.getType(sig.substring(start + 1, end));
244:                    } else {
245:                        type = Type.getType(Utility.getSignature(item
246:                                .getTypeName()));
247:                    }
248:                    MethodBuilder mb = new ExceptionMethodBuilder(name,
249:                            Type.VOID, new Type[] { type }, cf, (short) 0);
250:
251:                    // add the actual access method code
252:                    mb.appendLoadLocal(0);
253:                    mb.appendLoadLocal(1);
254:                    if (item.isMethod()) {
255:                        mb.addMethodExceptions(item);
256:                        mb.appendCall(item);
257:                    } else {
258:                        mb.appendPutField(item);
259:                    }
260:                    mb.appendReturn();
261:
262:                    // track unique instance of this method
263:                    method = m_mungedClass.getUniqueMethod(mb, true);
264:                    m_storeMap.put(item, method);
265:                }
266:
267:                // make sure method is accessible
268:                method.makeAccessible(from);
269:                return method.getItem();
270:            }
271:
272:            /**
273:             * Get unique method. Just delegates to the modified class handling, with
274:             * unique suffix appended to method name.
275:             * 
276:             * @param builder method to be defined
277:             * @return defined method item
278:             * @throws JiBXException on configuration error
279:             */
280:
281:            public BindingMethod getUniqueMethod(MethodBuilder builder)
282:                    throws JiBXException {
283:                return m_mungedClass.getUniqueMethod(builder, true);
284:            }
285:
286:            /**
287:             * Get unique method. Just delegates to the modified class handling. The
288:             * supplied name is used without change.
289:             * 
290:             * @param builder method to be defined
291:             * @return defined method item
292:             * @throws JiBXException on configuration error
293:             */
294:
295:            public BindingMethod getUniqueNamed(MethodBuilder builder)
296:                    throws JiBXException {
297:                return m_mungedClass.getUniqueMethod(builder, false);
298:            }
299:
300:            /**
301:             * Add binding factory to class. Makes sure that there's no surrogate class
302:             * for code generation, then delegates to the modified class handling.
303:             * 
304:             * @param fact binding factory name
305:             */
306:
307:            public void addFactory(String fact) {
308:                if (isDirectAccess()) {
309:                    m_mungedClass.addFactory(fact);
310:                } else {
311:                    throw new IllegalStateException(
312:                            "Internal error: not directly modifiable class");
313:                }
314:            }
315:
316:            /**
317:             * Generate factory list. Makes sure that there's no surrogate class for
318:             * code generation, then delegates to the modified class handling.
319:             * 
320:             * @throws JiBXException on configuration error
321:             */
322:
323:            public void setFactoryList() throws JiBXException {
324:                if (isDirectAccess()) {
325:                    m_mungedClass.setFactoryList();
326:                } else {
327:                    throw new IllegalStateException(
328:                            "Internal error: not directly modifiable class");
329:                }
330:            }
331:
332:            /**
333:             * Create binding information for class. This creates the combination of
334:             * bound class and (if different) munged class and adds it to the internal
335:             * tables.
336:             * 
337:             * @param key text identifier for this bound class and munged class
338:             * combination
339:             * @param bound class information for bound class
340:             * @param munge information for surrogate class receiving generated code, or
341:             * <code>null</code> if no separate class
342:             * @return binding information for class
343:             */
344:
345:            private static BoundClass createInstance(String key,
346:                    ClassFile bound, MungedClass munge) {
347:                BoundClass inst = new BoundClass(bound, munge);
348:                s_nameMap.put(key, inst);
349:                return inst;
350:            }
351:
352:            /**
353:             * Find or create binding information for class. If the combination of bound
354:             * class and munged class already exists it's returned directly, otherwise
355:             * it's created and returned.
356:             * 
357:             * @param bound class information for bound class
358:             * @param munge information for surrogate class receiving generated code
359:             * @return binding information for class
360:             */
361:
362:            private static BoundClass findOrCreateInstance(ClassFile bound,
363:                    MungedClass munge) {
364:                String key = bound.getName() + ':'
365:                        + munge.getClassFile().getName();
366:                BoundClass inst = (BoundClass) s_nameMap.get(key);
367:                if (inst == null) {
368:                    inst = createInstance(key, bound, munge);
369:                }
370:                return inst;
371:            }
372:
373:            /**
374:             * Get binding information for class. This finds the class in which code
375:             * generation for the target class takes place. Normally this class will be
376:             * the target class itself, but in cases where the target class is not
377:             * modifiable an alternate class will be used. This can take two forms. If
378:             * the context class is provided and it is a subclass of the target class,
379:             * code for the target class is instead added to the context class. If there
380:             * is no context class, or if the context class is not a subclass of the
381:             * target class, a unique catch-all class is used.
382:             * 
383:             * @param cf bound class information
384:             * @param context context class for code generation, or <code>null</code>
385:             * if no context
386:             * @return binding information for class
387:             * @throws JiBXException on configuration error
388:             */
389:
390:            public static BoundClass getInstance(ClassFile cf,
391:                    BoundClass context) throws JiBXException {
392:
393:                // check if new instance needed for this class
394:                BoundClass inst = (BoundClass) s_nameMap.get(cf.getName());
395:                if (inst == null) {
396:
397:                    // load the basic class information and check for modifiable
398:                    if (!cf.isInterface() && cf.isModifiable()) {
399:
400:                        // return instance directly
401:                        inst = createInstance(cf.getName(), cf, MungedClass
402:                                .getInstance(cf));
403:
404:                    } else {
405:
406:                        // see if the context class is a subclass
407:                        if (context != null
408:                                && context.getClassFile().isSuperclass(
409:                                        cf.getName())) {
410:
411:                            // find or create munge with subclass as surrogate
412:                            inst = findOrCreateInstance(cf,
413:                                    context.m_mungedClass);
414:
415:                        } else {
416:
417:                            // use catch-all munge class as surrogate for all else
418:                            if (s_genericMunge == null) {
419:                                String mname;
420:                                if (s_modifyPackage == null) {
421:                                    mname = GENERIC_MUNGE_CLASS;
422:                                    MungedClass
423:                                            .checkDirectory(s_modifyRoot, "");
424:                                } else {
425:                                    mname = s_modifyPackage + '.'
426:                                            + GENERIC_MUNGE_CLASS;
427:                                    MungedClass.checkDirectory(s_modifyRoot,
428:                                            s_modifyPackage);
429:                                }
430:                                ClassFile base = ClassCache
431:                                        .getClassFile("java.lang.Object");
432:                                int acc = Constants.ACC_PUBLIC
433:                                        | Constants.ACC_ABSTRACT;
434:                                ClassFile gen = new ClassFile(mname,
435:                                        s_modifyRoot, base, acc, new String[0]);
436:                                gen.addDefaultConstructor();
437:                                s_genericMunge = MungedClass.getInstance(gen);
438:                                MungedClass.delayedAddUnique(gen);
439:                            }
440:                            inst = findOrCreateInstance(cf, s_genericMunge);
441:
442:                        }
443:                    }
444:                }
445:                return inst;
446:            }
447:
448:            /**
449:             * Get binding information for class. This version takes a fully-qualified
450:             * class name, calling the paired method if necessary to create a new
451:             * instance.
452:             * 
453:             * @param name fully qualified name of bound class
454:             * @param context context class for code generation, or <code>null</code>
455:             * if no context
456:             * @return binding information for class
457:             * @throws JiBXException on configuration error
458:             */
459:
460:            public static BoundClass getInstance(String name, BoundClass context)
461:                    throws JiBXException {
462:
463:                // check if new instance needed for this class
464:                BoundClass inst = (BoundClass) s_nameMap.get(name);
465:                if (inst == null) {
466:                    ClassFile cf = ClassCache.getClassFile(name);
467:                    return getInstance(cf, context);
468:                }
469:                return inst;
470:            }
471:
472:            /**
473:             * Discard cached information and reset in preparation for a new binding
474:             * run.
475:             */
476:
477:            public static void reset() {
478:                s_nameMap = new HashMap();
479:                s_modifyPackage = null;
480:                s_modifyRoot = null;
481:                s_genericMunge = null;
482:            }
483:
484:            /**
485:             * Discard cached information and reset in preparation for a new binding
486:             * run.
487:             */
488:
489:            public static void setModify(File root, String pkg) {
490:                s_modifyRoot = root;
491:                s_modifyPackage = pkg;
492:                if (s_modifyPackage.length() == 0) {
493:                    s_modifyPackage = null;
494:                }
495:            }
496:
497:            /**
498:             * Derive generated class name for bound class. This generates a JiBX class
499:             * name from the name of this class, using the supplied prefix and suffix
500:             * information. The derived class name is always in the same package as the
501:             * munged class for this class.
502:             * 
503:             * @param prefix generated class name prefix
504:             * @param suffix generated class name suffix
505:             * @return derived class name
506:             */
507:
508:            public String deriveClassName(String prefix, String suffix) {
509:                String pack = m_mungedClass.getClassFile().getPackage();
510:                if (pack.length() > 0) {
511:                    pack += '.';
512:                }
513:                String tname = m_boundClass.getName();
514:                int split = tname.lastIndexOf('.');
515:                if (split >= 0) {
516:                    tname = tname.substring(split + 1);
517:                }
518:                return pack + prefix + tname + suffix;
519:            }
520:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.