KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jibx > binding > def > ValueChild


1 /*
2 Copyright (c) 2003-2005, Dennis M. Sosnoski
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8  * Redistributions of source code must retain the above copyright notice, this
9    list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice,
11    this list of conditions and the following disclaimer in the documentation
12    and/or other materials provided with the distribution.
13  * Neither the name of JiBX nor the names of its contributors may be used
14    to endorse or promote products derived from this software without specific
15    prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */

28
29 package org.jibx.binding.def;
30
31 import org.apache.bcel.Constants;
32 import org.apache.bcel.generic.*;
33
34 import org.jibx.binding.classes.*;
35 import org.jibx.runtime.JiBXException;
36
37 /**
38  * Attribute or simple content value definition from binding. This organizes
39  * information for anything that can be converted to and from a simple
40  * <code>String</code>. Content values include both elements with only character
41  * data content and text, as character data content or CDATA sections.
42  *
43  * @author Dennis M. Sosnoski
44  * @version 1.0
45  */

46
47 public class ValueChild implements IComponent
48 {
49     //
50
// Ident type enumeration.
51

52     /*package*/ static final int DIRECT_IDENT = 0;
53     /*package*/ static final int AUTO_IDENT = 1;
54     /*package*/ static final int DEF_IDENT = 2;
55     /*package*/ static final int REF_IDENT = 3;
56     
57     //
58
// Value style enumeration.
59

60     /*package*/ static final int ATTRIBUTE_STYLE = 0;
61     /*package*/ static final int ELEMENT_STYLE = 1;
62     /*package*/ static final int TEXT_STYLE = 2;
63     /*package*/ static final int CDATA_STYLE = 3;
64     
65     //
66
// Constants for unmarshalling.
67

68     /** Prefix used for backfill classes. */
69     private static final String JavaDoc BACKFILL_SUFFIX = "_backfill_";
70     
71     private static final String JavaDoc[] BACKFILL_INTERFACES =
72     {
73         "org.jibx.runtime.impl.BackFillReference"
74     };
75     private static final String JavaDoc BACKFILL_METHODNAME = "backfill";
76     private static final Type[] BACKFILL_METHODARGS =
77     {
78         Type.OBJECT
79     };
80     private static final String JavaDoc BOUNDREF_NAME = "m_obj";
81     private static final String JavaDoc CHECK_ELEMENT_NAME =
82         "org.jibx.runtime.impl.UnmarshallingContext.isAt";
83     private static final String JavaDoc CHECK_ATTRIBUTE_NAME =
84         "org.jibx.runtime.impl.UnmarshallingContext.hasAttribute";
85     private static final String JavaDoc CHECK_SIGNATURE =
86         "(Ljava/lang/String;Ljava/lang/String;)Z";
87     private static final String JavaDoc UNMARSHAL_DEFREF_ATTR_NAME =
88         "org.jibx.runtime.impl.UnmarshallingContext.attributeExistingIDREF";
89     private static final String JavaDoc UNMARSHAL_DEFREF_ELEM_NAME =
90         "org.jibx.runtime.impl.UnmarshallingContext.parseElementExistingIDREF";
91     private static final String JavaDoc UNMARSHAL_FWDREF_ATTR_NAME =
92         "org.jibx.runtime.impl.UnmarshallingContext.attributeForwardIDREF";
93     private static final String JavaDoc UNMARSHAL_FWDREF_ELEM_NAME =
94         "org.jibx.runtime.impl.UnmarshallingContext.parseElementForwardIDREF";
95     private static final String JavaDoc UNMARSHAL_DEFREF_SIGNATURE =
96         "(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/Object;";
97     private static final String JavaDoc REGISTER_BACKFILL_NAME =
98         "org.jibx.runtime.impl.UnmarshallingContext.registerBackFill";
99     private static final String JavaDoc REGISTER_BACKFILL_SIGNATURE =
100         "(ILorg/jibx/runtime/impl/BackFillReference;)V";
101     private static final String JavaDoc DEFINE_ID_NAME =
102         "org.jibx.runtime.impl.UnmarshallingContext.defineID";
103     private static final String JavaDoc DEFINE_ID_SIGNATURE =
104         "(Ljava/lang/String;ILjava/lang/Object;)V";
105     private static final String JavaDoc UNMARSHAL_TEXT_NAME =
106         "org.jibx.runtime.impl.UnmarshallingContext.parseContentText";
107     private static final String JavaDoc UNMARSHAL_TEXT_SIGNATURE =
108         "()Ljava/lang/String;";
109     private static final String JavaDoc MARSHAL_TEXT_NAME =
110         "org.jibx.runtime.impl.MarshallingContext.writeContent";
111     private static final String JavaDoc MARSHAL_CDATA_NAME =
112         "org.jibx.runtime.impl.MarshallingContext.writeCData";
113     private static final String JavaDoc MARSHAL_TEXT_SIGNATURE =
114         "(Ljava/lang/String;)Lorg/jibx/runtime/impl/MarshallingContext;";
115     private static final String JavaDoc UNMARSHALLING_THROWEXCEPTION_METHOD =
116         "org.jibx.runtime.impl.UnmarshallingContext.throwException";
117     private static final String JavaDoc UNMARSHALLING_THROWEXCEPTION_SIGNATURE =
118         "(Ljava/lang/String;)V";
119     protected static final String JavaDoc MARSHAL_ATTRIBUTE =
120         "org.jibx.runtime.impl.MarshallingContext.attribute";
121     protected static final String JavaDoc MARSHAL_ELEMENT =
122         "org.jibx.runtime.impl.MarshallingContext.element";
123     protected static final String JavaDoc MARSHAL_SIGNATURE =
124         "(ILjava/lang/String;Ljava/lang/String;)" +
125         "Lorg/jibx/runtime/impl/MarshallingContext;";
126
127     //
128
// Actual instance data
129

130     /** Containing binding definition structure. */
131     private final IContainer m_container;
132
133     /** Containing object context. */
134     private final IContextObj m_objContext;
135
136     /** Value style code. */
137     private final int m_valueStyle;
138     
139     /** Constant value. */
140     private final String JavaDoc m_constantValue;
141
142     /** Ident type code. */
143     private final int m_identType;
144
145     /** Attribute or element name information. */
146     private final NameDefinition m_name;
147     
148     /** Fully qualified name of type. */
149     private final String JavaDoc m_type;
150
151     /** Linked property information. */
152     private final PropertyDefinition m_property;
153     
154     /** Conversion handling for value. */
155     private final StringConversion m_conversion;
156     
157     /** Mapping definition for object class supplying identifier. */
158     private IMapping m_idRefMap;
159
160     /**
161      * Constructor. Saves the context information for later use.
162      *
163      * @param contain containing binding definition structure
164      * @param objc containing object context
165      * @param name element or attribute name information (may be
166      * <code>null</code>)
167      * @param prop property reference information
168      * @param conv string conversion handler
169      * @param style value style code
170      * @param ident identifier type code
171      * @param constant value for constant
172      */

173
174     public ValueChild(IContainer contain, IContextObj objc, NameDefinition name,
175         PropertyDefinition prop, StringConversion conv, int style, int ident,
176         String JavaDoc constant) {
177         m_container = contain;
178         m_objContext = objc;
179         m_name = name;
180         m_property = prop;
181         m_type = prop.getTypeName();
182         m_conversion = conv;
183         m_valueStyle = style;
184         m_identType = ident;
185         m_constantValue = constant;
186     }
187
188     /**
189      * Create backfill handler class if it does not already exist. This either
190      * looks up the existing backfill handler class or creates a new one
191      * specifically for this value.
192      *
193      * @return backfill handler class for value
194      * @throws JiBXException if error in configuration
195      */

196
197     private ClassFile createBackfillClass() throws JiBXException {
198         
199         // create the new class
200
BoundClass bc = m_objContext.getBoundClass();
201         BindingDefinition def = m_container.getBindingRoot();
202         String JavaDoc name = bc.getClassFile().deriveClassName(def.getPrefix(),
203             BACKFILL_SUFFIX + m_property.getName());
204         ClassFile base = ClassCache.getClassFile("java.lang.Object");
205         ClassFile cf = new ClassFile(name, bc.getClassFile().getRoot(),
206             base, Constants.ACC_PUBLIC, BACKFILL_INTERFACES);
207         
208         // add member variable for bound class reference
209
String JavaDoc type = bc.getClassFile().getName();
210         ClassItem ref = cf.addPrivateField(type, BOUNDREF_NAME);
211         
212         // add the constructor taking bound class reference
213
Type[] args = new Type[] { ClassItem.typeFromName(type) };
214         MethodBuilder mb = new ExceptionMethodBuilder("<init>",
215             Type.VOID, args, cf, (short)0);
216         
217         // call the superclass constructor
218
mb.appendLoadLocal(0);
219         mb.appendCallInit("java.lang.Object", "()V");
220         
221         // store bound class reference to member variable
222
mb.appendLoadLocal(0);
223         mb.appendLoadLocal(1);
224         mb.appendPutField(ref);
225         mb.appendReturn();
226         mb.codeComplete(false);
227         mb.addMethod();
228         
229         // add actual backfill interface implementation method
230
mb = new ExceptionMethodBuilder(BACKFILL_METHODNAME, Type.VOID,
231             BACKFILL_METHODARGS, cf, Constants.ACC_PUBLIC);
232         mb.appendLoadLocal(0);
233         mb.appendGetField(ref);
234         mb.appendLoadLocal(1);
235         mb.appendCreateCast(m_property.getSetValueType());
236         m_property.genStore(mb);
237         mb.appendReturn();
238         mb.codeComplete(false);
239         mb.addMethod();
240         
241         // return unique instance of class
242
return MungedClass.getUniqueSupportClass(cf);
243     }
244
245     /**
246      * Generate unmarshalling code for object identifier reference. The code
247      * generated by this method assumes the unmarshalling context and name have
248      * already been loaded to the stack, and these are consumed by the code.
249      *
250      * @param mb method builder
251      * @throws JiBXException if error in configuration
252      */

253
254     private void genParseIdRef(ContextMethodBuilder mb) throws JiBXException {
255         
256         // first part of generated instruction sequence is to check if optional
257
// value is present
258
BranchWrapper ifmiss = null;
259         if (m_property.isOptional()) {
260             
261             // use existing context reference and name information to check for
262
// attribute or element present
263
String JavaDoc name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ?
264                 CHECK_ATTRIBUTE_NAME : CHECK_ELEMENT_NAME;
265             mb.appendCallVirtual(name, CHECK_SIGNATURE);
266             BranchWrapper ifpres = mb.appendIFNE(this);
267             
268             // push a null value to be stored as result for missing case
269
mb.appendACONST_NULL();
270             ifmiss = mb.appendUnconditionalBranch(this);
271             
272             // reload context reference and name information for use by actual
273
// unmarshalling call
274
mb.targetNext(ifpres);
275             mb.loadContext();
276             m_name.genPushUriPair(mb);
277             
278         }
279         
280         // find index of target class ID map
281
int index = m_container.getBindingRoot().
282             getIdClassIndex(m_property.getTypeName());
283         
284         // check if forward references allowed
285
if (m_container.getBindingRoot().isForwards()) {
286             
287             // generate call to unmarshal with forward allowed
288
mb.appendLoadConstant(index);
289             String JavaDoc name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ?
290                 UNMARSHAL_FWDREF_ATTR_NAME : UNMARSHAL_FWDREF_ELEM_NAME;
291             mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE);
292             
293             // check for null result returned
294
mb.appendDUP();
295             BranchWrapper ifdef = mb.appendIFNONNULL(this);
296             
297             // build and register backfill handler; start by loading the
298
// unmarshalling context, then load the index number of the target
299
// class and create an instance of the backfill handler
300
ClassFile backclas = createBackfillClass();
301             mb.loadContext();
302             mb.appendLoadConstant(index);
303             mb.appendCreateNew(backclas.getName());
304             
305             // duplicate the backfill handler reference, then load a reference
306
// to the owning object and call the initializer before calling
307
// the unmarshalling context to register the handler
308
mb.appendDUP();
309             mb.loadObject();
310             mb.appendCallInit(backclas.getName(), "(" +
311                 m_objContext.getBoundClass().getClassFile().getSignature() +
312                 ")V");
313             mb.appendCallVirtual(REGISTER_BACKFILL_NAME,
314                 REGISTER_BACKFILL_SIGNATURE);
315             
316             // set branch target for case where already defined
317
mb.targetNext(ifdef);
318             
319         } else {
320             
321             // generate call to unmarshal with predefined ID required
322
mb.appendLoadConstant(index);
323             String JavaDoc name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ?
324                 UNMARSHAL_DEFREF_ATTR_NAME : UNMARSHAL_DEFREF_ELEM_NAME;
325             mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE);
326         }
327             
328         // handle object type conversion if needed
329
mb.appendCreateCast(m_property.getSetValueType());
330         
331         // store returned reference to property
332
if (ifmiss != null) {
333             mb.targetNext(ifmiss);
334         }
335         m_property.genStore(mb);
336     }
337     
338     /**
339      * Generate test if present code. This generates code that tests if the
340      * child is present, leaving the result of the test (zero if missing,
341      * nonzero if present) on the stack.
342      *
343      * @param mb unmarshal method builder
344      * @throws JiBXException if configuration error
345      */

346
347     public void genIfPresentTest(UnmarshalBuilder mb) throws JiBXException {
348         
349         // make sure this is an appropriate call
350
if (m_name == null) {
351             throw new JiBXException("Method call on invalid value");
352         }
353         
354         // load the unmarshalling context and name information, then call the
355
// appropriate method to test for item present
356
mb.loadContext();
357         m_name.genPushUriPair(mb);
358         String JavaDoc name = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE) ?
359             CHECK_ATTRIBUTE_NAME : CHECK_ELEMENT_NAME;
360         mb.appendCallVirtual(name, CHECK_SIGNATURE);
361     }
362
363     /**
364      * Generate unmarshalling code. This internal method generates the
365      * necessary code for handling the unmarshalling operation. The code
366      * generated by this method restores the stack to the original state
367      * when done.
368      *
369      * @param mb method builder
370      * @throws JiBXException if error in configuration
371      */

372
373     private void genUnmarshal(ContextMethodBuilder mb) throws JiBXException {
374         
375         // first part of generated instruction sequence is to preload object
376
// reference for later use, then load the unmarshalling context and
377
// the name information
378
if (m_constantValue == null && !m_property.isImplicit()) {
379             mb.loadObject();
380         }
381         mb.loadContext();
382         if (m_name != null) {
383             m_name.genPushUriPair(mb);
384         }
385         
386         // check if this is an identifier for object
387
boolean isatt = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE);
388         if (m_identType == DEF_IDENT || m_identType == AUTO_IDENT) {
389             
390             // always unmarshal identifier value as text, then duplicate for use
391
// if storing
392
BindingDefinition.s_stringConversion.genParseRequired(isatt, mb);
393             if (m_identType != AUTO_IDENT) {
394                 mb.appendDUP();
395             }
396             
397             // load the context and swap to reorder, load the index for the
398
// class, and finally the ID'ed object, then call ID definition
399
// method
400
mb.loadContext();
401             mb.appendSWAP();
402             int index = m_container.getBindingRoot().
403                 getIdClassIndex(m_property.getTypeName());
404             mb.appendLoadConstant(index);
405             mb.loadObject();
406             mb.appendCallVirtual(DEFINE_ID_NAME, DEFINE_ID_SIGNATURE);
407             
408             // convert from text and store result using object reference loaded
409
// earlier
410
if (m_identType != AUTO_IDENT) {
411                 m_conversion.genFromText(mb);
412                 m_property.genStore(mb);
413             }
414
415         } else if (m_identType == REF_IDENT) {
416             
417             // generate code for unmarshalling object ID
418
genParseIdRef(mb);
419
420         } else if (m_constantValue == null) {
421             
422             // unmarshal and convert value
423
if (m_valueStyle == ValueChild.TEXT_STYLE ||
424                 m_valueStyle == ValueChild.CDATA_STYLE) {
425                 
426                 // unmarshal text value directly and let handler convert
427
mb.appendCallVirtual(UNMARSHAL_TEXT_NAME,
428                     UNMARSHAL_TEXT_SIGNATURE);
429                 m_conversion.genFromText(mb);
430                 
431             } else if (m_property.isOptional() &&
432                 (isatt || m_container.isContentOrdered())) {
433                 
434                 // parse value with possible default in ordered container
435
m_conversion.genParseOptional(isatt, mb);
436                 
437             } else {
438                 
439                 // parse required value, or value in unordered container
440
m_conversion.genParseRequired(isatt, mb);
441                 
442             }
443             
444             // handle object type conversion if needed
445
if (!m_conversion.isPrimitive() && m_property != null) {
446                 String JavaDoc stype = m_conversion.getTypeName();
447                 String JavaDoc dtype = m_property.getSetValueType();
448                 mb.appendCreateCast(stype, dtype);
449             }
450             
451             // store result using object reference loaded earlier
452
m_property.genStore(mb);
453
454         } else {
455             
456             // unmarshal and compare value
457
BranchWrapper ifmiss = null;
458             if (m_valueStyle == ValueChild.TEXT_STYLE ||
459                 m_valueStyle == ValueChild.CDATA_STYLE) {
460                 
461                 // unmarshal text value directly and let handler convert
462
mb.appendCallVirtual(UNMARSHAL_TEXT_NAME,
463                     UNMARSHAL_TEXT_SIGNATURE);
464                 
465             } else {
466                 
467                 // parse required attribute or element value
468
m_conversion.genParseOptional(isatt, mb);
469                 mb.appendDUP();
470                 ifmiss = mb.appendIFNULL(this);
471             }
472             
473             // compare unmarshalled value with required constant
474
mb.appendDUP();
475             mb.appendLoadConstant(m_constantValue);
476             mb.appendCallVirtual("java.lang.String.equals",
477                 "(Ljava/lang/Object;)Z");
478             BranchWrapper ifmatch = mb.appendIFNE(this);
479             
480             // throw exception on comparison error
481
mb.appendCreateNew("java.lang.StringBuffer");
482             mb.appendDUP();
483             mb.appendLoadConstant("Expected constant value \"" +
484                 m_constantValue + "\", found \"");
485             mb.appendCallInit("java.lang.StringBuffer",
486                 "(Ljava/lang/String;)V");
487             mb.appendSWAP();
488             mb.appendCallVirtual("java.lang.StringBuffer.append",
489                 "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
490             mb.appendLoadConstant("\"");
491             mb.appendCallVirtual("java.lang.StringBuffer.append",
492                 "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
493             mb.appendCallVirtual("java.lang.StringBuffer.toString",
494                 "()Ljava/lang/String;");
495             mb.loadContext();
496             mb.appendSWAP();
497             mb.appendCallVirtual(UNMARSHALLING_THROWEXCEPTION_METHOD,
498                 UNMARSHALLING_THROWEXCEPTION_SIGNATURE);
499             
500             // finish by setting target for branch
501
mb.targetNext(ifmatch);
502             mb.targetNext(ifmiss);
503             mb.appendPOP();
504         }
505     }
506
507     /**
508      * Generate marshalling code. This internal method generates the
509      * necessary code for handling the marshalling operation. The code
510      * generated by this method restores the stack to the original state
511      * when done.
512      *
513      * @param mb method builder
514      * @throws JiBXException if error in configuration
515      */

516
517     private void genMarshal(ContextMethodBuilder mb) throws JiBXException {
518         if (m_constantValue == null) {
519             
520             // first part of generated instruction sequence is to generate a
521
// check for an optional property present, then load the context
522
// and the name information (if present) for later use, then
523
// finally load the actual property value
524
BranchWrapper ifmiss = null;
525             if (m_property.hasTest()) {
526                 mb.loadObject();
527                 ifmiss = m_property.genTest(mb);
528             }
529             String JavaDoc type = m_property.getTypeName();
530             if (m_name != null) {
531                 
532                 // handle implicit property by first saving value to local, then
533
// reloading after the name information is on the stack
534
Type tobj = ClassItem.typeFromName(type);
535                 if (m_property.isImplicit()) {
536                     mb.defineSlot(this, tobj);
537                 }
538                 m_name.genPushIndexPair(mb);
539                 if (m_property.isImplicit()) {
540                     mb.appendLoadLocal(mb.getSlot(this));
541                     mb.freeSlot(this);
542                 }
543             }
544             if (!m_property.isImplicit()) {
545                 mb.loadObject();
546                 m_property.genLoad(mb);
547             }
548             
549             // check for object identity definition (accessed through property)
550
StringConversion convert = m_conversion;
551             if (m_identType == REF_IDENT) {
552                 m_idRefMap.getImplComponent().genLoadId(mb);
553                 convert = BindingDefinition.s_stringConversion;
554                 type = "java.lang.String";
555             }
556                 
557             // convert and marshal value
558
boolean isatt = m_valueStyle == ValueChild.ATTRIBUTE_STYLE;
559             if (m_valueStyle == ValueChild.TEXT_STYLE ||
560                 m_valueStyle == ValueChild.CDATA_STYLE) {
561                 convert.genToText(type, mb);
562                 String JavaDoc name = (m_valueStyle == ValueChild.TEXT_STYLE) ?
563                     MARSHAL_TEXT_NAME : MARSHAL_CDATA_NAME;
564                 mb.appendCallVirtual(name, MARSHAL_TEXT_SIGNATURE);
565             } else if (m_property.isOptional()) {
566                 convert.genWriteOptional(isatt, type, mb);
567             } else {
568                 convert.genWriteRequired(isatt, type, mb);
569             }
570             
571             // finish by setting target for missing optional property test
572
if (ifmiss != null) {
573                 mb.targetNext(ifmiss);
574             }
575             
576         } else {
577             
578             // just write constant value directly
579
if (m_name != null) {
580                 m_name.genPushIndexPair(mb);
581             }
582             mb.appendLoadConstant(m_constantValue);
583             switch (m_valueStyle) {
584                 case ATTRIBUTE_STYLE:
585                     mb.appendCallVirtual(MARSHAL_ATTRIBUTE, MARSHAL_SIGNATURE);
586                     break;
587                 case ELEMENT_STYLE:
588                     mb.appendCallVirtual(MARSHAL_ELEMENT, MARSHAL_SIGNATURE);
589                     break;
590                 case TEXT_STYLE:
591                     mb.appendCallVirtual(MARSHAL_TEXT_NAME,
592                         MARSHAL_TEXT_SIGNATURE);
593                     break;
594                 case CDATA_STYLE:
595                     mb.appendCallVirtual(MARSHAL_CDATA_NAME,
596                         MARSHAL_TEXT_SIGNATURE);
597                     break;
598             }
599         }
600     }
601
602     /**
603      * Get property name. If the child has an associated property this returns
604      * the name of that property.
605      *
606      * @return name for child property
607      */

608     
609     public String JavaDoc getPropertyName() {
610         if (m_property == null) {
611             return null;
612         } else {
613             return m_property.getName();
614         }
615     }
616     
617     //
618
// IComponent interface method definitions
619

620     public boolean isOptional() {
621         return m_property.isOptional();
622     }
623     
624     public boolean hasAttribute() {
625         return m_valueStyle == ATTRIBUTE_STYLE;
626     }
627
628     public void genAttrPresentTest(ContextMethodBuilder mb)
629         throws JiBXException {
630         
631         // make sure this is an appropriate call
632
if (m_valueStyle != ATTRIBUTE_STYLE || m_name == null) {
633             throw new JiBXException("Method call on invalid structure");
634         }
635         
636         // generate load of the unmarshalling context and the name information,
637
// then just call the attribute check method
638
mb.loadContext();
639         m_name.genPushUriPair(mb);
640         mb.appendCallVirtual(CHECK_ATTRIBUTE_NAME, CHECK_SIGNATURE);
641     }
642
643     public void genAttributeUnmarshal(ContextMethodBuilder mb)
644         throws JiBXException {
645         if (m_valueStyle == ATTRIBUTE_STYLE) {
646             genUnmarshal(mb);
647         }
648     }
649
650     public void genAttributeMarshal(ContextMethodBuilder mb)
651         throws JiBXException {
652         if (m_valueStyle == ATTRIBUTE_STYLE) {
653             genMarshal(mb);
654         }
655     }
656
657     public boolean hasContent() {
658         return m_valueStyle != ATTRIBUTE_STYLE;
659     }
660     
661
662     public void genContentPresentTest(ContextMethodBuilder mb)
663         throws JiBXException {
664         
665         // make sure this is an appropriate call
666
if (m_valueStyle != ELEMENT_STYLE) {
667             throw new JiBXException("Method call on invalid structure");
668         }
669         
670         // generate load of the unmarshalling context and the name information,
671
// then just call the attribute check method
672
mb.loadContext();
673         m_name.genPushUriPair(mb);
674         mb.appendCallVirtual(CHECK_ELEMENT_NAME, CHECK_SIGNATURE);
675     }
676
677     public void genContentUnmarshal(ContextMethodBuilder mb)
678         throws JiBXException {
679         if (m_valueStyle != ATTRIBUTE_STYLE) {
680             genUnmarshal(mb);
681         }
682     }
683
684     public void genContentMarshal(ContextMethodBuilder mb)
685         throws JiBXException {
686         if (m_valueStyle != ATTRIBUTE_STYLE) {
687             genMarshal(mb);
688         }
689     }
690     
691     public void genNewInstance(ContextMethodBuilder mb) {
692         throw new IllegalStateException JavaDoc
693             ("Internal error - no instance creation");
694     }
695     
696     public String JavaDoc getType() {
697         return m_type;
698     }
699
700     public boolean hasId() {
701         return m_identType == DEF_IDENT;
702     }
703     
704     public void genLoadId(ContextMethodBuilder mub) throws JiBXException {
705         m_property.genLoad(mub);
706     }
707
708     public boolean checkContentSequence(boolean text) throws JiBXException {
709         if (m_valueStyle == ELEMENT_STYLE) {
710             return true;
711         } else if (m_valueStyle == ATTRIBUTE_STYLE) {
712             return text;
713         } else if (text) {
714             return false;
715         } else {
716             throw new JiBXException("Text value must follow required element");
717         }
718     }
719
720     public void setLinkages() throws JiBXException {
721         if (m_identType == REF_IDENT) {
722             String JavaDoc type;
723             if (m_property == null) {
724                 type = m_objContext.getBoundClass().getClassFile().getName();
725             } else {
726                 type = m_property.getTypeName();
727             }
728             m_idRefMap = m_container.getDefinitionContext().
729                 getClassMapping(type);
730             if (m_idRefMap == null) {
731                 throw new JiBXException("No mapping defined for " +
732                     type + " used as IDREF target");
733             } else if (!m_idRefMap.getImplComponent().hasId()) {
734                 throw new JiBXException("No ID value defined for " +
735                     type + " used as IDREF target");
736             }
737         }
738     }
739     
740     // DEBUG
741
public void print(int depth) {
742         BindingDefinition.indent(depth);
743         if (m_valueStyle == ELEMENT_STYLE) {
744             System.out.print("element");
745         } else if (m_valueStyle == ATTRIBUTE_STYLE) {
746             System.out.print("attribute");
747         } else if (m_valueStyle == TEXT_STYLE) {
748             System.out.print("text");
749         } else if (m_valueStyle == CDATA_STYLE) {
750             System.out.print("cdata");
751         }
752         if (m_name != null) {
753             System.out.print(" " + m_name.toString());
754         }
755         if (m_property != null) {
756             System.out.print(" from " + m_property.toString());
757         }
758         System.out.println();
759     }
760 }
761
Popular Tags