Source Code Cross Referenced for MappingDefinition.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-2007, 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 java.util.ArrayList;
032:
033:        import org.apache.bcel.Constants;
034:        import org.apache.bcel.generic.*;
035:
036:        import org.jibx.binding.classes.*;
037:        import org.jibx.runtime.JiBXException;
038:
039:        /**
040:         * Normal mapping with defined binding. This is used for a mapping definition
041:         * which includes detailed binding information (rather than marshaller and
042:         * unmarshaller classes which handle the binding directly).
043:         *
044:         * @author Dennis M. Sosnoski
045:         */
046:        public class MappingDefinition extends MappingBase {
047:            //
048:            // Constants and such related to code generation.
049:
050:            // definitions used in generating the adapter class
051:            private static final String ADAPTERCLASS_SUFFIX = "_access";
052:            private static final String MARSHAL_METHODNAME = "marshal";
053:            private static final String BASEMARSHAL_METHODNAME = "baseMarshal";
054:            private static final String UNMARSHAL_METHODNAME = "unmarshal";
055:            private static final String ISPRESENT_METHODNAME = "isPresent";
056:            private static final String UNMARSHALCONTEXT_CLASS = "org.jibx.runtime.impl.UnmarshallingContext";
057:            private static final String MARSHALCONTEXT_CLASS = "org.jibx.runtime.impl.MarshallingContext";
058:            private static final String UNMARSHAL_ISATMETHOD = "org.jibx.runtime.IUnmarshallingContext.isAt";
059:            private static final String UNMARSHAL_ISATSIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)Z";
060:            private static final String CHECKEXTENDS_METHOD = "org.jibx.runtime.IMarshaller.isExtension";
061:            private static final String GETINDEX_METHOD = "org.jibx.runtime.IMarshallable.JiBX_getIndex";
062:            private static final String UNMARSHALLERPRESENT_METHOD = "org.jibx.runtime.IUnmarshaller.isPresent";
063:            private static final String UNMARSHALLERPRESENT_SIGNATURE = "(Lorg/jibx/runtime/IUnmarshallingContext;)Z";
064:            private static final String UNMARSHALCONTEXT_INTERFACE = "org.jibx.runtime.IUnmarshallingContext";
065:            private static final String MARSHALCONTEXT_INTERFACE = "org.jibx.runtime.IMarshallingContext";
066:            private static final String CURRENTELEMENT_METHOD = "org.jibx.runtime.impl.UnmarshallingContext.currentNameString";
067:            private static final String CURRENTELEMENT_SIGNATURE = "()Ljava/lang/String;";
068:            private static final String PARSERNEXT_METHOD = "org.jibx.runtime.impl.UnmarshallingContext.next";
069:            private static final String PARSERNEXT_SIGNATURE = "()I";
070:            private static final String CLOSESTART_METHOD = "org.jibx.runtime.impl.MarshallingContext.closeStartContent";
071:            private static final String CLOSESTART_SIGNATURE = "()Lorg/jibx/runtime/impl/MarshallingContext;";
072:            private static final String ADDUNMARSHALLER_METHOD = "org.jibx.runtime.impl.UnmarshallingContext.addUnmarshalling";
073:            private static final String ADDUNMARSHALLER_SIGNATURE = "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
074:            private static final String REMOVEUNMARSHALLER_METHOD = "org.jibx.runtime.impl.UnmarshallingContext.removeUnmarshalling";
075:            private static final String REMOVEUNMARSHALLER_SIGNATURE = "(I)V";
076:            private static final String ADDMARSHALLER_METHOD = "org.jibx.runtime.impl.MarshallingContext.addMarshalling";
077:            private static final String ADDMARSHALLER_SIGNATURE = "(ILjava/lang/String;)V";
078:            private static final String REMOVEMARSHALLER_METHOD = "org.jibx.runtime.impl.MarshallingContext.removeMarshalling";
079:            private static final String REMOVEMARSHALLER_SIGNATURE = "(I)V";
080:
081:            // argument list for the unmarshaller methods
082:            private static final Type[] ISPRESENT_METHOD_ARGS = { ClassItem
083:                    .typeFromName("org.jibx.runtime.IUnmarshallingContext") };
084:            private static final Type[] UNMARSHAL_METHOD_ARGS = {
085:                    Type.OBJECT,
086:                    ClassItem
087:                            .typeFromName("org.jibx.runtime.IUnmarshallingContext") };
088:
089:            // argument list for the marshaller methods
090:            private static final Type[] MARSHAL_METHOD_ARGS = {
091:                    Type.OBJECT,
092:                    ClassItem
093:                            .typeFromName("org.jibx.runtime.IMarshallingContext") };
094:
095:            //
096:            // Data shared with other classes within package
097:
098:            // interface list for adapter with unmarshaller only
099:            /*package*/static final String[] UNMARSHALLER_INTERFACES = { UNMARSHALLER_INTERFACE };
100:
101:            // interface list for adapter with marshaller only
102:            /*package*/static final String[] MARSHALLER_INTERFACES = { MARSHALLER_INTERFACE };
103:
104:            // interface list for adapter with both unmarshaller and marshaller
105:            /*package*/static final String[] BOTH_INTERFACES = {
106:                    UNMARSHALLER_INTERFACE, MARSHALLER_INTERFACE };
107:
108:            //
109:            // Actual instance data.
110:
111:            /** Containing binding definition structure. */
112:            private final IContainer m_container;
113:
114:            /** Definition context for mapping. */
115:            private final DefinitionContext m_defContext;
116:
117:            /** Class linked to mapping. */
118:            private final BoundClass m_class;
119:
120:            /** Mapped element name (may be <code>null</code> if element(s) defined
121:             by marshaller and unmarshaller, or if abstract mapping). */
122:            private final NameDefinition m_name;
123:
124:            /** Abstract mapping flag. */
125:            private final boolean m_isAbstract;
126:
127:            /** Name of abstract base type. */
128:            private final String m_baseType;
129:
130:            /** Abstract binding this one is based on (<code>null</code> if not an
131:             extension. */
132:            private IMapping m_baseMapping;
133:
134:            /** Duplicate of component structure for use as "this" reference
135:             * (<code>null</code> if not yet defined). */
136:            private IComponent m_this Binding;
137:
138:            /** Constructed marshaller class. */
139:            private ClassFile m_marshaller;
140:
141:            /** Constructed unmarshaller class. */
142:            private ClassFile m_unmarshaller;
143:
144:            /** Mapping which extend this one (<code>null</code> if none). */
145:            private ArrayList m_extensions;
146:
147:            /** Reference type of mapping, as fully qualifed class name. */
148:            private String m_referenceType;
149:
150:            /**
151:             * Constructor. This initializes the new definition context.
152:             *
153:             * @param contain containing binding definition structure
154:             * @param defc definition context for this mapping
155:             * @param type bound class name
156:             * @param name mapped element name information (<code>null</code> if defined
157:             * by marshaller and unmarshaller)
158:             * @param tname qualified type name for abstract mapping (<code>null</code>
159:             * if none)
160:             * @param abs abstract mapping flag
161:             * @param base abstract mapping extended by this one
162:             * @param bind binding definition component
163:             * @param nillable flag for nillable element
164:             * @throws JiBXException if class definition not found
165:             */
166:            public MappingDefinition(IContainer contain,
167:                    DefinitionContext defc, String type, NameDefinition name,
168:                    String tname, boolean abs, String base, ObjectBinding bind,
169:                    boolean nillable) throws JiBXException {
170:                super (contain, type, tname);
171:                IComponent tref = new ObjectBinding(bind);
172:                if (name == null) {
173:                    setWrappedComponent(bind);
174:                } else {
175:                    setWrappedComponent(new ElementWrapper(defc, name, bind,
176:                            nillable));
177:                    tref = new ElementWrapper(defc, name, tref, nillable);
178:                }
179:                m_this Binding = tref;
180:                m_container = contain;
181:                m_defContext = defc;
182:                m_class = BoundClass.getInstance(type, null);
183:                m_referenceType = type == null ? "java.lang.Object" : type;
184:                m_name = name;
185:                m_isAbstract = abs;
186:                m_baseType = base;
187:            }
188:
189:            /**
190:             * Check if one or more namespaces are defined for element.
191:             *
192:             * @return <code>true</code> if namespaces are defined, <code>false</code>
193:             * if not
194:             */
195:            /*package*/boolean hasNamespace() {
196:                return m_defContext.hasNamespace();
197:            }
198:
199:            /**
200:             * Generate code for loading namespace index and URI arrays.
201:             *
202:             * @param mb method builder for generated code
203:             */
204:            /*package*/void genLoadNamespaces(MethodBuilder mb) {
205:                m_defContext.genLoadNamespaces(mb);
206:            }
207:
208:            /**
209:             * Get the mapped class information. This implements the method used by the
210:             * base class.
211:             *
212:             * @return information for mapped class
213:             */
214:            public BoundClass getBoundClass() {
215:                return m_class;
216:            }
217:
218:            /**
219:             * Links extension mappings to their base mappings. This must be done before
220:             * the more general linking step in order to determine which abstract
221:             * mappings are standalone and which are extended by other mappings
222:             *
223:             * @throws JiBXException if error in linking
224:             */
225:            public void linkMappings() throws JiBXException {
226:                if (m_baseType != null) {
227:                    m_baseMapping = m_defContext.getClassMapping(m_baseType);
228:                    if (m_baseMapping == null) {
229:                        throw new JiBXException("Mapping for base class "
230:                                + m_baseType + " not defined");
231:                    }
232:                    m_baseMapping.addExtension(this );
233:                }
234:                m_defContext.linkMappings();
235:            }
236:
237:            //
238:            // IMapping interface method definitions
239:
240:            public String getBoundType() {
241:                return m_class.getClassName();
242:            }
243:
244:            public String getReferenceType() {
245:                return m_referenceType;
246:            }
247:
248:            public IComponent getImplComponent() {
249:                return m_component;
250:            }
251:
252:            public ClassFile getMarshaller() {
253:                return m_marshaller;
254:            }
255:
256:            public ClassFile getUnmarshaller() {
257:                return m_unmarshaller;
258:            }
259:
260:            public NameDefinition getName() {
261:                return m_name;
262:            }
263:
264:            public void addNamespace(NamespaceDefinition ns)
265:                    throws JiBXException {
266:                m_defContext.addNamespace(ns);
267:            }
268:
269:            public boolean isAbstract() {
270:                return m_isAbstract;
271:            }
272:
273:            public boolean isBase() {
274:                return m_extensions != null && m_extensions.size() > 0;
275:            }
276:
277:            public void addExtension(MappingDefinition mdef)
278:                    throws JiBXException {
279:                if (m_extensions == null) {
280:                    m_extensions = new ArrayList();
281:                }
282:                if (!m_extensions.contains(mdef)) {
283:                    m_extensions.add(mdef);
284:                }
285:                ClassFile cf = mdef.getBoundClass().getClassFile();
286:                if (!cf.isSuperclass(m_referenceType)
287:                        && !cf.isImplements(m_referenceType)) {
288:                    m_referenceType = "java.lang.Object";
289:                }
290:            }
291:
292:            public IComponent buildRef(IContainer parent, IContextObj objc,
293:                    String type, PropertyDefinition prop) throws JiBXException {
294:                if (prop.isThis()) {
295:
296:                    // directly incorporate base mapping definition
297:                    return new BaseMappingWrapper(m_this Binding);
298:
299:                } else if (m_isAbstract && m_extensions == null) {
300:
301:                    // create reference to use mapping definition directly
302:                    ComponentProperty comp = new ComponentProperty(prop,
303:                            m_component, false);
304:                    if (!hasAttribute() && !hasContent()) {
305:                        comp.setForceUnmarshal(true);
306:                    }
307:                    return comp;
308:
309:                } else {
310:
311:                    // create link to mapping definition
312:                    DirectObject dobj = new DirectObject(m_container, null,
313:                            m_class.getClassFile(), m_isAbstract
314:                                    || m_extensions != null, m_marshaller,
315:                            m_unmarshaller, getIndex(), null);
316:                    return new DirectProperty(prop, dobj);
317:
318:                }
319:            }
320:
321:            public ArrayList getNamespaces() {
322:                return m_defContext.getNamespaces();
323:            }
324:
325:            /**
326:             * Add abstract marshaller interface to handler class. This adds the
327:             * interface and generates the {@link
328:             * org.jibx.runtime.IAbstractMarshaller#baseMarshal(Object,
329:             * org.jibx.runtime.IMarshallingContext)} method responsible for passing
330:             * handling on to the appropriate extension class.
331:             *
332:             * @param cf hanlder class
333:             * @throws JiBXException
334:             */
335:            private void generateAbstractMarshaller(ClassFile cf)
336:                    throws JiBXException {
337:
338:                // build the implementation method
339:                ContextMethodBuilder mb = new ContextMethodBuilder(
340:                        BASEMARSHAL_METHODNAME, Type.VOID, MARSHAL_METHOD_ARGS,
341:                        cf, Constants.ACC_PUBLIC | Constants.ACC_FINAL, 1,
342:                        "java.lang.Object", 2, MARSHALCONTEXT_INTERFACE);
343:                mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
344:                // TODO: optionally check for null value on object
345:                mb.loadContext();
346:                mb.loadObject(IMARSHALLABLE_INTERFACE);
347:                mb.appendCallInterface(GETINDEX_METHOD, GETINDEX_SIGNATURE);
348:                mb.loadObject();
349:                mb.appendCallVirtual("java.lang.Object.getClass",
350:                        "()Ljava/lang/Class;");
351:                mb.appendCallVirtual("java.lang.Class.getName",
352:                        "()Ljava/lang/String;");
353:                mb.appendCallInterface(GETMARSHALLER_METHOD,
354:                        GETMARSHALLER_SIGNATURE);
355:                mb.appendDUP();
356:                mb.appendLoadConstant(getIndex());
357:                mb.appendCallInterface(CHECKEXTENDS_METHOD,
358:                        CHECKEXTENDS_SIGNATURE);
359:                BranchWrapper ifvalid = mb.appendIFNE(this );
360:
361:                // generate and throw exception describing the problem
362:                mb.appendCreateNew("java.lang.StringBuffer");
363:                mb.appendDUP();
364:                mb.appendLoadConstant("Mapping for type ");
365:                mb.appendCallInit("java.lang.StringBuffer",
366:                        "(Ljava/lang/String;)V");
367:                mb.appendDUP();
368:                mb.loadObject();
369:                mb.appendCallVirtual("java.lang.Object.getClass",
370:                        "()Ljava/lang/Class;");
371:                mb.appendCallVirtual("java.lang.Class.getName",
372:                        "()Ljava/lang/String;");
373:                mb.appendCallVirtual("java.lang.StringBuffer.append",
374:                        "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
375:                mb.appendDUP();
376:                mb.appendLoadConstant(" must extend abstract mapping for "
377:                        + "type " + m_class.getClassName());
378:                mb.appendCallVirtual("java.lang.StringBuffer.append",
379:                        "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
380:                mb.appendCallVirtual("java.lang.StringBuffer.toString",
381:                        "()Ljava/lang/String;");
382:                mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
383:                mb.appendDUP_X1();
384:                mb.appendSWAP();
385:                mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS,
386:                        MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1);
387:                mb.appendThrow();
388:
389:                // for valid extension mapping, just call the marshaller
390:                mb.targetNext(ifvalid);
391:                mb.loadObject();
392:                mb.loadContext();
393:                mb.appendCallInterface(MARSHALLERMARSHAL_METHOD,
394:                        MARSHALLERMARSHAL_SIGNATURE);
395:                mb.appendReturn();
396:                mb.codeComplete(false);
397:                mb.addMethod();
398:
399:                // add extended interface to constructed class
400:                cf.addInterface(ABSTRACTMARSHALLER_INTERFACE);
401:            }
402:
403:            /**
404:             * Generate the {@link org.jibx.runtime.IMarshaller#isExtension(int)}
405:             * method to check if this mapping is extending a particular abstract
406:             * mapping.
407:             *
408:             * @param cf
409:             * @param hasname
410:             * @throws JiBXException
411:             */
412:            private void generateIfExtendingCheck(ClassFile cf, boolean hasname)
413:                    throws JiBXException {
414:
415:                // build the method
416:                ExceptionMethodBuilder xb = new ExceptionMethodBuilder(
417:                        CHECKEXTENDS_METHODNAME, CHECKEXTENDS_SIGNATURE, cf,
418:                        Constants.ACC_PUBLIC | Constants.ACC_FINAL);
419:                xb.appendLoadLocal(1);
420:                xb.appendLoadConstant(getIndex());
421:                xb.appendISUB();
422:                ArrayList ifeqs = new ArrayList();
423:                ifeqs.add(xb.appendIFEQ(this ));
424:                IMapping base = m_baseMapping;
425:                while (base != null) {
426:                    xb.appendLoadLocal(1);
427:                    xb.appendLoadConstant(base.getIndex());
428:                    xb.appendISUB();
429:                    ifeqs.add(xb.appendIFEQ(this ));
430:                    if (base instanceof  MappingDefinition) {
431:                        base = ((MappingDefinition) base).m_baseMapping;
432:                    } else {
433:                        break;
434:                    }
435:                }
436:                xb.appendICONST_0();
437:                xb.appendReturn("int");
438:                for (int i = 0; i < ifeqs.size(); i++) {
439:                    xb.targetNext((BranchWrapper) ifeqs.get(i));
440:                }
441:                xb.appendICONST_1();
442:                xb.appendReturn("int");
443:                xb.codeComplete(false);
444:                xb.addMethod();
445:            }
446:
447:            /**
448:             * Generate the {@link org.jibx.runtime.IUnmarshaller#unmarshal(Object,
449:             * org.jibx.runtime.IUnmarshallingContext)} method implementation.
450:             *
451:             * @param cf class to receive method
452:             * @param hasattr attribute definition present flag
453:             * @param hascont content definition present flag
454:             * @param hasname element name defined by this mapping flag
455:             * @throws JiBXException
456:             */
457:            private void generateUnmarshalImplementation(ClassFile cf,
458:                    boolean hasattr, boolean hascont, boolean hasname)
459:                    throws JiBXException {
460:
461:                // build the unmarshal method for item; this just generates code
462:                //  to unmarshal attributes and content, first creating an
463:                //  instance of the class if one was not passed in, then
464:                //  returning the unmarshalled instance as the value of the call
465:                String type = m_class.getClassName();
466:                ContextMethodBuilder mb = new ContextMethodBuilder(
467:                        UNMARSHAL_METHODNAME, Type.OBJECT,
468:                        UNMARSHAL_METHOD_ARGS, cf, Constants.ACC_PUBLIC
469:                                | Constants.ACC_FINAL, 1, type, 2,
470:                        UNMARSHALCONTEXT_INTERFACE);
471:                mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
472:
473:                // first part of generated code just checks if an object has
474:                //  been supplied; if it has, this can just go direct to
475:                //  unmarshalling
476:                mb.loadObject();
477:                BranchWrapper ifnnull = mb.appendIFNONNULL(this );
478:
479:                // check for extension mapping handling required
480:                if (m_extensions != null) {
481:
482:                    // generate name comparison unless an abstract mapping
483:                    BranchWrapper ifthis  = null;
484:                    if (hasname) {
485:
486:                        // test if at defined element name
487:                        mb
488:                                .addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
489:                        mb.loadContext();
490:                        m_name.genPushUriPair(mb);
491:                        mb.appendCallInterface(UNMARSHAL_ISATMETHOD,
492:                                UNMARSHAL_ISATSIGNATURE);
493:                        ifthis  = mb.appendIFNE(this );
494:                    }
495:
496:                    // build code to check each extension mapping in turn,
497:                    //  keeping an instance of the unmarshaller for the matching
498:                    //  extension
499:                    BranchWrapper[] iffounds = new BranchWrapper[m_extensions
500:                            .size()];
501:                    for (int i = 0; i < iffounds.length; i++) {
502:                        IMapping map = (IMapping) m_extensions.get(i);
503:                        mb.loadContext();
504:                        mb.appendLoadConstant(map.getIndex());
505:                        mb.appendCallInterface(GETUNMARSHALLER_METHOD,
506:                                GETUNMARSHALLER_SIGNATURE);
507:                        mb.appendDUP();
508:                        mb.loadContext();
509:                        mb.appendCallInterface(UNMARSHALLERPRESENT_METHOD,
510:                                UNMARSHALLERPRESENT_SIGNATURE);
511:                        iffounds[i] = mb.appendIFNE(this );
512:                        mb.appendPOP();
513:                    }
514:
515:                    // generate code to throw exception if no matching extension
516:                    //  found
517:                    mb.appendCreateNew("java.lang.StringBuffer");
518:                    mb.appendDUP();
519:                    mb.appendLoadConstant("Element ");
520:                    mb.appendCallInit("java.lang.StringBuffer",
521:                            "(Ljava/lang/String;)V");
522:                    mb.appendDUP();
523:                    mb.loadContext(UNMARSHALCONTEXT_CLASS);
524:                    mb.appendCallVirtual(CURRENTELEMENT_METHOD,
525:                            CURRENTELEMENT_SIGNATURE);
526:                    mb.appendCallVirtual("java.lang.StringBuffer.append",
527:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
528:                    mb.appendDUP();
529:                    mb.appendLoadConstant(" has no mapping that extends "
530:                            + m_class.getClassName());
531:                    mb.appendCallVirtual("java.lang.StringBuffer.append",
532:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
533:                    mb.appendCallVirtual("java.lang.StringBuffer.toString",
534:                            "()Ljava/lang/String;");
535:                    mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
536:                    mb.appendDUP_X1();
537:                    mb.appendSWAP();
538:                    mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS,
539:                            MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1);
540:                    mb.appendThrow();
541:                    if (iffounds.length > 0) {
542:
543:                        // finish by calling unmarshaller for extension mapping
544:                        //  found and returning the result with no further
545:                        //  processing
546:                        mb.initStackState(iffounds[0]);
547:                        BranchTarget found = mb.appendTargetACONST_NULL();
548:                        for (int i = 0; i < iffounds.length; i++) {
549:                            iffounds[i].setTarget(found, mb);
550:                        }
551:                        mb.loadContext();
552:                        mb.appendCallInterface(UNMARSHALLERUNMARSHAL_METHOD,
553:                                UNMARSHALLERUNMARSHAL_SIGNATURE);
554:                        mb.appendReturn("java.lang.Object");
555:                    }
556:
557:                    // fall into instance creation if this mapping reference
558:                    if (ifthis  != null) {
559:                        mb.targetNext(ifthis );
560:                    }
561:
562:                } else if (m_isAbstract) {
563:
564:                    // throw an exception when no instance supplied
565:                    mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
566:                    mb.appendDUP();
567:                    mb
568:                            .appendLoadConstant("Abstract mapping requires instance to "
569:                                    + "be supplied for class "
570:                                    + m_class.getClassName());
571:                    mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS,
572:                            MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1);
573:                    mb.appendThrow();
574:
575:                }
576:                if (hasname) {
577:
578:                    // just create an instance of the (non-abstract) mapped class
579:                    genNewInstance(mb);
580:                    mb.storeObject();
581:
582:                }
583:
584:                // define unmarshallings for child mappings of this mapping
585:                mb.targetNext(ifnnull);
586:                ArrayList maps = m_defContext.getMappings();
587:                if (maps != null && maps.size() > 0) {
588:                    for (int i = 0; i < maps.size(); i++) {
589:                        IMapping map = (IMapping) maps.get(i);
590:                        if (!map.isAbstract() || map.isBase()) {
591:                            mb.loadContext(UNMARSHALCONTEXT_CLASS);
592:                            mb.appendLoadConstant(map.getIndex());
593:                            NameDefinition mname = map.getName();
594:                            if (mname == null) {
595:                                mb.appendACONST_NULL();
596:                                mb.appendACONST_NULL();
597:                            } else {
598:                                map.getName().genPushUriPair(mb);
599:                            }
600:                            mb.appendLoadConstant(map.getUnmarshaller()
601:                                    .getName());
602:                            mb.appendCallVirtual(ADDUNMARSHALLER_METHOD,
603:                                    ADDUNMARSHALLER_SIGNATURE);
604:                        }
605:                    }
606:                }
607:
608:                // load object and cast to type
609:                mb.loadObject();
610:                mb.appendCreateCast(type);
611:
612:                // handle the actual unmarshalling
613:                if (hasattr) {
614:                    m_component.genAttributeUnmarshal(mb);
615:                }
616:                if (hasattr || !hasname) {
617:                    mb.loadContext(UNMARSHALCONTEXT_CLASS);
618:                    mb.appendCallVirtual(PARSERNEXT_METHOD,
619:                            PARSERNEXT_SIGNATURE);
620:                    mb.appendPOP();
621:                }
622:                if (hascont) {
623:                    m_component.genContentUnmarshal(mb);
624:                }
625:
626:                // undefine unmarshallings for child mappings of this mapping
627:                if (maps != null && maps.size() > 0) {
628:                    for (int i = 0; i < maps.size(); i++) {
629:                        IMapping map = (IMapping) maps.get(i);
630:                        if (!map.isAbstract() || map.isBase()) {
631:                            mb.loadContext(UNMARSHALCONTEXT_CLASS);
632:                            mb.appendLoadConstant(map.getIndex());
633:                            mb.appendCallVirtual(REMOVEUNMARSHALLER_METHOD,
634:                                    REMOVEUNMARSHALLER_SIGNATURE);
635:                        }
636:                    }
637:                }
638:
639:                // finish by returning unmarshalled object reference
640:                mb.appendReturn("java.lang.Object");
641:                mb.codeComplete(false);
642:                mb.addMethod();
643:
644:                // add interface if mapped class is directly unmarshallable
645:                if (hasname
646:                        && m_class.getClassFile() == m_class.getMungedFile()) {
647:                    addIUnmarshallableMethod();
648:                }
649:            }
650:
651:            /**
652:             * Generate the {@link
653:             * org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext)}
654:             * method implementation.
655:             *
656:             * @param cf class to receive method
657:             * @param hasname element name defined by this mapping flag
658:             * @throws JiBXException
659:             */
660:            private void generateIsPresent(ClassFile cf, boolean hasname)
661:                    throws JiBXException {
662:
663:                // create the method builder
664:                ContextMethodBuilder mb = new ContextMethodBuilder(
665:                        ISPRESENT_METHODNAME, Type.BOOLEAN,
666:                        ISPRESENT_METHOD_ARGS, cf, Constants.ACC_PUBLIC
667:                                | Constants.ACC_FINAL, -1, null, 1,
668:                        UNMARSHALCONTEXT_INTERFACE);
669:
670:                // generate name comparison unless an abstract mapping
671:                if (hasname) {
672:
673:                    // test if at defined element name
674:                    mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
675:                    mb.loadContext();
676:                    m_name.genPushUriPair(mb);
677:                    mb.appendCallInterface(UNMARSHAL_ISATMETHOD,
678:                            UNMARSHAL_ISATSIGNATURE);
679:                }
680:
681:                // check for extension mapping handling required
682:                if (m_extensions != null) {
683:
684:                    // return immediately if this mapping name check successful
685:                    BranchWrapper ifthis  = null;
686:                    if (hasname) {
687:                        ifthis  = mb.appendIFNE(this );
688:                    }
689:
690:                    // build code to check each extension mapping in turn;
691:                    //  return "true" if one matches, or "false" if none do
692:                    mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
693:                    BranchWrapper[] iffounds = new BranchWrapper[m_extensions
694:                            .size()];
695:                    for (int i = 0; i < iffounds.length; i++) {
696:                        IMapping map = (IMapping) m_extensions.get(i);
697:                        mb.loadContext();
698:                        mb.appendLoadConstant(map.getIndex());
699:                        mb.appendCallInterface(GETUNMARSHALLER_METHOD,
700:                                GETUNMARSHALLER_SIGNATURE);
701:                        mb.loadContext();
702:                        mb.appendCallInterface(UNMARSHALLERPRESENT_METHOD,
703:                                UNMARSHALLERPRESENT_SIGNATURE);
704:                        iffounds[i] = mb.appendIFNE(this );
705:                    }
706:                    mb.appendICONST_0();
707:                    mb.appendReturn("int");
708:                    mb.initStackState(iffounds[0]);
709:                    BranchTarget found = mb.appendTargetLoadConstant(1);
710:                    if (ifthis  != null) {
711:                        ifthis .setTarget(found, mb);
712:                    }
713:                    for (int i = 0; i < iffounds.length; i++) {
714:                        iffounds[i].setTarget(found, mb);
715:                    }
716:
717:                } else if (!hasname) {
718:
719:                    // mapping with no separate element name, just return "true"
720:                    mb.appendICONST_1();
721:
722:                }
723:                mb.appendReturn("int");
724:                mb.codeComplete(false);
725:                mb.addMethod();
726:            }
727:
728:            /**
729:             * Generate the {@link org.jibx.runtime.IMarshaller#marshal(Object,
730:             * org.jibx.runtime.IMarshallingContext)} method implementation.
731:             *
732:             * @param cf class to receive method
733:             * @param hasattr attribute definition present flag
734:             * @param hascont content definition present flag
735:             * @throws JiBXException
736:             */
737:            private void generateMarshalImplementation(ClassFile cf,
738:                    boolean hasattr, boolean hascont) throws JiBXException {
739:
740:                // build the marshal implementation method; this loads the
741:                //  passed object and casts it to the target type, then handles
742:                //  marshalling first attributes and followed by content for the
743:                //  item
744:                ContextMethodBuilder mb = new ContextMethodBuilder(
745:                        MARSHAL_METHODNAME, Type.VOID, MARSHAL_METHOD_ARGS, cf,
746:                        Constants.ACC_PUBLIC | Constants.ACC_FINAL, 1,
747:                        "java.lang.Object", 2, MARSHALCONTEXT_INTERFACE);
748:                mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
749:                // TODO: optionally check for null value on object
750:
751:                // define marshallings for child mappings of this mapping
752:                ArrayList maps = m_defContext.getMappings();
753:                if (maps != null && maps.size() > 0) {
754:                    for (int i = 0; i < maps.size(); i++) {
755:                        IMapping map = (IMapping) maps.get(i);
756:                        if (!map.isAbstract() || map.isBase()) {
757:                            mb.loadContext(MARSHALCONTEXT_CLASS);
758:                            mb.appendLoadConstant(map.getIndex());
759:                            mb
760:                                    .appendLoadConstant(map.getMarshaller()
761:                                            .getName());
762:                            mb.appendCallVirtual(ADDMARSHALLER_METHOD,
763:                                    ADDMARSHALLER_SIGNATURE);
764:                        }
765:                    }
766:                }
767:
768:                // handle the actual marshalling
769:                if (hasattr || hascont) {
770:                    mb.loadObject(m_class.getClassName());
771:                    if (hasattr) {
772:                        if (hascont) {
773:                            mb.appendDUP();
774:                        }
775:                        m_component.genAttributeMarshal(mb);
776:                    }
777:                    if (hasattr || m_isAbstract) {
778:                        mb.loadContext(MARSHALCONTEXT_CLASS);
779:                        mb.appendCallVirtual(CLOSESTART_METHOD,
780:                                CLOSESTART_SIGNATURE);
781:                        mb.appendPOP();
782:                    }
783:                    if (hascont) {
784:                        m_component.genContentMarshal(mb);
785:                    }
786:                }
787:
788:                // undefine marshallings for child mappings of this mapping
789:                if (maps != null && maps.size() > 0) {
790:                    for (int i = 0; i < maps.size(); i++) {
791:                        IMapping map = (IMapping) maps.get(i);
792:                        if (!map.isAbstract() || map.isBase()) {
793:                            mb.loadContext(MARSHALCONTEXT_CLASS);
794:                            mb.appendLoadConstant(map.getIndex());
795:                            mb.appendCallVirtual(REMOVEMARSHALLER_METHOD,
796:                                    REMOVEMARSHALLER_SIGNATURE);
797:                        }
798:                    }
799:                }
800:
801:                // finish with plain return
802:                mb.appendReturn();
803:                mb.codeComplete(false);
804:                mb.addMethod();
805:            }
806:
807:            public void generateCode(boolean force) throws JiBXException {
808:
809:                // first call code generation for child mappings
810:                m_defContext.generateCode(false, false);
811:                if (!force && m_isAbstract && m_extensions == null) {
812:                    return;
813:                }
814:
815:                // create the helper class
816:                BindingDefinition def = m_container.getBindingRoot();
817:                String init = m_class.deriveClassName(def.getPrefix(),
818:                        ADAPTERCLASS_SUFFIX);
819:                String name = init;
820:                int loop = 0;
821:                while (ClassCache.hasClassFile(name)) {
822:                    name = init + ++loop;
823:                }
824:                ClassFile base = ClassCache.getClassFile("java.lang.Object");
825:                String[] intfs = def.isInput() ? (def.isOutput() ? BOTH_INTERFACES
826:                        : UNMARSHALLER_INTERFACES)
827:                        : MARSHALLER_INTERFACES;
828:                ClassFile cf = new ClassFile(name, m_class.getMungedFile()
829:                        .getRoot(), base, Constants.ACC_PUBLIC, intfs);
830:                cf.addDefaultConstructor();
831:
832:                // add marshaller/unmarshaller implementation methods
833:                boolean hasattr = m_component.hasAttribute();
834:                boolean hascont = m_component.hasContent();
835:                boolean hasname = !m_isAbstract && m_name != null;
836:                if (def.isInput()) {
837:                    generateIsPresent(cf, hasname);
838:                    generateUnmarshalImplementation(cf, hasattr, hascont,
839:                            hasname);
840:                }
841:                if (def.isOutput()) {
842:
843:                    // generate the basic method
844:                    generateMarshalImplementation(cf, hasattr, hascont);
845:                    generateIfExtendingCheck(cf, hasname);
846:
847:                    // add interface if mapped class is directly marshallable
848:                    if (hasname
849:                            && m_class.getClassFile() == m_class
850:                                    .getMungedFile()) {
851:                        addIMarshallableMethod();
852:                    }
853:
854:                    // check for mapping with extensions to add extra method and
855:                    //  interface
856:                    if (m_extensions != null) {
857:                        generateAbstractMarshaller(cf);
858:                    }
859:                }
860:
861:                // add as generated class
862:                m_marshaller = m_unmarshaller = MungedClass
863:                        .getUniqueSupportClass(cf);
864:            }
865:
866:            public NameDefinition getWrapperName() {
867:                return m_name;
868:            }
869:
870:            public void setLinkages() throws JiBXException {
871:                m_component.setLinkages();
872:                m_defContext.setLinkages();
873:                if (m_name != null) {
874:                    m_name.fixNamespace(m_defContext);
875:                }
876:            }
877:
878:            // DEBUG
879:            public void print(int depth) {
880:                BindingDefinition.indent(depth);
881:                System.out.print("mapping class "
882:                        + m_class.getClassFile().getName());
883:                if (m_name != null) {
884:                    System.out.print(" to element " + m_name.toString());
885:                }
886:                System.out.print(" (#" + getIndex() + ')');
887:                if (m_baseMapping != null) {
888:                    System.out
889:                            .print(" extends " + m_baseMapping.getBoundType());
890:                }
891:                if (m_isAbstract) {
892:                    if (m_extensions != null) {
893:                        System.out.print(" (abstract, " + m_extensions.size()
894:                                + " extensions)");
895:                    } else {
896:                        System.out.print(" (abstract)");
897:                    }
898:                }
899:                System.out.println();
900:                m_defContext.print(depth + 1);
901:                m_component.print(depth + 1);
902:            }
903:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.