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


001:        /*
002:        Copyright (c) 2003-2004, Dennis M. Sosnoski
003:        All rights reserved.
004:
005:        Redistribution and use in source and binary forms, with or without modification,
006:        are permitted provided that the following conditions are met:
007:
008:         * Redistributions of source code must retain the above copyright notice, this
009:           list of conditions and the following disclaimer.
010:         * Redistributions in binary form must reproduce the above copyright notice,
011:           this list of conditions and the following disclaimer in the documentation
012:           and/or other materials provided with the distribution.
013:         * Neither the name of JiBX nor the names of its contributors may be used
014:           to endorse or promote products derived from this software without specific
015:           prior written permission.
016:
017:        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018:        ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019:        WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020:        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021:        ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022:        (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023:        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024:        ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025:        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026:        SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027:         */
028:
029:        package org.jibx.binding.def;
030:
031:        import org.apache.bcel.Constants;
032:        import org.apache.bcel.generic.*;
033:
034:        import org.jibx.binding.classes.*;
035:        import org.jibx.runtime.JiBXException;
036:        import org.jibx.runtime.Utility;
037:
038:        /**
039:         * Binding modifiers that apply to a class reference. This adds the methods used
040:         * for handling binding operations to the object class, then generates calls to
041:         * the added methods as this binding definition is used.
042:         *
043:         * @author Dennis M. Sosnoski
044:         * @version 1.0
045:         */
046:
047:        public class ObjectBinding extends PassThroughComponent implements 
048:                IComponent, IContextObj {
049:            //
050:            // Constants and such related to code generation.
051:
052:            // recognized marshal hook method (pre-get) signatures.
053:            private static final String[] MARSHAL_HOOK_SIGNATURES = {
054:                    "(Lorg/jibx/runtime/IMarshallingContext;)V",
055:                    "(Ljava/lang/Object;)V", "()V" };
056:
057:            // recognized factory hook method signatures.
058:            private static final String[] FACTORY_HOOK_SIGNATURES = {
059:                    "(Lorg/jibx/runtime/IUnmarshallingContext;)",
060:                    "(Ljava/lang/Object;)", "()" };
061:
062:            // recognized unmarshal hook method (pre-set, post-set) signatures.
063:            private static final String[] UNMARSHAL_HOOK_SIGNATURES = {
064:                    "(Lorg/jibx/runtime/IUnmarshallingContext;)V",
065:                    "(Ljava/lang/Object;)V", "()V" };
066:
067:            // definitions used in generating calls to user defined methods
068:            private static final String UNMARSHAL_GETSTACKTOPMETHOD = "org.jibx.runtime.impl.UnmarshallingContext.getStackTop";
069:            private static final String MARSHAL_GETSTACKTOPMETHOD = "org.jibx.runtime.impl.MarshallingContext.getStackTop";
070:            private static final String GETSTACKTOP_SIGNATURE = "()Ljava/lang/Object;";
071:            private static final String MARSHALLING_CONTEXT = "org.jibx.runtime.impl.MarshallingContext";
072:            private static final String UNMARSHALLING_CONTEXT = "org.jibx.runtime.impl.UnmarshallingContext";
073:            private static final String UNMARSHAL_PARAMETER_SIGNATURE = "(Lorg/jibx/runtime/impl/UnmarshallingContext;)";
074:            private static final String UNMARSHAL_PUSHOBJECTMETHOD = "org.jibx.runtime.impl.UnmarshallingContext.pushObject";
075:            private static final String UNMARSHAL_PUSHTRACKEDOBJECTMETHOD = "org.jibx.runtime.impl.UnmarshallingContext.pushTrackedObject";
076:            private static final String MARSHAL_PUSHOBJECTMETHOD = "org.jibx.runtime.impl.MarshallingContext.pushObject";
077:            private static final String PUSHOBJECT_SIGNATURE = "(Ljava/lang/Object;)V";
078:            private static final String UNMARSHAL_POPOBJECTMETHOD = "org.jibx.runtime.impl.UnmarshallingContext.popObject";
079:            private static final String MARSHAL_POPOBJECTMETHOD = "org.jibx.runtime.impl.MarshallingContext.popObject";
080:            private static final String POPOBJECT_SIGNATURE = "()V";
081:
082:            // definitions for methods added to mapped class
083:            private static final String NEWINSTANCE_SUFFIX = "_newinstance";
084:            private static final String UNMARSHAL_ATTR_SUFFIX = "_unmarshalAttr";
085:            private static final String MARSHAL_ATTR_SUFFIX = "_marshalAttr";
086:            private static final String UNMARSHAL_SUFFIX = "_unmarshal";
087:            private static final String MARSHAL_SUFFIX = "_marshal";
088:
089:            // definitions for source position tracking
090:            private static final String SOURCE_TRACKING_INTERFACE = "org.jibx.runtime.impl.ITrackSourceImpl";
091:            private static final String SETSOURCE_METHODNAME = "jibx_setSource";
092:            private static final Type[] SETSOURCE_ARGS = { Type.STRING,
093:                    Type.INT, Type.INT };
094:            private static final String SOURCEDOCUMENT_FIELDNAME = "jibx_sourceDocument";
095:            private static final String SOURCELINE_FIELDNAME = "jibx_sourceLine";
096:            private static final String SOURCECOLUMN_FIELDNAME = "jibx_sourceColumn";
097:            private static final String SOURCENAME_METHODNAME = "jibx_getDocumentName";
098:            private static final String SOURCELINE_METHODNAME = "jibx_getLineNumber";
099:            private static final String SOURCECOLUMN_METHODNAME = "jibx_getColumnNumber";
100:            private static final Type[] EMPTY_ARGS = {};
101:
102:            //
103:            // Actual instance data.
104:
105:            /** Containing binding definition structure. */
106:            private final IContainer m_container;
107:
108:            /** Class linked to mapping. */
109:            private BoundClass m_class;
110:
111:            /** Object factory method. */
112:            private final ClassItem m_factoryMethod;
113:
114:            /** Preset method for object. */
115:            private final ClassItem m_preSetMethod;
116:
117:            /** Postset method for object. */
118:            private final ClassItem m_postSetMethod;
119:
120:            /** Preget method for object. */
121:            private final ClassItem m_preGetMethod;
122:
123:            /** Type to be used for creating new instances. */
124:            private final ClassFile m_createClass;
125:
126:            /** Generated new instance method. */
127:            private ClassItem m_newInstanceMethod;
128:
129:            /** Flag for recursion while generating attribute unmarshal. */
130:            private boolean m_lockAttributeUnmarshal;
131:
132:            /** Flag for recursion while generating attribute marshal. */
133:            private boolean m_lockAttributeMarshal;
134:
135:            /** Flag for recursion while generating attribute unmarshal. */
136:            private boolean m_lockContentUnmarshal;
137:
138:            /** Flag for recursion while generating attribute marshal. */
139:            private boolean m_lockContentMarshal;
140:
141:            /** Signature used for unmarshal methods. */
142:            private String m_unmarshalSignature;
143:
144:            /** Name for unmarshal attribute method (<code>null</code> unless
145:             generation started). */
146:            private String m_unmarshalAttributeName;
147:
148:            /** Name for  unmarshal content method (<code>null</code> unless
149:             generation started). */
150:            private String m_unmarshalContentName;
151:
152:            /** Flag for static unmarshal methods. */
153:            private boolean m_isStaticUnmarshal;
154:
155:            /** Flag for static marshal methods. */
156:            private boolean m_isStaticMarshal;
157:
158:            /** Signature used for marshal methods. */
159:            private String m_marshalSignature;
160:
161:            /** Name for  marshal attribute method (<code>null</code> unless
162:             generation started). */
163:            private String m_marshalAttributeName;
164:
165:            /** Name for  marshal content method (<code>null</code> unless
166:             generation istarted). */
167:            private String m_marshalContentName;
168:
169:            /** Generated unmarshal attribute method. */
170:            private ClassItem m_unmarshalAttributeMethod;
171:
172:            /** Generated unmarshal content method. */
173:            private ClassItem m_unmarshalContentMethod;
174:
175:            /** Generated marshal attribute method. */
176:            private ClassItem m_marshalAttributeMethod;
177:
178:            /** Generated marshal content method. */
179:            private ClassItem m_marshalContentMethod;
180:
181:            /** Child supplying instance identifier value. */
182:            private IComponent m_idChild;
183:
184:            /** Flag for "this" reference, meaning that there's no separate object
185:             * instance created. */
186:            private boolean m_isThisBinding;
187:
188:            /**
189:             * Constructor. This initializes the definition context to be the same as
190:             * the parent's. Subclasses may change this definition context if
191:             * appropriate.
192:             *
193:             * @param contain containing binding definition component
194:             * @param objc current object context
195:             * @param type fully qualified class name for bound object
196:             * @param fact user new instance factory method
197:             * @param pres user preset method for unmarshalling
198:             * @param posts user postset method for unmarshalling
199:             * @param pget user preget method for marshalling
200:             * @param ctype type to use for creating new instance (<code>null</code> if
201:             * not specified)
202:             * @throws JiBXException if method not found
203:             */
204:            public ObjectBinding(IContainer contain, IContextObj objc,
205:                    String type, String fact, String pres, String posts,
206:                    String pget, String ctype) throws JiBXException {
207:
208:                // initialize the basics
209:                m_container = contain;
210:                BoundClass ctxc = (objc == null) ? null : objc.getBoundClass();
211:                m_class = BoundClass.getInstance(type, ctxc);
212:                ClassFile cf = m_class.getClassFile();
213:                if (ctype == null) {
214:                    m_createClass = cf;
215:                } else {
216:                    m_createClass = ClassCache.getClassFile(ctype);
217:                }
218:
219:                // check instance creation for unmarshalling
220:                if (fact == null) {
221:                    m_factoryMethod = null;
222:                } else {
223:
224:                    // look up supplied static factory method
225:                    int split = fact.lastIndexOf('.');
226:                    if (split >= 0) {
227:
228:                        // verify the method is defined
229:                        String cname = fact.substring(0, split);
230:                        String mname = fact.substring(split + 1);
231:                        ClassFile mcf = ClassCache.getClassFile(cname);
232:                        m_factoryMethod = mcf.getMethod(mname,
233:                                FACTORY_HOOK_SIGNATURES);
234:                        if (m_factoryMethod == null) {
235:                            throw new JiBXException("Factory method " + fact
236:                                    + " not found");
237:                        } else {
238:
239:                            // force access if necessary
240:                            m_factoryMethod.makeAccessible(cf);
241:
242:                        }
243:                    } else {
244:                        m_factoryMethod = null;
245:                    }
246:                    if (m_factoryMethod == null) {
247:                        throw new JiBXException("Factory method " + fact
248:                                + " not found.");
249:                    }
250:                }
251:
252:                // look up other method names as members of class
253:                if (pres == null) {
254:                    m_preSetMethod = null;
255:                } else {
256:                    m_preSetMethod = cf.getMethod(pres,
257:                            UNMARSHAL_HOOK_SIGNATURES);
258:                    if (m_preSetMethod == null) {
259:                        throw new JiBXException("User method " + pres
260:                                + " not found.");
261:                    }
262:                }
263:                if (posts == null) {
264:                    m_postSetMethod = null;
265:                } else {
266:                    m_postSetMethod = cf.getMethod(posts,
267:                            UNMARSHAL_HOOK_SIGNATURES);
268:                    if (m_postSetMethod == null) {
269:                        throw new JiBXException("User method " + posts
270:                                + " not found.");
271:                    }
272:                }
273:                if (pget == null) {
274:                    m_preGetMethod = null;
275:                } else {
276:                    m_preGetMethod = cf
277:                            .getMethod(pget, MARSHAL_HOOK_SIGNATURES);
278:                    if (m_preGetMethod == null) {
279:                        throw new JiBXException("User method " + pget
280:                                + " not found.");
281:                    }
282:                }
283:            }
284:
285:            /**
286:             * Abstract binding copy constructor. This is used to create a variation of
287:             * the object binding for a mapping which will be used for "this"
288:             * references. The "this" reference handling differs only in the code
289:             * generation, where it skips adding the source tracking interfaces and
290:             * does not push an instance of the object on the marshalling or
291:             * unmarshalling stack (since the object will already be there). This method
292:             * is only to be used before code generation.
293:             * 
294:             * @param base original object binding
295:             */
296:            public ObjectBinding(ObjectBinding base) {
297:                m_container = base.m_container;
298:                m_class = base.m_class;
299:                m_factoryMethod = null;
300:                m_preSetMethod = base.m_preSetMethod;
301:                m_postSetMethod = base.m_postSetMethod;
302:                m_preGetMethod = base.m_preGetMethod;
303:                m_createClass = base.m_createClass;
304:                m_idChild = base.m_idChild;
305:                m_component = base.m_component;
306:                m_isThisBinding = true;
307:            }
308:
309:            /**
310:             * Copy constructor. This is used in handling abstract mappings, where the
311:             * properties of the mapping definition object binding need to be copied for
312:             * each use of that binding.
313:             * 
314:             * @param contain binding definition component containing copy
315:             */
316:            public ObjectBinding(IContainer contain, ObjectBinding base) {
317:                m_container = contain;
318:                m_class = base.m_class;
319:                m_factoryMethod = base.m_factoryMethod;
320:                m_preSetMethod = base.m_preSetMethod;
321:                m_postSetMethod = base.m_postSetMethod;
322:                m_preGetMethod = base.m_preGetMethod;
323:                m_newInstanceMethod = base.m_newInstanceMethod;
324:                m_unmarshalSignature = base.m_unmarshalSignature;
325:                m_unmarshalAttributeName = base.m_unmarshalAttributeName;
326:                m_unmarshalContentName = base.m_unmarshalContentName;
327:                m_isStaticUnmarshal = base.m_isStaticUnmarshal;
328:                m_isStaticMarshal = base.m_isStaticMarshal;
329:                m_marshalSignature = base.m_marshalSignature;
330:                m_marshalAttributeName = base.m_marshalAttributeName;
331:                m_marshalContentName = base.m_marshalAttributeName;
332:                m_marshalContentName = base.m_marshalContentName;
333:                m_unmarshalAttributeMethod = base.m_unmarshalAttributeMethod;
334:                m_unmarshalContentMethod = base.m_unmarshalContentMethod;
335:                m_marshalAttributeMethod = base.m_marshalAttributeMethod;
336:                m_marshalContentMethod = base.m_marshalContentMethod;
337:                m_createClass = base.m_createClass;
338:                m_idChild = base.m_idChild;
339:                m_component = base.m_component;
340:            }
341:
342:            /**
343:             * Generate code for calling a user supplied method. The object methods
344:             * support three signature variations, with no parameters, with the
345:             * marshalling or unmarshalling context, or with the owning object.
346:             *
347:             * @param in flag for unmarshalling method
348:             * @param method information for method being called
349:             * @param mb method builder for generated code
350:             */
351:
352:            private void genUserMethodCall(boolean in, ClassItem method,
353:                    ContextMethodBuilder mb) {
354:
355:                // load object reference for virtual call
356:                if (!method.isStatic()) {
357:                    mb.loadObject();
358:                }
359:
360:                // check if parameter required for call
361:                if (method.getArgumentCount() > 0) {
362:
363:                    // generate code to load context, then get containing object if
364:                    //  needed for call
365:                    mb.loadContext();
366:                    String type = method.getArgumentType(0);
367:                    if ("java.lang.Object".equals(type)) {
368:                        String name = in ? UNMARSHAL_GETSTACKTOPMETHOD
369:                                : MARSHAL_GETSTACKTOPMETHOD;
370:                        mb.appendCallVirtual(name, GETSTACKTOP_SIGNATURE);
371:                    }
372:                }
373:
374:                // generate appropriate form of call to user method
375:                mb.appendCall(method);
376:                mb.addMethodExceptions(method);
377:            }
378:
379:            /**
380:             * Generate code to create an instance of the object for this mapping. This
381:             * convenience method generates the actual code for creating an instance of
382:             * an object. The generated code leaves the created object reference on the
383:             * stack.
384:             *
385:             * @param mb method builder
386:             * @throws JiBXException if error in generating code
387:             */
388:
389:            private void genNewInstanceCode(ContextMethodBuilder mb)
390:                    throws JiBXException {
391:
392:                // check for factory supplied to create instance
393:                if (m_factoryMethod == null) {
394:                    if (m_createClass.isArray()) {
395:
396:                        // construct array instance directly with basic size
397:                        mb.appendLoadConstant(Utility.MINIMUM_GROWN_ARRAY_SIZE);
398:                        String type = m_createClass.getName();
399:                        mb.appendCreateArray(type.substring(0,
400:                                type.length() - 2));
401:
402:                    } else {
403:
404:                        // make sure we have a no argument constructor
405:                        ClassItem cons = m_createClass
406:                                .getInitializerMethod("()V");
407:                        if (cons == null) {
408:                            m_createClass.addDefaultConstructor();
409:                        } else {
410:                            cons.makeAccessible(m_class.getMungedFile());
411:                        }
412:
413:                        // no factory, so create an instance, duplicate the
414:                        //  reference, and then call the null constructor
415:                        mb.appendCreateNew(m_createClass.getName());
416:                        mb.appendDUP();
417:                        mb.appendCallInit(m_createClass.getName(), "()V");
418:
419:                    }
420:
421:                } else {
422:
423:                    // generate call to factory method
424:                    genUserMethodCall(true, m_factoryMethod, mb);
425:                    mb.appendCreateCast(m_factoryMethod.getTypeName(), m_class
426:                            .getClassName());
427:
428:                }
429:            }
430:
431:            /**
432:             * Generate call to new instance creation method for object. This
433:             * convenience method just generates code to call the generated new
434:             * instance method added to the class definition.
435:             *
436:             * @param mb method builder
437:             * @throws JiBXException if error in configuration
438:             */
439:
440:            private void genNewInstanceCall(ContextMethodBuilder mb)
441:                    throws JiBXException {
442:
443:                // check if new instance method needs to be added to class
444:                if (m_newInstanceMethod == null) {
445:
446:                    // set up for constructing new method
447:                    String name = m_container.getBindingRoot().getPrefix()
448:                            + NEWINSTANCE_SUFFIX;
449:                    String sig = UNMARSHAL_PARAMETER_SIGNATURE
450:                            + m_class.getClassFile().getSignature();
451:                    ClassFile cf = m_class.getMungedFile();
452:                    ContextMethodBuilder meth = new ContextMethodBuilder(name,
453:                            sig, cf, Constants.ACC_PUBLIC
454:                                    | Constants.ACC_STATIC, -1, m_class
455:                                    .getClassName(), 0, UNMARSHALLING_CONTEXT);
456:
457:                    // generate the code to build a new instance
458:                    genNewInstanceCode(meth);
459:
460:                    // finish method code with return of new instance
461:                    meth.appendReturn(m_class.getClassName());
462:                    m_newInstanceMethod = m_class.getUniqueMethod(meth)
463:                            .getItem();
464:                }
465:
466:                // generate code to call created new instance method
467:                mb.loadContext(UNMARSHALLING_CONTEXT);
468:                mb.appendCall(m_newInstanceMethod);
469:            }
470:
471:            /**
472:             * Generate code to handle unmarshal source location tracking. This
473:             * convenience method generates the member variables and method used to
474:             * support setting the source location, the methods used to access the
475:             * information, and also adds the appropriate interfaces to the class.
476:             *
477:             * @throws JiBXException if error in generating code
478:             */
479:
480:            private void genTrackSourceCode() throws JiBXException {
481:                ClassFile cf = m_class.getMungedFile();
482:                if (!m_isThisBinding && m_class.isDirectAccess()
483:                        && !cf.isAbstract()
484:                        && cf.addInterface(SOURCE_TRACKING_INTERFACE)) {
485:
486:                    // add position tracking fields to class
487:                    ClassItem srcname = cf.addPrivateField("java.lang.String;",
488:                            SOURCEDOCUMENT_FIELDNAME);
489:                    ClassItem srcline = cf.addPrivateField("int",
490:                            SOURCELINE_FIELDNAME);
491:                    ClassItem srccol = cf.addPrivateField("int",
492:                            SOURCECOLUMN_FIELDNAME);
493:
494:                    // add method for setting the source information
495:                    MethodBuilder mb = new ExceptionMethodBuilder(
496:                            SETSOURCE_METHODNAME, Type.VOID, SETSOURCE_ARGS,
497:                            cf, Constants.ACC_PUBLIC);
498:                    mb.appendLoadLocal(0);
499:                    mb.appendLoadLocal(1);
500:                    mb.appendPutField(srcname);
501:                    mb.appendLoadLocal(0);
502:                    mb.appendLoadLocal(2);
503:                    mb.appendPutField(srcline);
504:                    mb.appendLoadLocal(0);
505:                    mb.appendLoadLocal(3);
506:                    mb.appendPutField(srccol);
507:                    mb.appendReturn();
508:                    mb.codeComplete(false);
509:                    mb.addMethod();
510:
511:                    // add methods for getting the source information
512:                    mb = new ExceptionMethodBuilder(SOURCENAME_METHODNAME,
513:                            Type.STRING, EMPTY_ARGS, cf, Constants.ACC_PUBLIC);
514:                    mb.appendLoadLocal(0);
515:                    mb.appendGetField(srcname);
516:                    mb.appendReturn(Type.STRING);
517:                    mb.codeComplete(false);
518:                    mb.addMethod();
519:                    mb = new ExceptionMethodBuilder(SOURCELINE_METHODNAME,
520:                            Type.INT, EMPTY_ARGS, cf, Constants.ACC_PUBLIC);
521:                    mb.appendLoadLocal(0);
522:                    mb.appendGetField(srcline);
523:                    mb.appendReturn("int");
524:                    mb.codeComplete(false);
525:                    mb.addMethod();
526:                    mb = new ExceptionMethodBuilder(SOURCECOLUMN_METHODNAME,
527:                            Type.INT, EMPTY_ARGS, cf, Constants.ACC_PUBLIC);
528:                    mb.appendLoadLocal(0);
529:                    mb.appendGetField(srccol);
530:                    mb.appendReturn("int");
531:                    mb.codeComplete(false);
532:                    mb.addMethod();
533:                }
534:            }
535:
536:            /**
537:             * Construct fullly-qualified class and method name for method under
538:             * construction.
539:             * 
540:             * @param mb method to be named
541:             * @return fully-qualified class and method name
542:             */
543:            private String fullMethodName(ContextMethodBuilder mb) {
544:                return mb.getClassFile().getName() + '.' + mb.getName();
545:            }
546:
547:            /**
548:             * Construct fully-qualified class and method name for constructed method.
549:             * 
550:             * @param item method to be named
551:             * @return fully-qualified class and method name
552:             */
553:            private String fullMethodName(ClassItem item) {
554:                return item.getClassFile().getName() + '.' + item.getName();
555:            }
556:
557:            /**
558:             * Generate call to a constructed unmarshal method.
559:             * 
560:             * @param mb
561:             */
562:            private void genUnmarshalCall(String name, ContextMethodBuilder mb) {
563:                if (m_isStaticUnmarshal) {
564:                    mb.appendCallStatic(name, m_unmarshalSignature);
565:                } else {
566:                    mb.appendCallVirtual(name, m_unmarshalSignature);
567:                }
568:            }
569:
570:            /**
571:             * Generate call to a constructed marshal method.
572:             * 
573:             * @param mb
574:             */
575:            private void genMarshalCall(String name, ContextMethodBuilder mb) {
576:                if (m_isStaticMarshal) {
577:                    mb.appendCallStatic(name, m_marshalSignature);
578:                } else {
579:                    mb.appendCallVirtual(name, m_marshalSignature);
580:                }
581:            }
582:
583:            /**
584:             * Generate call to attribute unmarshal method for object. This convenience
585:             * method just generates code to call the generated unmarshal method added
586:             * to the class definition. The code generated prior to this call must have
587:             * loaded a reference to the object to be unmarshalled on the stack, and the
588:             * generated code returns the (possibly different, in the case of arrays)
589:             * object on the stack.
590:             *
591:             * @param mb method builder
592:             * @throws JiBXException if error in configuration
593:             */
594:
595:            private void genUnmarshalAttributeCall(ContextMethodBuilder mb)
596:                    throws JiBXException {
597:
598:                // check if unmarshal method needs to be added to class
599:                if (m_unmarshalAttributeMethod == null) {
600:                    if (m_unmarshalAttributeName == null) {
601:
602:                        // set up for constructing new method
603:                        String name = m_container.getBindingRoot().getPrefix()
604:                                + UNMARSHAL_ATTR_SUFFIX;
605:                        UnmarshalBuilder meth = new UnmarshalBuilder(name,
606:                                m_class.getClassFile(), m_class.getMungedFile());
607:                        m_unmarshalAttributeName = fullMethodName(meth);
608:                        m_unmarshalSignature = meth.getSignature();
609:                        m_isStaticUnmarshal = meth.isStaticMethod();
610:
611:                        // if preset method supplied add code to call it
612:                        if (m_preSetMethod != null) {
613:                            meth.loadObject();
614:                            genUserMethodCall(true, m_preSetMethod, meth);
615:                        }
616:
617:                        // push object being unmarshalled to unmarshaller stack
618:                        if (!m_isThisBinding) {
619:                            meth.loadContext();
620:                            meth.loadObject();
621:                            meth.appendCallVirtual(
622:                                    UNMARSHAL_PUSHTRACKEDOBJECTMETHOD,
623:                                    PUSHOBJECT_SIGNATURE);
624:                        }
625:
626:                        // generate the actual unmarshalling code in method
627:                        meth.loadObject();
628:                        m_component.genAttributeUnmarshal(meth);
629:
630:                        // pop object from unmarshal stack
631:                        if (!m_isThisBinding) {
632:                            meth.loadContext();
633:                            meth.appendCallVirtual(UNMARSHAL_POPOBJECTMETHOD,
634:                                    POPOBJECT_SIGNATURE);
635:                        }
636:
637:                        // if postset method supplied and no content add code to call it
638:                        if (m_postSetMethod != null && !hasContent()) {
639:                            genUserMethodCall(true, m_postSetMethod, meth);
640:                        }
641:
642:                        // finish by returning object
643:                        meth.loadObject();
644:                        meth.appendReturn(m_class.getClassFile().getName());
645:
646:                        // add method to class
647:                        if (m_lockAttributeUnmarshal) {
648:                            m_unmarshalAttributeMethod = m_class
649:                                    .getUniqueNamed(meth).getItem();
650:                        } else {
651:                            m_unmarshalAttributeMethod = m_class
652:                                    .getUniqueMethod(meth).getItem();
653:                            m_unmarshalAttributeName = fullMethodName(m_unmarshalAttributeMethod);
654:                        }
655:
656:                    } else {
657:                        m_lockAttributeUnmarshal = true;
658:                    }
659:                }
660:
661:                // generate code to call created unmarshal method
662:                mb.loadContext(UNMARSHALLING_CONTEXT);
663:                genUnmarshalCall(m_unmarshalAttributeName, mb);
664:            }
665:
666:            /**
667:             * Generate call to attribute marshal method for object. This convenience
668:             * method just generates code to call the generated marshal method added to
669:             * the class definition. The code generated prior to this call must have
670:             * loaded a reference to the object to be marshalled on the stack.
671:             *
672:             * @param mb method builder
673:             * @throws JiBXException if error in configuration
674:             */
675:
676:            private void genMarshalAttributeCall(ContextMethodBuilder mb)
677:                    throws JiBXException {
678:
679:                // check if marshal method needs to be added to class
680:                if (m_marshalAttributeMethod == null) {
681:                    if (m_marshalAttributeName == null) {
682:
683:                        // set up for constructing new method
684:                        String name = m_container.getBindingRoot().getPrefix()
685:                                + MARSHAL_ATTR_SUFFIX;
686:                        MarshalBuilder meth = new MarshalBuilder(name, m_class
687:                                .getClassFile(), m_class.getMungedFile());
688:                        m_marshalAttributeName = fullMethodName(meth);
689:                        m_marshalSignature = meth.getSignature();
690:                        m_isStaticMarshal = meth.isStaticMethod();
691:
692:                        // if preget method supplied add code to call it
693:                        if (m_preGetMethod != null) {
694:                            genUserMethodCall(false, m_preGetMethod, meth);
695:                        }
696:
697:                        // push object being marshalled to marshaller stack
698:                        if (!m_isThisBinding) {
699:                            meth.loadContext();
700:                            meth.loadObject();
701:                            meth.appendCallVirtual(MARSHAL_PUSHOBJECTMETHOD,
702:                                    PUSHOBJECT_SIGNATURE);
703:                        }
704:
705:                        // generate actual marshalling code
706:                        meth.loadContext();
707:                        m_component.genAttributeMarshal(meth);
708:
709:                        // pop object from stack
710:                        if (!m_isThisBinding) {
711:                            meth.loadContext();
712:                            meth.appendCallVirtual(MARSHAL_POPOBJECTMETHOD,
713:                                    POPOBJECT_SIGNATURE);
714:                        }
715:
716:                        // finish and add constructed method to class
717:                        meth.appendReturn();
718:                        if (m_lockAttributeMarshal) {
719:                            m_marshalAttributeMethod = m_class.getUniqueNamed(
720:                                    meth).getItem();
721:                        } else {
722:                            m_marshalAttributeMethod = m_class.getUniqueMethod(
723:                                    meth).getItem();
724:                            m_marshalAttributeName = fullMethodName(m_marshalAttributeMethod);
725:                        }
726:
727:                    } else {
728:                        m_lockAttributeMarshal = true;
729:                    }
730:                }
731:
732:                // generate code to call created marshal method
733:                //        if (!m_directAccess) {
734:                mb.loadContext(MARSHALLING_CONTEXT);
735:                //        }
736:                genMarshalCall(m_marshalAttributeName, mb);
737:            }
738:
739:            /**
740:             * Generate call to content unmarshal method for object. This convenience
741:             * method just generates code to call the generated unmarshal method added
742:             * to the class definition. The code generated prior to this call must have
743:             * loaded a reference to the object to be unmarshalled on the stack, and the
744:             * generated code returns the (possibly different, in the case of arrays)
745:             * object on the stack.
746:             *
747:             * @param mb method builder
748:             * @throws JiBXException if error in configuration
749:             */
750:
751:            private void genUnmarshalContentCall(ContextMethodBuilder mb)
752:                    throws JiBXException {
753:
754:                // check if unmarshal method needs to be added to class
755:                if (m_unmarshalContentMethod == null) {
756:                    if (m_unmarshalContentName == null) {
757:
758:                        // set up for constructing new method
759:                        String name = m_container.getBindingRoot().getPrefix()
760:                                + UNMARSHAL_SUFFIX;
761:                        UnmarshalBuilder meth = new UnmarshalBuilder(name,
762:                                m_class.getClassFile(), m_class.getMungedFile());
763:                        m_unmarshalContentName = fullMethodName(meth);
764:                        m_unmarshalSignature = meth.getSignature();
765:                        m_isStaticUnmarshal = meth.isStaticMethod();
766:
767:                        // if preset method supplied add code to call it
768:                        if (!hasAttribute() && m_preSetMethod != null) {
769:                            meth.loadObject();
770:                            genUserMethodCall(true, m_preSetMethod, meth);
771:                        }
772:
773:                        // push object being unmarshalled to unmarshaller stack
774:                        if (!m_isThisBinding) {
775:                            meth.loadContext();
776:                            meth.loadObject();
777:                            String mname = hasAttribute() ? UNMARSHAL_PUSHOBJECTMETHOD
778:                                    : UNMARSHAL_PUSHTRACKEDOBJECTMETHOD;
779:                            meth.appendCallVirtual(mname, PUSHOBJECT_SIGNATURE);
780:                        }
781:
782:                        // generate the actual unmarshalling code in method
783:                        meth.loadObject();
784:                        m_component.genContentUnmarshal(meth);
785:
786:                        // pop object from unmarshal stack
787:                        if (!m_isThisBinding) {
788:                            meth.loadContext();
789:                            meth.appendCallVirtual(UNMARSHAL_POPOBJECTMETHOD,
790:                                    POPOBJECT_SIGNATURE);
791:                        }
792:
793:                        // if postset method supplied and no attributes add code to call
794:                        if (m_postSetMethod != null) {
795:                            genUserMethodCall(true, m_postSetMethod, meth);
796:                        }
797:
798:                        // finish by returning object
799:                        meth.loadObject();
800:                        meth.appendReturn(m_class.getClassFile().getName());
801:
802:                        // add method to class
803:                        if (m_lockContentUnmarshal) {
804:                            m_unmarshalContentMethod = m_class.getUniqueNamed(
805:                                    meth).getItem();
806:                        } else {
807:                            m_unmarshalContentMethod = m_class.getUniqueMethod(
808:                                    meth).getItem();
809:                            m_unmarshalContentName = fullMethodName(m_unmarshalContentMethod);
810:                        }
811:
812:                    } else {
813:                        m_lockContentUnmarshal = true;
814:                    }
815:                }
816:
817:                // generate code to call created unmarshal method
818:                mb.loadContext(UNMARSHALLING_CONTEXT);
819:                genUnmarshalCall(m_unmarshalContentName, mb);
820:            }
821:
822:            /**
823:             * Generate call to content marshal method for object. This convenience
824:             * method just generates code to call the generated marshal method added to
825:             * the class definition. The code generated prior to this call must have
826:             * loaded a reference to the object to be marshalled on the stack.
827:             *
828:             * @param mb method builder
829:             * @throws JiBXException if error in configuration
830:             */
831:
832:            private void genMarshalContentCall(ContextMethodBuilder mb)
833:                    throws JiBXException {
834:
835:                // check if marshal method needs to be added to class
836:                if (m_marshalContentMethod == null) {
837:                    if (m_marshalContentName == null) {
838:
839:                        // set up for constructing new method
840:                        String name = m_container.getBindingRoot().getPrefix()
841:                                + MARSHAL_SUFFIX;
842:                        MarshalBuilder meth = new MarshalBuilder(name, m_class
843:                                .getClassFile(), m_class.getMungedFile());
844:                        m_marshalContentName = fullMethodName(meth);
845:                        m_marshalSignature = meth.getSignature();
846:                        m_isStaticMarshal = meth.isStaticMethod();
847:
848:                        // if preget method supplied and no attributes add code to call it
849:                        if (m_preGetMethod != null && !hasAttribute()) {
850:                            genUserMethodCall(false, m_preGetMethod, meth);
851:                        }
852:
853:                        // push object being marshalled to marshaller stack
854:                        if (!m_isThisBinding) {
855:                            meth.loadContext();
856:                            meth.loadObject();
857:                            meth.appendCallVirtual(MARSHAL_PUSHOBJECTMETHOD,
858:                                    PUSHOBJECT_SIGNATURE);
859:                        }
860:
861:                        // generate actual marshalling code
862:                        meth.loadContext();
863:                        m_component.genContentMarshal(meth);
864:
865:                        // pop object from stack
866:                        if (!m_isThisBinding) {
867:                            meth.loadContext();
868:                            meth.appendCallVirtual(MARSHAL_POPOBJECTMETHOD,
869:                                    POPOBJECT_SIGNATURE);
870:                        }
871:
872:                        // finish and add constructed method to class
873:                        meth.appendReturn();
874:                        if (m_lockContentMarshal) {
875:                            m_marshalContentMethod = m_class.getUniqueNamed(
876:                                    meth).getItem();
877:                        } else {
878:                            m_marshalContentMethod = m_class.getUniqueMethod(
879:                                    meth).getItem();
880:                            m_marshalContentName = fullMethodName(m_marshalContentMethod);
881:                        }
882:
883:                    } else {
884:                        m_lockContentMarshal = true;
885:                    }
886:                }
887:
888:                // generate code to call created marshal method
889:                mb.loadContext(MARSHALLING_CONTEXT);
890:                genMarshalCall(m_marshalContentName, mb);
891:            }
892:
893:            //
894:            // IContextObj interface method definitions
895:
896:            public BoundClass getBoundClass() {
897:                return m_class;
898:            }
899:
900:            public boolean setIdChild(IComponent child) {
901:                if (m_idChild == null) {
902:                    m_idChild = child;
903:                    return true;
904:                } else {
905:                    return false;
906:                }
907:            }
908:
909:            //
910:            // IComponent interface method definitions
911:
912:            public boolean isOptional() {
913:                return false;
914:            }
915:
916:            public void genAttributeUnmarshal(ContextMethodBuilder mb)
917:                    throws JiBXException {
918:                genUnmarshalAttributeCall(mb);
919:            }
920:
921:            public void genAttributeMarshal(ContextMethodBuilder mb)
922:                    throws JiBXException {
923:                genMarshalAttributeCall(mb);
924:            }
925:
926:            public void genContentUnmarshal(ContextMethodBuilder mb)
927:                    throws JiBXException {
928:                genUnmarshalContentCall(mb);
929:            }
930:
931:            public void genContentMarshal(ContextMethodBuilder mb)
932:                    throws JiBXException {
933:                genMarshalContentCall(mb);
934:            }
935:
936:            public void genNewInstance(ContextMethodBuilder mb)
937:                    throws JiBXException {
938:                genNewInstanceCall(mb);
939:            }
940:
941:            public String getType() {
942:                return m_class.getClassName();
943:            }
944:
945:            public boolean hasId() {
946:                return m_idChild != null;
947:            }
948:
949:            public void genLoadId(ContextMethodBuilder mb) throws JiBXException {
950:                if (m_idChild == null) {
951:                    throw new IllegalStateException(
952:                            "Internal error: no id defined");
953:                } else {
954:                    m_idChild.genLoadId(mb);
955:                }
956:            }
957:
958:            public void setLinkages() throws JiBXException {
959:                super .setLinkages();
960:                if (m_container.getBindingRoot().isTrackSource()) {
961:                    genTrackSourceCode();
962:                }
963:            }
964:
965:            // DEBUG
966:            public void print(int depth) {
967:                BindingDefinition.indent(depth);
968:                System.out.print("object binding for "
969:                        + m_class.getClassFile().getName());
970:                if (m_isThisBinding) {
971:                    System.out.print(" (\"this\" reference)");
972:                }
973:                if (m_createClass != null) {
974:                    System.out
975:                            .print(" create class " + m_createClass.getName());
976:                }
977:                System.out.println();
978:                m_component.print(depth + 1);
979:            }
980:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.