Source Code Cross Referenced for ValueChild.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-2005, 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:
037:        /**
038:         * Attribute or simple content value definition from binding. This organizes
039:         * information for anything that can be converted to and from a simple
040:         * <code>String</code>. Content values include both elements with only character
041:         * data content and text, as character data content or CDATA sections.
042:         *
043:         * @author Dennis M. Sosnoski
044:         * @version 1.0
045:         */
046:
047:        public class ValueChild implements  IComponent {
048:            //
049:            // Ident type enumeration.
050:
051:            /*package*/static final int DIRECT_IDENT = 0;
052:            /*package*/static final int AUTO_IDENT = 1;
053:            /*package*/static final int DEF_IDENT = 2;
054:            /*package*/static final int REF_IDENT = 3;
055:
056:            //
057:            // Value style enumeration.
058:
059:            /*package*/static final int ATTRIBUTE_STYLE = 0;
060:            /*package*/static final int ELEMENT_STYLE = 1;
061:            /*package*/static final int TEXT_STYLE = 2;
062:            /*package*/static final int CDATA_STYLE = 3;
063:
064:            //
065:            // Constants for unmarshalling.
066:
067:            /** Prefix used for backfill classes. */
068:            private static final String BACKFILL_SUFFIX = "_backfill_";
069:
070:            private static final String[] BACKFILL_INTERFACES = { "org.jibx.runtime.impl.BackFillReference" };
071:            private static final String BACKFILL_METHODNAME = "backfill";
072:            private static final Type[] BACKFILL_METHODARGS = { Type.OBJECT };
073:            private static final String BOUNDREF_NAME = "m_obj";
074:            private static final String CHECK_ELEMENT_NAME = "org.jibx.runtime.impl.UnmarshallingContext.isAt";
075:            private static final String CHECK_ATTRIBUTE_NAME = "org.jibx.runtime.impl.UnmarshallingContext.hasAttribute";
076:            private static final String CHECK_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)Z";
077:            private static final String UNMARSHAL_DEFREF_ATTR_NAME = "org.jibx.runtime.impl.UnmarshallingContext.attributeExistingIDREF";
078:            private static final String UNMARSHAL_DEFREF_ELEM_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseElementExistingIDREF";
079:            private static final String UNMARSHAL_FWDREF_ATTR_NAME = "org.jibx.runtime.impl.UnmarshallingContext.attributeForwardIDREF";
080:            private static final String UNMARSHAL_FWDREF_ELEM_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseElementForwardIDREF";
081:            private static final String UNMARSHAL_DEFREF_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/Object;";
082:            private static final String REGISTER_BACKFILL_NAME = "org.jibx.runtime.impl.UnmarshallingContext.registerBackFill";
083:            private static final String REGISTER_BACKFILL_SIGNATURE = "(ILorg/jibx/runtime/impl/BackFillReference;)V";
084:            private static final String DEFINE_ID_NAME = "org.jibx.runtime.impl.UnmarshallingContext.defineID";
085:            private static final String DEFINE_ID_SIGNATURE = "(Ljava/lang/String;ILjava/lang/Object;)V";
086:            private static final String UNMARSHAL_TEXT_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseContentText";
087:            private static final String UNMARSHAL_TEXT_SIGNATURE = "()Ljava/lang/String;";
088:            private static final String UNMARSHAL_ELEMENT_TEXT_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseElementText";
089:            private static final String UNMARSHAL_ELEMENT_TEXT_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
090:            private static final String UNMARSHAL_PARSE_IF_START_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseIfStartTag";
091:            private static final String UNMARSHAL_PARSE_IF_START_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)Z";
092:            private static final String UNMARSHAL_PARSE_TO_START_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parseToStartTag";
093:            private static final String UNMARSHAL_PARSE_TO_START_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)V";
094:            private static final String UNMARSHAL_PARSE_PAST_END_NAME = "org.jibx.runtime.impl.UnmarshallingContext.parsePastEndTag";
095:            private static final String UNMARSHAL_PARSE_PAST_END_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;)V";
096:            private static final String MARSHAL_TEXT_NAME = "org.jibx.runtime.impl.MarshallingContext.writeContent";
097:            private static final String MARSHAL_CDATA_NAME = "org.jibx.runtime.impl.MarshallingContext.writeCData";
098:            private static final String MARSHAL_TEXT_SIGNATURE = "(Ljava/lang/String;)Lorg/jibx/runtime/impl/MarshallingContext;";
099:            private static final String UNMARSHALLING_THROWEXCEPTION_METHOD = "org.jibx.runtime.impl.UnmarshallingContext.throwException";
100:            private static final String UNMARSHALLING_THROWEXCEPTION_SIGNATURE = "(Ljava/lang/String;)V";
101:            protected static final String MARSHAL_ATTRIBUTE = "org.jibx.runtime.impl.MarshallingContext.attribute";
102:            protected static final String MARSHAL_ELEMENT = "org.jibx.runtime.impl.MarshallingContext.element";
103:            protected static final String MARSHAL_SIGNATURE = "(ILjava/lang/String;Ljava/lang/String;)"
104:                    + "Lorg/jibx/runtime/impl/MarshallingContext;";
105:            protected static final String MARSHAL_STARTTAG_ATTRIBUTES = "org.jibx.runtime.impl.MarshallingContext.startTagAttributes";
106:            protected static final String MARSHAL_STARTTAG_SIGNATURE = "(ILjava/lang/String;)Lorg/jibx/runtime/impl/MarshallingContext;";
107:            protected static final String MARSHAL_CLOSESTART_EMPTY = "org.jibx.runtime.impl.MarshallingContext.closeStartEmpty";
108:            protected static final String MARSHAL_CLOSESTART_EMPTY_SIGNATURE = "()Lorg/jibx/runtime/impl/MarshallingContext;";
109:            protected static final String UNMARSHAL_ATTRIBUTE_BOOLEAN_NAME = "org.jibx.runtime.impl.UnmarshallingContext.attributeBoolean";
110:            protected static final String UNMARSHAL_ATTRIBUTE_BOOLEAN_SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Z)Z";
111:
112:            //
113:            // Actual instance data
114:
115:            /** Containing binding definition structure. */
116:            private final IContainer m_container;
117:
118:            /** Containing object context. */
119:            private final IContextObj m_objContext;
120:
121:            /** Value style code. */
122:            private final int m_valueStyle;
123:
124:            /** Constant value. */
125:            private final String m_constantValue;
126:
127:            /** Ident type code. */
128:            private final int m_identType;
129:
130:            /** Attribute or element name information. */
131:            private final NameDefinition m_name;
132:
133:            /** Fully qualified name of type. */
134:            private final String m_type;
135:
136:            /** Nillable element flag. */
137:            private final boolean m_isNillable;
138:
139:            /** Linked property information. */
140:            private final PropertyDefinition m_property;
141:
142:            /** Conversion handling for value. */
143:            private final StringConversion m_conversion;
144:
145:            /** Mapping definition for object class supplying identifier. */
146:            private IMapping m_idRefMap;
147:
148:            /**
149:             * Constructor. Saves the context information for later use.
150:             *
151:             * @param contain containing binding definition structure
152:             * @param objc containing object context
153:             * @param name element or attribute name information (may be
154:             * <code>null</code>)
155:             * @param prop property reference information
156:             * @param conv string conversion handler
157:             * @param style value style code
158:             * @param ident identifier type code
159:             * @param constant value for constant
160:             * @param nillable nillable element flag
161:             */
162:            public ValueChild(IContainer contain, IContextObj objc,
163:                    NameDefinition name, PropertyDefinition prop,
164:                    StringConversion conv, int style, int ident,
165:                    String constant, boolean nillable) {
166:                m_container = contain;
167:                m_objContext = objc;
168:                m_name = name;
169:                m_property = prop;
170:                m_type = prop.getTypeName();
171:                m_conversion = conv;
172:                m_valueStyle = style;
173:                m_identType = ident;
174:                m_constantValue = constant;
175:                m_isNillable = nillable;
176:            }
177:
178:            /**
179:             * Create backfill handler class if it does not already exist. This either
180:             * looks up the existing backfill handler class or creates a new one
181:             * specifically for this value.
182:             *
183:             * @return backfill handler class for value
184:             * @throws JiBXException if error in configuration
185:             */
186:
187:            private ClassFile createBackfillClass() throws JiBXException {
188:
189:                // create the new class
190:                BoundClass bc = m_objContext.getBoundClass();
191:                BindingDefinition def = m_container.getBindingRoot();
192:                String name = bc.getClassFile()
193:                        .deriveClassName(def.getPrefix(),
194:                                BACKFILL_SUFFIX + m_property.getName());
195:                ClassFile base = ClassCache.getClassFile("java.lang.Object");
196:                ClassFile cf = new ClassFile(name, bc.getClassFile().getRoot(),
197:                        base, Constants.ACC_PUBLIC, BACKFILL_INTERFACES);
198:
199:                // add member variable for bound class reference
200:                String type = bc.getClassFile().getName();
201:                ClassItem ref = cf.addPrivateField(type, BOUNDREF_NAME);
202:
203:                // add the constructor taking bound class reference
204:                Type[] args = new Type[] { ClassItem.typeFromName(type) };
205:                MethodBuilder mb = new ExceptionMethodBuilder("<init>",
206:                        Type.VOID, args, cf, (short) 0);
207:
208:                // call the superclass constructor
209:                mb.appendLoadLocal(0);
210:                mb.appendCallInit("java.lang.Object", "()V");
211:
212:                // store bound class reference to member variable
213:                mb.appendLoadLocal(0);
214:                mb.appendLoadLocal(1);
215:                mb.appendPutField(ref);
216:                mb.appendReturn();
217:                mb.codeComplete(false);
218:                mb.addMethod();
219:
220:                // add actual backfill interface implementation method
221:                mb = new ExceptionMethodBuilder(BACKFILL_METHODNAME, Type.VOID,
222:                        BACKFILL_METHODARGS, cf, Constants.ACC_PUBLIC);
223:                mb.appendLoadLocal(0);
224:                mb.appendGetField(ref);
225:                mb.appendLoadLocal(1);
226:                mb.appendCreateCast(m_property.getSetValueType());
227:                m_property.genStore(mb);
228:                mb.appendReturn();
229:                mb.codeComplete(false);
230:                mb.addMethod();
231:
232:                // return unique instance of class
233:                return MungedClass.getUniqueSupportClass(cf);
234:            }
235:
236:            /**
237:             * Generate unmarshalling code for object identifier reference. The code
238:             * generated by this method assumes the unmarshalling context and name have
239:             * already been loaded to the stack, and these are consumed by the code.
240:             *
241:             * @param mb method builder
242:             * @throws JiBXException if error in configuration
243:             */
244:
245:            private void genParseIdRef(ContextMethodBuilder mb)
246:                    throws JiBXException {
247:
248:                // first part of generated instruction sequence is to check if optional
249:                //  value is present
250:                BranchWrapper ifmiss = null;
251:                if (m_property.isOptional()) {
252:
253:                    // use existing context reference and name information to check for
254:                    //  attribute or element present
255:                    String name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ? CHECK_ATTRIBUTE_NAME
256:                            : CHECK_ELEMENT_NAME;
257:                    mb.appendCallVirtual(name, CHECK_SIGNATURE);
258:                    BranchWrapper ifpres = mb.appendIFNE(this );
259:
260:                    // push a null value to be stored as result for missing case
261:                    mb.appendACONST_NULL();
262:                    ifmiss = mb.appendUnconditionalBranch(this );
263:
264:                    // reload context reference and name information for use by actual
265:                    //  unmarshalling call
266:                    mb.targetNext(ifpres);
267:                    mb.loadContext();
268:                    m_name.genPushUriPair(mb);
269:
270:                }
271:
272:                // find index of target class ID map
273:                int index = m_container.getBindingRoot().getIdClassIndex(
274:                        m_property.getTypeName());
275:
276:                // check if forward references allowed
277:                if (m_container.getBindingRoot().isForwards()) {
278:
279:                    // generate call to unmarshal with forward allowed
280:                    mb.appendLoadConstant(index);
281:                    String name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ? UNMARSHAL_FWDREF_ATTR_NAME
282:                            : UNMARSHAL_FWDREF_ELEM_NAME;
283:                    mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE);
284:
285:                    // check for null result returned
286:                    mb.appendDUP();
287:                    BranchWrapper ifdef = mb.appendIFNONNULL(this );
288:
289:                    // build and register backfill handler; start by loading the
290:                    //  unmarshalling context, then load the index number of the target
291:                    //  class and create an instance of the backfill handler
292:                    ClassFile backclas = createBackfillClass();
293:                    mb.loadContext();
294:                    mb.appendLoadConstant(index);
295:                    mb.appendCreateNew(backclas.getName());
296:
297:                    // duplicate the backfill handler reference, then load a reference
298:                    //  to the owning object and call the initializer before calling
299:                    //  the unmarshalling context to register the handler
300:                    mb.appendDUP();
301:                    mb.loadObject();
302:                    mb.appendCallInit(backclas.getName(), "("
303:                            + m_objContext.getBoundClass().getClassFile()
304:                                    .getSignature() + ")V");
305:                    mb.appendCallVirtual(REGISTER_BACKFILL_NAME,
306:                            REGISTER_BACKFILL_SIGNATURE);
307:
308:                    // set branch target for case where already defined
309:                    mb.targetNext(ifdef);
310:
311:                } else {
312:
313:                    // generate call to unmarshal with predefined ID required
314:                    mb.appendLoadConstant(index);
315:                    String name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ? UNMARSHAL_DEFREF_ATTR_NAME
316:                            : UNMARSHAL_DEFREF_ELEM_NAME;
317:                    mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE);
318:                }
319:
320:                // handle object type conversion if needed
321:                mb.appendCreateCast(m_property.getSetValueType());
322:
323:                // store returned reference to property
324:                if (ifmiss != null) {
325:                    mb.targetNext(ifmiss);
326:                }
327:                m_property.genStore(mb);
328:            }
329:
330:            /**
331:             * Generate test if present code. This generates code that tests if the
332:             * child is present, leaving the result of the test (zero if missing,
333:             * nonzero if present) on the stack.
334:             *
335:             * @param mb unmarshal method builder
336:             * @throws JiBXException if configuration error
337:             */
338:
339:            public void genIfPresentTest(UnmarshalBuilder mb)
340:                    throws JiBXException {
341:
342:                // make sure this is an appropriate call
343:                if (m_name == null) {
344:                    throw new JiBXException("Method call on invalid value");
345:                }
346:
347:                // load the unmarshalling context and name information, then call the
348:                //  appropriate method to test for item present
349:                mb.loadContext();
350:                m_name.genPushUriPair(mb);
351:                String name = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE) ? CHECK_ATTRIBUTE_NAME
352:                        : CHECK_ELEMENT_NAME;
353:                mb.appendCallVirtual(name, CHECK_SIGNATURE);
354:            }
355:
356:            /**
357:             * Generate unmarshalling code. This internal method generates the
358:             * necessary code for handling the unmarshalling operation. The code
359:             * generated by this method restores the stack to the original state
360:             * when done.
361:             *
362:             * @param mb method builder
363:             * @throws JiBXException if error in configuration
364:             */
365:
366:            private void genUnmarshal(ContextMethodBuilder mb)
367:                    throws JiBXException {
368:
369:                // first part of generated instruction sequence is to preload object
370:                //  reference for later use, then load the unmarshalling context and
371:                //  the name information
372:                if (m_constantValue == null && !m_property.isImplicit()) {
373:                    mb.loadObject();
374:                }
375:
376:                // prepare for parsing the element name
377:                mb.loadContext();
378:                if (m_name != null) {
379:                    m_name.genPushUriPair(mb);
380:                }
381:
382:                // check if this is an identifier for object
383:                boolean isatt = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE);
384:                if (m_identType == DEF_IDENT || m_identType == AUTO_IDENT) {
385:
386:                    // always unmarshal identifier value as text, then duplicate for use
387:                    //  if storing
388:                    BindingDefinition.s_stringConversion.genParseRequired(
389:                            isatt, mb);
390:                    if (m_identType != AUTO_IDENT) {
391:                        mb.appendDUP();
392:                    }
393:
394:                    // load the context and swap to reorder, load the index for the
395:                    //  class, and finally the ID'ed object, then call ID definition
396:                    //  method
397:                    mb.loadContext();
398:                    mb.appendSWAP();
399:                    int index = m_container.getBindingRoot().getIdClassIndex(
400:                            m_property.getTypeName());
401:                    mb.appendLoadConstant(index);
402:                    mb.loadObject();
403:                    mb.appendCallVirtual(DEFINE_ID_NAME, DEFINE_ID_SIGNATURE);
404:
405:                    // convert from text and store result using object reference loaded
406:                    //  earlier
407:                    if (m_identType != AUTO_IDENT) {
408:                        m_conversion.genFromText(mb);
409:                        m_property.genStore(mb);
410:                    }
411:
412:                } else if (m_identType == REF_IDENT) {
413:
414:                    // generate code for unmarshalling object ID
415:                    genParseIdRef(mb);
416:
417:                } else if (m_constantValue == null) {
418:
419:                    // unmarshal and convert value
420:                    if (m_isNillable) {
421:
422:                        // first check for element present at all
423:                        BranchWrapper ifmiss = null;
424:                        if (m_property.isOptional()) {
425:                            mb.appendCallVirtual(UNMARSHAL_PARSE_IF_START_NAME,
426:                                    UNMARSHAL_PARSE_IF_START_SIGNATURE);
427:                            ifmiss = mb.appendIFEQ(this );
428:                        } else {
429:                            mb.appendCallVirtual(UNMARSHAL_PARSE_TO_START_NAME,
430:                                    UNMARSHAL_PARSE_TO_START_SIGNATURE);
431:                        }
432:
433:                        // check for xsi:nil="true"
434:                        mb.loadContext();
435:                        mb
436:                                .appendLoadConstant("http://www.w3.org/2001/XMLSchema-instance");
437:                        mb.appendLoadConstant("nil");
438:                        mb.appendICONST_0();
439:                        mb.appendCallVirtual(UNMARSHAL_ATTRIBUTE_BOOLEAN_NAME,
440:                                UNMARSHAL_ATTRIBUTE_BOOLEAN_SIGNATURE);
441:                        BranchWrapper notnil = mb.appendIFEQ(this );
442:
443:                        // code to handle nil case just parses past end
444:                        mb.loadContext();
445:                        m_name.genPushUriPair(mb);
446:                        mb.appendCallVirtual(UNMARSHAL_PARSE_PAST_END_NAME,
447:                                UNMARSHAL_PARSE_PAST_END_SIGNATURE);
448:
449:                        // merge path with element not present, which just loads null
450:                        mb.targetNext(ifmiss);
451:                        mb.appendACONST_NULL();
452:                        BranchWrapper ifnil = mb
453:                                .appendUnconditionalBranch(this );
454:
455:                        // read element text and process for not-nil case
456:                        mb.targetNext(notnil);
457:                        mb.loadContext();
458:                        m_name.genPushUriPair(mb);
459:                        mb.appendCallVirtual(UNMARSHAL_ELEMENT_TEXT_NAME,
460:                                UNMARSHAL_ELEMENT_TEXT_SIGNATURE);
461:                        m_conversion.genFromText(mb);
462:                        mb.targetNext(ifnil);
463:
464:                    } else if (m_valueStyle == ValueChild.TEXT_STYLE
465:                            || m_valueStyle == ValueChild.CDATA_STYLE) {
466:
467:                        // unmarshal text value directly and let handler convert
468:                        mb.appendCallVirtual(UNMARSHAL_TEXT_NAME,
469:                                UNMARSHAL_TEXT_SIGNATURE);
470:                        m_conversion.genFromText(mb);
471:
472:                    } else if (m_property.isOptional()
473:                            && (isatt || m_container.isContentOrdered())) {
474:
475:                        // parse value with possible default in ordered container
476:                        m_conversion.genParseOptional(isatt, mb);
477:
478:                    } else {
479:
480:                        // parse required value, or value in unordered container
481:                        m_conversion.genParseRequired(isatt, mb);
482:
483:                    }
484:
485:                    // handle object type conversion if needed
486:                    if (!m_conversion.isPrimitive() && m_property != null) {
487:                        String stype = m_conversion.getTypeName();
488:                        String dtype = m_property.getSetValueType();
489:                        mb.appendCreateCast(stype, dtype);
490:                    }
491:
492:                    // store result using object reference loaded earlier
493:                    m_property.genStore(mb);
494:
495:                } else {
496:
497:                    // unmarshal and compare value
498:                    BranchWrapper ifmiss = null;
499:                    if (m_valueStyle == ValueChild.TEXT_STYLE
500:                            || m_valueStyle == ValueChild.CDATA_STYLE) {
501:
502:                        // unmarshal text value directly and let handler convert
503:                        mb.appendCallVirtual(UNMARSHAL_TEXT_NAME,
504:                                UNMARSHAL_TEXT_SIGNATURE);
505:
506:                    } else if (m_property.isOptional()
507:                            && (isatt || m_container.isContentOrdered())) {
508:
509:                        // parse optional attribute or element value
510:                        m_conversion.genParseOptional(isatt, mb);
511:                        mb.appendDUP();
512:                        ifmiss = mb.appendIFNULL(this );
513:
514:                    } else {
515:
516:                        // parse required attribute or element value
517:                        m_conversion.genParseRequired(isatt, mb);
518:                    }
519:
520:                    // compare unmarshalled value with required constant
521:                    mb.appendDUP();
522:                    mb.appendLoadConstant(m_constantValue);
523:                    mb.appendCallVirtual("java.lang.String.equals",
524:                            "(Ljava/lang/Object;)Z");
525:                    BranchWrapper ifmatch = mb.appendIFNE(this );
526:
527:                    // throw exception on comparison error
528:                    mb.appendCreateNew("java.lang.StringBuffer");
529:                    mb.appendDUP();
530:                    mb.appendLoadConstant("Expected constant value \""
531:                            + m_constantValue + "\", found \"");
532:                    mb.appendCallInit("java.lang.StringBuffer",
533:                            "(Ljava/lang/String;)V");
534:                    mb.appendSWAP();
535:                    mb.appendCallVirtual("java.lang.StringBuffer.append",
536:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
537:                    mb.appendLoadConstant("\"");
538:                    mb.appendCallVirtual("java.lang.StringBuffer.append",
539:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
540:                    mb.appendCallVirtual("java.lang.StringBuffer.toString",
541:                            "()Ljava/lang/String;");
542:                    mb.loadContext();
543:                    mb.appendSWAP();
544:                    mb.appendCallVirtual(UNMARSHALLING_THROWEXCEPTION_METHOD,
545:                            UNMARSHALLING_THROWEXCEPTION_SIGNATURE);
546:                    mb.appendACONST_NULL();
547:
548:                    // finish by setting target for branch
549:                    mb.targetNext(ifmatch);
550:                    mb.targetNext(ifmiss);
551:                    mb.appendPOP();
552:                }
553:            }
554:
555:            /**
556:             * Generate marshalling code. This internal method generates the
557:             * necessary code for handling the marshalling operation.  The code
558:             * generated by this method restores the stack to the original state
559:             * when done.
560:             *
561:             * @param mb method builder
562:             * @throws JiBXException if error in configuration
563:             */
564:
565:            private void genMarshal(ContextMethodBuilder mb)
566:                    throws JiBXException {
567:                if (m_constantValue == null) {
568:
569:                    // first part of generated instruction sequence is to generate a
570:                    //  check for an optional property present, then load the context
571:                    //  and the name information (if present) for later use, then
572:                    //  finally load the actual property value
573:                    BranchWrapper ifmiss = null;
574:                    if (m_property.hasTest()) {
575:                        mb.loadObject();
576:                        ifmiss = m_property.genTest(mb);
577:                    } else if (m_isNillable) {
578:
579:                        // check for null object
580:                        BranchWrapper ifhit;
581:                        if (m_property.isImplicit()) {
582:                            mb.appendDUP();
583:                            ifhit = mb.appendIFNONNULL(this );
584:                            mb.appendPOP();
585:                        } else {
586:                            mb.loadObject();
587:                            m_property.genLoad(mb);
588:                            ifhit = mb.appendIFNONNULL(this );
589:                        }
590:
591:                        // generate empty element with xsi:nil="true"
592:                        mb.loadContext();
593:                        m_name.genPushIndexPair(mb);
594:                        mb.appendCallVirtual(MARSHAL_STARTTAG_ATTRIBUTES,
595:                                MARSHAL_STARTTAG_SIGNATURE);
596:                        mb.appendLoadConstant(2);
597:                        mb.appendLoadConstant("nil");
598:                        mb.appendLoadConstant("true");
599:                        mb.appendCallVirtual(MARSHAL_ATTRIBUTE,
600:                                MARSHAL_SIGNATURE);
601:                        mb.appendCallVirtual(MARSHAL_CLOSESTART_EMPTY,
602:                                MARSHAL_CLOSESTART_EMPTY_SIGNATURE);
603:                        mb.appendPOP();
604:                        ifmiss = mb.appendUnconditionalBranch(this );
605:                        mb.targetNext(ifhit);
606:
607:                    }
608:                    String type = m_property.getTypeName();
609:                    if (m_name != null) {
610:
611:                        // handle implicit property by first saving value to local, then
612:                        //  reloading after the name information is on the stack
613:                        Type tobj = ClassItem.typeFromName(type);
614:                        if (m_property.isImplicit()) {
615:                            mb.defineSlot(this , tobj);
616:                        }
617:                        m_name.genPushIndexPair(mb);
618:                        if (m_property.isImplicit()) {
619:                            mb.appendLoadLocal(mb.getSlot(this ));
620:                            mb.freeSlot(this );
621:                        }
622:                    }
623:                    if (!m_property.isImplicit()) {
624:                        mb.loadObject();
625:                        m_property.genLoad(mb);
626:                    }
627:
628:                    // check for object identity definition (accessed through property)
629:                    StringConversion convert = m_conversion;
630:                    if (m_identType == REF_IDENT) {
631:                        m_idRefMap.getImplComponent().genLoadId(mb);
632:                        convert = BindingDefinition.s_stringConversion;
633:                        type = "java.lang.String";
634:                    }
635:
636:                    // convert to expected type if object
637:                    if (!ClassItem.isPrimitive(type)) {
638:                        mb.appendCreateCast(type);
639:                    }
640:
641:                    // convert and marshal value
642:                    boolean isatt = m_valueStyle == ValueChild.ATTRIBUTE_STYLE;
643:                    if (m_valueStyle == ValueChild.TEXT_STYLE
644:                            || m_valueStyle == ValueChild.CDATA_STYLE) {
645:                        convert.genToText(type, mb);
646:                        String name = (m_valueStyle == ValueChild.TEXT_STYLE) ? MARSHAL_TEXT_NAME
647:                                : MARSHAL_CDATA_NAME;
648:                        mb.appendCallVirtual(name, MARSHAL_TEXT_SIGNATURE);
649:                    } else if (m_property.isOptional()) {
650:                        convert.genWriteOptional(isatt, type, mb);
651:                    } else {
652:                        convert.genWriteRequired(isatt, type, mb);
653:                    }
654:
655:                    // finish by setting target for missing optional property test
656:                    mb.targetNext(ifmiss);
657:
658:                } else {
659:
660:                    // just write constant value directly
661:                    if (m_name != null) {
662:                        m_name.genPushIndexPair(mb);
663:                    }
664:                    mb.appendLoadConstant(m_constantValue);
665:                    switch (m_valueStyle) {
666:                    case ATTRIBUTE_STYLE:
667:                        mb.appendCallVirtual(MARSHAL_ATTRIBUTE,
668:                                MARSHAL_SIGNATURE);
669:                        break;
670:                    case ELEMENT_STYLE:
671:                        mb
672:                                .appendCallVirtual(MARSHAL_ELEMENT,
673:                                        MARSHAL_SIGNATURE);
674:                        break;
675:                    case TEXT_STYLE:
676:                        mb.appendCallVirtual(MARSHAL_TEXT_NAME,
677:                                MARSHAL_TEXT_SIGNATURE);
678:                        break;
679:                    case CDATA_STYLE:
680:                        mb.appendCallVirtual(MARSHAL_CDATA_NAME,
681:                                MARSHAL_TEXT_SIGNATURE);
682:                        break;
683:                    }
684:                }
685:            }
686:
687:            /**
688:             * Get property name. If the child has an associated property this returns
689:             * the name of that property.
690:             * 
691:             * @return name for child property
692:             */
693:
694:            public String getPropertyName() {
695:                if (m_property == null) {
696:                    return null;
697:                } else {
698:                    return m_property.getName();
699:                }
700:            }
701:
702:            /**
703:             * Check if implicit.
704:             * 
705:             * @return <code>true</code> if implicit, <code>false</code> if not
706:             */
707:            public boolean isImplicit() {
708:                return m_property.isThis();
709:            }
710:
711:            /**
712:             * Switch property from "this" to "implicit".
713:             */
714:            public void switchProperty() {
715:                m_property.switchProperty();
716:            }
717:
718:            //
719:            // IComponent interface method definitions
720:
721:            public boolean isOptional() {
722:                return m_property.isOptional();
723:            }
724:
725:            public boolean hasAttribute() {
726:                return m_valueStyle == ATTRIBUTE_STYLE;
727:            }
728:
729:            public void genAttrPresentTest(ContextMethodBuilder mb)
730:                    throws JiBXException {
731:
732:                // make sure this is an appropriate call
733:                if (m_valueStyle != ATTRIBUTE_STYLE || m_name == null) {
734:                    throw new JiBXException("Method call on invalid structure");
735:                }
736:
737:                // generate load of the unmarshalling context and the name information,
738:                //  then just call the attribute check method
739:                mb.loadContext();
740:                m_name.genPushUriPair(mb);
741:                mb.appendCallVirtual(CHECK_ATTRIBUTE_NAME, CHECK_SIGNATURE);
742:            }
743:
744:            public void genAttributeUnmarshal(ContextMethodBuilder mb)
745:                    throws JiBXException {
746:                if (m_valueStyle == ATTRIBUTE_STYLE) {
747:                    genUnmarshal(mb);
748:                }
749:            }
750:
751:            public void genAttributeMarshal(ContextMethodBuilder mb)
752:                    throws JiBXException {
753:                if (m_valueStyle == ATTRIBUTE_STYLE) {
754:                    genMarshal(mb);
755:                }
756:            }
757:
758:            public boolean hasContent() {
759:                return m_valueStyle != ATTRIBUTE_STYLE;
760:            }
761:
762:            public void genContentPresentTest(ContextMethodBuilder mb)
763:                    throws JiBXException {
764:
765:                // make sure this is an appropriate call
766:                if (m_valueStyle != ELEMENT_STYLE) {
767:                    throw new JiBXException("Method call on invalid structure");
768:                }
769:
770:                // generate load of the unmarshalling context and the name information,
771:                //  then just call the attribute check method
772:                mb.loadContext();
773:                m_name.genPushUriPair(mb);
774:                mb.appendCallVirtual(CHECK_ELEMENT_NAME, CHECK_SIGNATURE);
775:            }
776:
777:            public void genContentUnmarshal(ContextMethodBuilder mb)
778:                    throws JiBXException {
779:                if (m_valueStyle != ATTRIBUTE_STYLE) {
780:                    genUnmarshal(mb);
781:                }
782:            }
783:
784:            public void genContentMarshal(ContextMethodBuilder mb)
785:                    throws JiBXException {
786:                if (m_valueStyle != ATTRIBUTE_STYLE) {
787:                    genMarshal(mb);
788:                }
789:            }
790:
791:            public void genNewInstance(ContextMethodBuilder mb) {
792:                throw new IllegalStateException(
793:                        "Internal error - no instance creation");
794:            }
795:
796:            public String getType() {
797:                return m_type;
798:            }
799:
800:            public boolean hasId() {
801:                return m_identType == DEF_IDENT;
802:            }
803:
804:            public void genLoadId(ContextMethodBuilder mub)
805:                    throws JiBXException {
806:                m_property.genLoad(mub);
807:            }
808:
809:            public NameDefinition getWrapperName() {
810:                return (m_valueStyle == ELEMENT_STYLE) ? m_name : null;
811:            }
812:
813:            public void setLinkages() throws JiBXException {
814:                if (m_identType == REF_IDENT) {
815:                    String type;
816:                    if (m_property == null) {
817:                        type = m_objContext.getBoundClass().getClassFile()
818:                                .getName();
819:                    } else {
820:                        type = m_property.getTypeName();
821:                    }
822:                    m_idRefMap = m_container.getDefinitionContext()
823:                            .getClassMapping(type);
824:                    if (m_idRefMap == null) {
825:                        throw new JiBXException("No mapping defined for "
826:                                + type + " used as IDREF target");
827:                    } else if (!m_idRefMap.getImplComponent().hasId()) {
828:                        throw new JiBXException("No ID value defined for "
829:                                + type + " used as IDREF target");
830:                    }
831:                }
832:            }
833:
834:            // DEBUG
835:            public void print(int depth) {
836:                BindingDefinition.indent(depth);
837:                if (m_valueStyle == ELEMENT_STYLE) {
838:                    System.out.print("element");
839:                } else if (m_valueStyle == ATTRIBUTE_STYLE) {
840:                    System.out.print("attribute");
841:                } else if (m_valueStyle == TEXT_STYLE) {
842:                    System.out.print("text");
843:                } else if (m_valueStyle == CDATA_STYLE) {
844:                    System.out.print("cdata");
845:                }
846:                if (m_name != null) {
847:                    System.out.print(" " + m_name.toString());
848:                }
849:                if (m_property != null) {
850:                    System.out.print(" from " + m_property.toString());
851:                }
852:                System.out.println();
853:            }
854:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.