KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.io.IOException JavaDoc;
32 import java.net.MalformedURLException JavaDoc;
33 import java.net.URL JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.HashSet JavaDoc;
36
37 import org.apache.bcel.classfile.Utility;
38 import org.jibx.binding.classes.ClassCache;
39 import org.jibx.binding.classes.ClassFile;
40 import org.jibx.binding.classes.ClassItem;
41 import org.jibx.runtime.JiBXException;
42 import org.jibx.runtime.impl.UnmarshallingContext;
43
44 /**
45  * Binding definition constants. This gives the definitions for names and
46  * namespaces used by the binding definition file.
47  *
48  * @author Dennis M. Sosnoski
49  * @version 1.0
50  */

51
52 public abstract class BindingBuilder
53 {
54     /** Element namespace used for binding definition file. */
55     private static final String JavaDoc URI_ELEMENTS = null;
56
57     /** Attribute namespace used for binding definition file. */
58     private static final String JavaDoc URI_ATTRIBUTES = null;
59
60     /* Common style attribute. */
61     private static final String JavaDoc COMMON_STYLE = "value-style";
62
63     /* Common linkage attributes. */
64     private static final String JavaDoc COMMON_AUTOLINK = "auto-link";
65     private static final String JavaDoc COMMON_ACCESSLEVEL = "access-level";
66     private static final String JavaDoc COMMON_STRIPPREFIX = "strip-prefix";
67     private static final String JavaDoc COMMON_STRIPSUFFIX = "strip-suffix";
68     private static final String JavaDoc COMMON_NAMESTYLE = "name-style";
69
70     /* Common name attributes. */
71     private static final String JavaDoc COMMON_NAME = "name";
72     private static final String JavaDoc COMMON_NAMESPACE = "ns";
73
74     /* Common object attributes. */
75     private static final String JavaDoc COMMON_FACTORY = "factory";
76     private static final String JavaDoc COMMON_PRESET = "pre-set";
77     private static final String JavaDoc COMMON_POSTSET = "post-set";
78     private static final String JavaDoc COMMON_PREGET = "pre-get";
79     private static final String JavaDoc COMMON_MARSHALLER = "marshaller";
80     private static final String JavaDoc COMMON_UNMARSHALLER = "unmarshaller";
81
82     /* Common property attributes. */
83     private static final String JavaDoc COMMON_FIELD = "field";
84     private static final String JavaDoc COMMON_TYPE = "type";
85     private static final String JavaDoc COMMON_USAGE = "usage";
86     private static final String JavaDoc COMMON_TESTMETHOD = "test-method";
87     private static final String JavaDoc COMMON_GETMETHOD = "get-method";
88     private static final String JavaDoc COMMON_SETMETHOD = "set-method";
89
90     /* Common string attributes. */
91     private static final String JavaDoc COMMON_DEFAULT = "default";
92     private static final String JavaDoc COMMON_SERIALIZER = "serializer";
93     private static final String JavaDoc COMMON_DESERIALIZER = "deserializer";
94     
95     /* Common label attributes. */
96     private static final String JavaDoc COMMON_LABEL = "label";
97     private static final String JavaDoc COMMON_USING = "using";
98
99     /* Common ordered attribute. */
100     private static final String JavaDoc COMMON_ORDERED = "ordered";
101
102     /** Definitions for "binding" element use "BINDING" prefix. */
103     private static final String JavaDoc BINDING_ELEMENT = "binding";
104     private static final String JavaDoc BINDING_NAME = "name";
105     private static final String JavaDoc BINDING_DIRECTION = "direction";
106     private static final String JavaDoc BINDING_GLOBALID = "global-id";
107     private static final String JavaDoc BINDING_FORWARDS = "forwards";
108     private static final String JavaDoc BINDING_AUTOPREFIX = "auto-prefix";
109     private static final String JavaDoc BINDING_PACKAGE = "package";
110     private static final String JavaDoc BINDING_TRACKING = "track-source";
111     // also COMMON_STYLE, and linkage group
112

113     /** Definitions for "namespace" element use "NAMESPACE" prefix. */
114     private static final String JavaDoc NAMESPACE_ELEMENT = "namespace";
115     private static final String JavaDoc NAMESPACE_URI = "uri";
116     private static final String JavaDoc NAMESPACE_PREFIX = "prefix";
117     private static final String JavaDoc NAMESPACE_DEFAULT = "default";
118
119     /** Definitions for "format" element use "FORMAT" prefix. */
120     private static final String JavaDoc FORMAT_ELEMENT = "format";
121     private static final String JavaDoc FORMAT_NAME = "label";
122     private static final String JavaDoc FORMAT_TYPE = "type";
123     // also string group
124

125     /** Definitions for "mapping" element use "MAPPING" prefix. */
126     private static final String JavaDoc MAPPING_ELEMENT = "mapping";
127     private static final String JavaDoc MAPPING_CLASS = "class";
128     private static final String JavaDoc MAPPING_ABSTRACT = "abstract";
129     private static final String JavaDoc MAPPING_EXTENDS = "extends";
130     // also COMMON_STYLE, name, object, ordered, and linkage groups
131

132     /** Definitions for "value" element use "VALUE" prefix. */
133     private static final String JavaDoc VALUE_ELEMENT = "value";
134     private static final String JavaDoc VALUE_STYLE = "style";
135     private static final String JavaDoc VALUE_FORMAT = "format";
136     private static final String JavaDoc VALUE_CONSTANT = "constant";
137     private static final String JavaDoc VALUE_IDENT = "ident";
138     // also name, property, and string groups
139

140     /** Definitions for "structure" element use "STRUCTURE" prefix. */
141     private static final String JavaDoc STRUCTURE_ELEMENT = "structure";
142     private static final String JavaDoc STRUCTURE_MAPAS = "map-as";
143     // also COMMON_STYLE, name, object, ordered, property, and label groups
144

145     /** Definitions for "collection" element use "COLLECTION" prefix. */
146     private static final String JavaDoc COLLECTION_ELEMENT = "collection";
147     private static final String JavaDoc COLLECTION_LOADMETHOD = "load-method";
148     private static final String JavaDoc COLLECTION_SIZEMETHOD = "size-method";
149     private static final String JavaDoc COLLECTION_STOREMETHOD = "store-method";
150     private static final String JavaDoc COLLECTION_ADDMETHOD = "add-method";
151     private static final String JavaDoc COLLECTION_ITERMETHOD = "iter-method";
152     private static final String JavaDoc COLLECTION_ITEMTYPE = "item-type";
153     // also COMMON_STYLE, name, ordered, property, and label groups
154

155     /** Definitions for "include" element use "INCLUDE" prefix. */
156     private static final String JavaDoc INCLUDE_ELEMENT = "include";
157     private static final String JavaDoc INCLUDE_PATH = "path";
158     
159     //
160
// Value style enumeration.
161

162     private static final String JavaDoc[] VALUE_STYLE_NAMES =
163     {
164         "attribute", "cdata", "element", "text"
165     };
166     private static final int[] VALUE_STYLE_NUMS =
167     {
168         ValueChild.ATTRIBUTE_STYLE,
169         ValueChild.CDATA_STYLE,
170         ValueChild.ELEMENT_STYLE,
171         ValueChild.TEXT_STYLE
172     };
173     
174     private static final String JavaDoc[] CONTAINING_STYLE_NAMES =
175     {
176         "attribute", "element"
177     };
178     private static final int[] CONTAINING_STYLE_NUMS =
179     {
180         ValueChild.ATTRIBUTE_STYLE,
181         ValueChild.ELEMENT_STYLE
182     };
183     
184     //
185
// Enumeration for auto-link types.
186

187     /*package*/ static final int LINK_NONE = 0;
188     /*package*/ static final int LINK_FIELDS = 1;
189     /*package*/ static final int LINK_METHODS = 2;
190     
191     private static final String JavaDoc[] AUTO_LINK_NAMES =
192     {
193         "fields", "none", "methods"
194     };
195     private static final int[] AUTO_LINK_NUMS =
196     {
197         LINK_FIELDS, LINK_NONE, LINK_METHODS
198     };
199     
200     //
201
// Enumeration for access level.
202

203     /*package*/ static final int ACC_PRIVATE = 0;
204     /*package*/ static final int ACC_PACKAGE = 1;
205     /*package*/ static final int ACC_PROTECTED = 2;
206     /*package*/ static final int ACC_PUBLIC = 3;
207     
208     private static final String JavaDoc[] ACCESS_LEVEL_NAMES =
209     {
210         "package", "private", "protected", "public"
211     };
212     private static final int[] ACCESS_LEVEL_NUMS =
213     {
214         ACC_PACKAGE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC
215     };
216     
217     //
218
// Enumeration for name generation styles.
219

220     /*package*/ static final int NAME_HYPHENS = 0;
221     /*package*/ static final int NAME_MIXED = 1;
222     
223     private static final String JavaDoc[] NAME_GENERATE_NAMES =
224     {
225         "hyphens", "mixed-case"
226     };
227     private static final int[] NAME_GENERATE_NUMS =
228     {
229         NAME_HYPHENS, NAME_MIXED
230     };
231     
232     //
233
// Attributes that imply a component object
234

235     private static final String JavaDoc[] COMPONENT_OBJECT_NAMESPACES =
236     {
237         URI_ATTRIBUTES,
238         URI_ATTRIBUTES,
239         URI_ATTRIBUTES,
240         URI_ATTRIBUTES
241     };
242     private static final String JavaDoc[] COMPONENT_OBJECT_NAMES =
243     {
244         COMMON_FACTORY,
245         COMMON_PRESET,
246         COMMON_POSTSET,
247         COMMON_PREGET
248     };
249     
250     //
251
// Enumeration for namespace usage.
252

253     private static final String JavaDoc[] NAMESPACEACCESS_NAMES =
254     {
255         "all", "attributes", "elements", "none"
256     };
257     private static final int[] NAMESPACEACCESS_NUMS =
258     {
259         NamespaceDefinition.ALLDEFAULT_USAGE,
260         NamespaceDefinition.ATTRIBUTES_USAGE,
261         NamespaceDefinition.ELEMENTS_USAGE,
262         NamespaceDefinition.NODEFAULT_USAGE
263     };
264     
265     //
266
// Ident type enumeration.
267

268     private static final String JavaDoc[] IDENTTYPE_NAMES =
269     {
270         "auto", "def", "direct", "ref"
271     };
272     private static final int[] IDENTTYPE_NUMS =
273     {
274         ValueChild.AUTO_IDENT,
275         ValueChild.DEF_IDENT,
276         ValueChild.DIRECT_IDENT,
277         ValueChild.REF_IDENT
278     };
279     
280     //
281
// Binding direction enumeration.
282

283     private static final int DIRECTION_INPUT = 0;
284     private static final int DIRECTION_OUTPUT = 1;
285     private static final int DIRECTION_BOTH = 2;
286     
287     private static final String JavaDoc[] BINDINGDIR_NAMES =
288     {
289         "both", "input", "output"
290     };
291     private static final int[] BINDINGDIR_NUMS =
292     {
293         DIRECTION_BOTH,
294         DIRECTION_INPUT,
295         DIRECTION_OUTPUT
296     };
297     
298     //
299
// Constants for property usage values
300

301     private static final String JavaDoc USAGE_OPTIONAL = "optional";
302     private static final String JavaDoc USAGE_REQUIRED = "required";
303     
304     //
305
// Checking and code generation constants
306

307     private static final String JavaDoc UNMARSHALLER_INTERFACE =
308         "org.jibx.runtime.IUnmarshaller";
309     private static final String JavaDoc MARSHALLER_INTERFACE =
310         "org.jibx.runtime.IMarshaller";
311     private static final String JavaDoc UNMARSHALLER_INTERFACETYPE =
312         "Lorg/jibx/runtime/IUnmarshaller;";
313     private static final String JavaDoc MARSHALLER_INTERFACETYPE =
314         "Lorg/jibx/runtime/IMarshaller;";
315
316     /**
317      * Check if attributes supply a name definition.
318      *
319      * @param ctx unmarshalling context information
320      * @return <code>true</code> if attributes define a name,
321      * <code>false</code> if not
322      * @throws JiBXException if error in unmarshalling
323      */

324
325     private static boolean isNamePresent(UnmarshallingContext ctx)
326         throws JiBXException {
327         return ctx.attributeText(URI_ATTRIBUTES, COMMON_NAME, null) != null;
328     }
329
330     /**
331      * Check for style or linkage attributes present.
332      *
333      * @param ctx unmarshalling context information
334      * @return <code>true</code> if style or linkage attributes are present,
335      * <code>false</code> if not
336      * @throws JiBXException if error in unmarshalling
337      */

338
339     private static boolean isLinkagePresent(UnmarshallingContext ctx)
340         throws JiBXException {
341         return ctx.hasAttribute(URI_ATTRIBUTES, COMMON_STYLE) ||
342             ctx.hasAttribute(URI_ATTRIBUTES, COMMON_AUTOLINK) ||
343             ctx.hasAttribute(URI_ATTRIBUTES, COMMON_ACCESSLEVEL) ||
344             ctx.hasAttribute(URI_ATTRIBUTES, COMMON_STRIPPREFIX) ||
345             ctx.hasAttribute(URI_ATTRIBUTES, COMMON_STRIPSUFFIX) ||
346             ctx.hasAttribute(URI_ATTRIBUTES, COMMON_NAMESTYLE);
347     }
348
349     /**
350      * Check for property definition present. Just checks the attributes of
351      * the current element.
352      *
353      * @param ctx unmarshalling context information
354      * @throws JiBXException if error in unmarshalling
355      */

356
357     private static boolean isPropertyPresent(UnmarshallingContext ctx)
358         throws JiBXException {
359         return ctx.attributeText(URI_ATTRIBUTES, COMMON_FIELD, null) != null ||
360             ctx.attributeText(URI_ATTRIBUTES, COMMON_GETMETHOD, null) != null ||
361             ctx.attributeText(URI_ATTRIBUTES, COMMON_SETMETHOD, null) != null ||
362             ctx.attributeText(URI_ATTRIBUTES, COMMON_TESTMETHOD, null) != null;
363     }
364
365     /**
366      * Check if attributes define a direct object reference. Just checks the
367      * attributes of the current element.
368      *
369      * @param ctx unmarshalling context information
370      * @throws JiBXException if error in unmarshalling
371      */

372
373     private static boolean isDirectObject(UnmarshallingContext ctx)
374         throws JiBXException {
375         return ctx.attributeText(URI_ATTRIBUTES,
376             COMMON_MARSHALLER, null) != null ||
377             ctx.attributeText(URI_ATTRIBUTES,
378             COMMON_UNMARSHALLER, null) != null;
379     }
380
381     /**
382      * Check if attributes define a mapping reference.
383      *
384      * @param ctx unmarshalling context information
385      * @return <code>true</code> if attributes define a mapping reference,
386      * <code>false</code> if not
387      * @throws JiBXException if error in unmarshalling
388      */

389     
390     private static boolean isMappingRef(UnmarshallingContext ctx)
391         throws JiBXException {
392         return ctx.hasAttribute(URI_ATTRIBUTES, STRUCTURE_MAPAS);
393     }
394
395     /**
396      * Check for component object present. Just checks the attributes of the
397      * current element, so this is not definitive - there may still be child
398      * binding definitions even without attributes.
399      *
400      * @param ctx unmarshalling context information
401      * @throws JiBXException if error in unmarshalling
402      */

403
404     private static boolean isObjectBinding(UnmarshallingContext ctx)
405         throws JiBXException {
406         return ctx.hasAnyAttribute(COMPONENT_OBJECT_NAMESPACES,
407             COMPONENT_OBJECT_NAMES);
408     }
409
410     /**
411      * Unmarshal name definition. This unmarshals directly from attributes of
412      * the current element.
413      *
414      * @param ctx unmarshalling context information
415      * @param attr flag for attribute name definition
416      * @throws JiBXException if error in unmarshalling
417      */

418
419     private static NameDefinition unmarshalName(UnmarshallingContext ctx,
420         boolean attr) throws JiBXException {
421         String JavaDoc name = ctx.attributeText(URI_ATTRIBUTES, COMMON_NAME);
422         String JavaDoc ns = ctx.attributeText(URI_ATTRIBUTES, COMMON_NAMESPACE, null);
423         return new NameDefinition(name, ns, attr);
424     }
425
426     /**
427      * Unmarshal namespace definition.
428      *
429      * @param ctx unmarshalling context information
430      * @throws JiBXException if error in unmarshalling
431      */

432
433     private static NamespaceDefinition unmarshalNamespace
434         (UnmarshallingContext ctx) throws JiBXException {
435         
436         // set up the basic information
437
String JavaDoc uri = ctx.attributeText(URI_ATTRIBUTES, NAMESPACE_URI);
438         String JavaDoc prefix = ctx.attributeText(URI_ATTRIBUTES,
439             NAMESPACE_PREFIX, null);
440         if ("".equals(prefix)) {
441             prefix = null;
442         }
443         
444         // check default usage attribute
445
int usage = ctx.attributeEnumeration(URI_ATTRIBUTES, NAMESPACE_DEFAULT,
446             NAMESPACEACCESS_NAMES, NAMESPACEACCESS_NUMS,
447             NamespaceDefinition.NODEFAULT_USAGE);
448         
449         // finish parsing the element
450
ctx.parsePastEndTag(URI_ELEMENTS, NAMESPACE_ELEMENT);
451         return new NamespaceDefinition(uri, prefix, usage);
452     }
453
454     /**
455      * Unmarshal string conversion. Unmarshals conversion information directly
456      * from the attributes of the current start tag.
457      *
458      * @param ctx unmarshalling context information
459      * @param base conversion used as base for this conversion
460      * @param type fully qualified class name of type handled by conversion
461      * @throws JiBXException if error in unmarshalling
462      */

463
464     private static StringConversion unmarshalStringConversion
465         (UnmarshallingContext ctx, StringConversion base, String JavaDoc type)
466         throws JiBXException {
467         String JavaDoc dflt = ctx.attributeText(URI_ATTRIBUTES, COMMON_DEFAULT, null);
468         String JavaDoc ser = ctx.attributeText(URI_ATTRIBUTES, COMMON_SERIALIZER, null);
469         String JavaDoc dser = ctx.attributeText(URI_ATTRIBUTES,
470             COMMON_DESERIALIZER, null);
471         return base.derive(type, ser, dser, dflt);
472     }
473
474     /**
475      * Check for optional property. Just checks for the attribute and makes sure
476      * it has a valid value if present, returning either the default or the
477      * defined value.
478      *
479      * @param ctx unmarshalling context information
480      * @return <code>true</code> if attribute present with value "true",
481      * <code>false</code> otherwise
482      * @throws JiBXException if error in unmarshalling
483      */

484
485     private static boolean isOptionalProperty(UnmarshallingContext ctx)
486         throws JiBXException {
487         boolean opt = false;
488         String JavaDoc value = ctx.attributeText(URI_ATTRIBUTES, COMMON_USAGE,
489             USAGE_REQUIRED);
490         if (USAGE_OPTIONAL.equals(value)) {
491             opt = true;
492         } else if (!USAGE_REQUIRED.equals(value)) {
493             ctx.throwStartTagException("Illegal value for \"" + COMMON_USAGE+
494                 "\" attribute");
495         }
496         return opt;
497     }
498
499     /**
500      * Unmarshal property definition. This unmarshals directly from attributes
501      * of the current element.
502      *
503      * @param ctx unmarshalling context information
504      * @param parent containing binding definition structure
505      * @param cobj context object information
506      * @param opt force optional value flag
507      * @throws JiBXException if error in unmarshalling
508      */

509
510     private static PropertyDefinition unmarshalProperty
511         (UnmarshallingContext ctx, IContainer parent, IContextObj cobj,
512         boolean opt) throws JiBXException {
513
514         // read basic attribute values for property definition
515
String JavaDoc type = ctx.attributeText(URI_ATTRIBUTES, COMMON_TYPE, null);
516         if (isOptionalProperty(ctx)) {
517             opt = true;
518         }
519
520         // read and validate method and/or field attribute values
521
PropertyDefinition pdef = null;
522         try {
523             String JavaDoc fname = ctx.attributeText(URI_ATTRIBUTES,
524                 COMMON_FIELD, null);
525             String JavaDoc test = ctx.attributeText(URI_ATTRIBUTES,
526                 COMMON_TESTMETHOD, null);
527             String JavaDoc get = ctx.attributeText(URI_ATTRIBUTES,
528                 COMMON_GETMETHOD, null);
529             String JavaDoc set = ctx.attributeText(URI_ATTRIBUTES,
530                 COMMON_SETMETHOD, null);
531             boolean isthis = fname == null && get == null && set == null;
532             pdef = new PropertyDefinition
533                 (parent, cobj, type, isthis, opt, fname, test, get, set);
534             
535         } catch (JiBXException ex) {
536
537             // rethrow error message with position information
538
ctx.throwStartTagException(ex.getMessage());
539         }
540         return pdef;
541     }
542
543     /**
544      * Unmarshal value definition. This handles the complete element supplying
545      * the value binding.
546      *
547      * @param ctx unmarshalling context information
548      * @param parent containing binding definition structure
549      * @param cobj context object information
550      * @param uord unordered collection member flag
551      * @param impl implicit value from collection flag
552      * @param itype base type for value
553      * @throws JiBXException if error in unmarshalling
554      */

555
556     private static ValueChild unmarshalValue(UnmarshallingContext ctx,
557         IContainer parent, IContextObj cobj, boolean uord, boolean impl,
558         String JavaDoc itype) throws JiBXException {
559         
560         // make sure the old form of style definition isn't present
561
if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_STYLE)) {
562             ctx.throwStartTagException(COMMON_STYLE +
563                 " attribute is not supported for " + VALUE_ELEMENT +
564                 ", use " + VALUE_STYLE + " attribute instead");
565         }
566         
567         // find the style for this value
568
int style = ctx.attributeEnumeration(URI_ATTRIBUTES, VALUE_STYLE,
569             VALUE_STYLE_NAMES, VALUE_STYLE_NUMS, parent.getStyleDefault());
570             
571         // set up the basic structures
572
boolean isatt = style == ValueChild.ATTRIBUTE_STYLE;
573         NameDefinition name = null;
574         if (isatt || style == ValueChild.ELEMENT_STYLE) {
575             name = unmarshalName(ctx, isatt);
576             name.fixNamespace(parent.getDefinitionContext());
577         } else if (isNamePresent(ctx)) {
578             ctx.throwStartTagException
579                 ("Name not allowed for text or CDATA value");
580         }
581         String JavaDoc constant = ctx.attributeText(URI_ATTRIBUTES,
582             VALUE_CONSTANT, null);
583         
584         // handle property information (unless auto ident or implicit value)
585
int ident = ctx.attributeEnumeration(URI_ATTRIBUTES, VALUE_IDENT,
586             IDENTTYPE_NAMES, IDENTTYPE_NUMS, ValueChild.DIRECT_IDENT);
587         PropertyDefinition prop = null;
588         if (ident == ValueChild.AUTO_IDENT) {
589             ctx.throwStartTagException
590                 ("Automatic id generation not yet supported");
591         } else if (impl) {
592             String JavaDoc type = ctx.attributeText(URI_ATTRIBUTES, COMMON_TYPE, itype);
593             prop = new PropertyDefinition(type, cobj, isOptionalProperty(ctx));
594         } else {
595             prop = unmarshalProperty(ctx, parent, cobj,
596                 ctx.hasAttribute(URI_ATTRIBUTES, COMMON_DEFAULT));
597             if (constant == null && prop.isThis()) {
598                 ctx.throwStartTagException("No property for value");
599             } else if (prop.isOptional()) {
600                 if (ident == ValueChild.DEF_IDENT) {
601                     ctx.throwStartTagException("Object ID cannot be optional");
602                 }
603             } else if (uord) {
604                 ctx.throwStartTagException("All items in unordered " +
605                     "structure must be optional");
606             }
607         }
608         if (ident != ValueChild.DIRECT_IDENT && uord) {
609             ctx.throwStartTagException(VALUE_IDENT +
610                 " not allowed in unordered structure");
611         }
612         
613         // find the basic converter to use
614
StringConversion convert = null;
615         String JavaDoc type = (prop == null || constant != null) ?
616             "java.lang.String" : prop.getTypeName();
617         String JavaDoc format = ctx.attributeText(URI_ATTRIBUTES, VALUE_FORMAT, null);
618         DefinitionContext defc = parent.getDefinitionContext();
619         if (format == null) {
620             
621             // no format name, get specific convertor for type or best match
622
convert = defc.getSpecificConversion(type);
623             if (convert == null) {
624                 
625                 // find best match converter for type
626
ClassFile target = ClassCache.getClassFile(type);
627                 convert = defc.getConversion(target);
628                 
629                 // generate specific converter for object derivative
630
if (convert.getTypeName().equals("java.lang.Object")) {
631                     convert = new ObjectStringConversion(type,
632                         (ObjectStringConversion)convert);
633                 }
634             }
635             
636         } else {
637             
638             // format name supplied, look it up and check compatibility
639
convert = defc.getNamedConversion(format);
640             if (convert == null) {
641                 ctx.throwStartTagException
642                     ("Unknown format \"" + format + "\"");
643             }
644             String JavaDoc ctype = convert.getTypeName();
645             if (!ClassItem.isAssignable(type, ctype) &&
646                 !ClassItem.isAssignable(ctype, type)) {
647                 ctx.throwStartTagException
648                     ("Converter type not compatible with value type");
649             }
650         }
651         
652         // check for any special conversion handling
653
String JavaDoc dflt = ctx.attributeText(URI_ATTRIBUTES, COMMON_DEFAULT, null);
654         String JavaDoc ser = ctx.attributeText(URI_ATTRIBUTES, COMMON_SERIALIZER, null);
655         String JavaDoc dser = ctx.attributeText(URI_ATTRIBUTES,
656             COMMON_DESERIALIZER, null);
657         if (dflt != null || ser != null || dser != null) {
658             convert = convert.derive(type, ser, dser, dflt);
659         }
660         
661         // create the instance to be returned
662
ValueChild value = new ValueChild(parent, cobj, name, prop, convert,
663             style, ident, constant);
664         
665         // handle identifier property flag
666
if (ident == ValueChild.DEF_IDENT || ident == ValueChild.AUTO_IDENT) {
667             if (!cobj.setIdChild(value)) {
668                 ctx.throwStartTagException
669                     ("Duplicate ID definition for containing mapping");
670             } else if (!"java.lang.String".equals(type)) {
671                 ctx.throwStartTagException
672                     ("ID property must be a String");
673             }
674         }
675         
676         // finish with skipping past end tag
677
ctx.parsePastEndTag(URI_ELEMENTS, VALUE_ELEMENT);
678         return value;
679     }
680
681     /**
682      * Unmarshal direct object component. Just constructs the component to
683      * be returned along with the supporting objects, and verifies that no
684      * disallowed properties are present.
685      *
686      * @param ctx unmarshalling context information
687      * @param type fully qualified class name of object type handled
688      * @param parent containing binding definition structure
689      * @param defc definition context to be used (if separate from parent,
690      * otherwise <code>null</code>)
691      * @param slot marshaller/unmarshaller slot number
692      * @param name element name information (<code>null</code> if no element
693      * name)
694      * @return constructed direct object component
695      * @throws JiBXException if error in unmarshalling
696      */

697     
698     private static DirectObject unmarshalDirectObj(UnmarshallingContext ctx,
699         String JavaDoc type, IContainer parent, DefinitionContext defc, int slot,
700         NameDefinition name) throws JiBXException {
701         
702         // define and validate marshaller
703
ClassFile mcf = null;
704         if (parent.getBindingRoot().isOutput()) {
705             String JavaDoc clas = ctx.attributeText(URI_ATTRIBUTES, COMMON_MARSHALLER);
706             mcf = ClassCache.getClassFile(clas);
707             if (!mcf.isImplements(MARSHALLER_INTERFACETYPE)) {
708                 ctx.throwStartTagException("Marshaller class " + clas +
709                     " does not implement required interface " +
710                     MARSHALLER_INTERFACE);
711             }
712         }
713         
714         // define and validate unmarshaller
715
ClassFile ucf = null;
716         if (parent.getBindingRoot().isInput()) {
717             String JavaDoc clas = ctx.attributeText(URI_ATTRIBUTES,
718                 COMMON_UNMARSHALLER);
719             ucf = ClassCache.getClassFile(clas);
720             if (!ucf.isImplements(UNMARSHALLER_INTERFACETYPE)) {
721                 ctx.throwStartTagException("Unmarshaller class " + clas +
722                     " does not implement required interface " +
723                     UNMARSHALLER_INTERFACE);
724             }
725         }
726         
727         // make sure none of the prohibited attributes are present
728
if (isObjectBinding(ctx)) {
729             ctx.throwStartTagException("Other object attributes not " +
730                 "allowed when using marshaller or unmarshaller");
731         } else if (isMappingRef(ctx)) {
732             ctx.throwStartTagException("Mapping not allowed when " +
733                 "using marshaller or unmarshaller");
734         } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
735             ctx.throwStartTagException(COMMON_USING +
736                 " attribute not allowed when using marshaller or unmarshaller");
737         }
738         
739         // return constructed instance
740
return new DirectObject(parent, defc,
741             ClassCache.getClassFile(type), false, mcf, ucf, slot, name);
742     }
743
744     /**
745      * Unmarshal mapping reference component. Just constructs the component to
746      * be returned along with the supporting objects, and verifies that no
747      * disallowed properties are present.
748      *
749      * @param ctx unmarshalling context information
750      * @param parent containing binding definition structure
751      * @param objc current object context
752      * @param prop property definition
753      * @param name reference name definition (only allowed with abstract
754      * mappings)
755      * @return constructed mapping reference component
756      * @throws JiBXException if error in unmarshalling
757      */

758     
759     private static IComponent unmarshalMappingRef(UnmarshallingContext ctx,
760         IContainer parent, IContextObj objc, PropertyDefinition prop,
761         NameDefinition name) throws JiBXException {
762         
763         // make sure no forbidden attributes are present
764
if (isObjectBinding(ctx)) {
765             ctx.throwStartTagException("Other object attributes not " +
766                 "allowed when using mapping reference");
767         } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
768             ctx.throwStartTagException(COMMON_USING +
769                 " attribute not allowed when using mapping reference");
770         }
771         
772         // build the actual component to be returned
773
String JavaDoc type = (prop == null) ? null : prop.getTypeName();
774         type = ctx.attributeText(URI_ATTRIBUTES, STRUCTURE_MAPAS, type);
775         return new MappingReference(parent, prop, type, objc, name);
776     }
777
778     /**
779      * Unmarshal structure reference component. Just constructs the component to
780      * be returned along with the supporting objects, and verifies that no
781      * disallowed properties are present.
782      *
783      * @param ctx unmarshalling context information
784      * @param contain containing binding component
785      * @param name element name information (<code>null</code> if no element
786      * name)
787      * @param prop property definition (<code>null</code> if no separate
788      * property)
789      * @param cobj context object
790      * @return constructed structure reference component
791      * @throws JiBXException if error in unmarshalling
792      */

793     
794     private static IComponent unmarshalStructureRef(UnmarshallingContext ctx,
795         IContainer contain, NameDefinition name, PropertyDefinition prop,
796         IContextObj cobj) throws JiBXException {
797         
798         // make sure no forbidden attributes are present
799
if (isObjectBinding(ctx)) {
800             ctx.throwStartTagException("Other object attributes not " +
801                 "allowed when using structure reference");
802         }
803         
804         // build the actual component to be returned
805
String JavaDoc ident = ctx.attributeText(URI_ATTRIBUTES, COMMON_USING);
806         IComponent comp = new StructureReference(contain, ident, prop,
807             name != null, cobj);
808         if (name != null) {
809             comp = new ElementWrapper(contain.getDefinitionContext(),
810                 name, comp);
811             if (prop != null && prop.isOptional()) {
812                 ((ElementWrapper)comp).setOptionalNormal(true);
813                 ((ElementWrapper)comp).setStructureObject(true);
814                 comp = new OptionalStructureWrapper(comp, prop, true);
815                 prop.setOptional(false);
816             }
817         }
818         return comp;
819     }
820
821     /**
822      * Unmarshal child bindings for a nested structure definition.
823      *
824      * @param ctx unmarshalling context information
825      * @param nest nested structure definition
826      * @param objc context object definition
827      * @param impl property value implicit flag
828      * @param itype item type for child components
829      * @throws JiBXException if error in unmarshalling
830      */

831
832     private static void unmarshalStructureChildren(UnmarshallingContext ctx,
833         NestedBase nest, IContextObj objc, boolean impl, String JavaDoc itype)
834         throws JiBXException {
835         boolean uord = !nest.isContentOrdered();
836         while (true) {
837             
838             // unmarshal next child binding definition
839
IComponent comp;
840             if (ctx.isAt(URI_ELEMENTS, VALUE_ELEMENT)) {
841                 ValueChild child =
842                     unmarshalValue(ctx, nest, objc, uord, impl, itype);
843                 comp = child;
844             } else if (ctx.isAt(URI_ELEMENTS, STRUCTURE_ELEMENT)) {
845                 comp = unmarshalStructure(ctx, nest, objc, false, uord, impl);
846             } else if (ctx.isAt(URI_ELEMENTS, COLLECTION_ELEMENT)) {
847                 comp = unmarshalStructure(ctx, nest, objc, true, uord, impl);
848             } else {
849                 break;
850             }
851             
852             // add component to structure
853
nest.addComponent(comp);
854         }
855     }
856
857     /**
858      * Unmarshal object binding component. Just constructs the component to
859      * be returned along with the supporting objects. This handles both the
860      * unmarshalling of attributes, and of nested binding components.
861      *
862      * @param ctx unmarshalling context information
863      * @param parent containing binding definition structure
864      * @param objc current object context
865      * @param type fully qualified name of object class
866      * @return constructed structure reference component
867      * @throws JiBXException if error in unmarshalling
868      */

869     
870     private static ObjectBinding unmarshalObjectBinding
871         (UnmarshallingContext ctx, IContextObj objc, IContainer parent,
872         String JavaDoc type) throws JiBXException {
873         
874         // set method names from attributes of start tag
875
String JavaDoc fact = ctx.attributeText(URI_ATTRIBUTES, COMMON_FACTORY, null);
876         String JavaDoc pres = ctx.attributeText(URI_ATTRIBUTES, COMMON_PRESET, null);
877         String JavaDoc posts = ctx.attributeText(URI_ATTRIBUTES, COMMON_POSTSET, null);
878         String JavaDoc preg = ctx.attributeText(URI_ATTRIBUTES, COMMON_PREGET, null);
879         ObjectBinding bind = null;
880         try {
881             bind = new ObjectBinding(parent, objc, type, fact, pres,
882                 posts, preg);
883         } catch (JiBXException ex) {
884             ctx.throwStartTagException(ex.getMessage(), ex);
885         }
886         return bind;
887     }
888
889     /**
890      * Unmarshal namespace definitions. Any namespace definitions present are
891      * unmarshalled and added to the supplied definition context.
892      *
893      * @param ctx unmarshalling context information
894      * @param defc definition context for defined namespaces
895      * @throws JiBXException if error in unmarshalling
896      */

897     
898     private static void unmarshalNamespaces(UnmarshallingContext ctx,
899         DefinitionContext defc) throws JiBXException {
900         while (ctx.isAt(URI_ELEMENTS, NAMESPACE_ELEMENT)) {
901             defc.addNamespace(unmarshalNamespace(ctx));
902         }
903     }
904
905     /**
906      * Unmarshal format definitions. Any format definitions present are
907      * unmarshalled and added to the supplied definition context.
908      *
909      * @param ctx unmarshalling context information
910      * @param defc definition context for defined formats
911      * @throws JiBXException if error in unmarshalling
912      */

913     
914     private static void unmarshalFormats(UnmarshallingContext ctx,
915         DefinitionContext defc) throws JiBXException {
916         
917         // process all format definitions at level
918
while (ctx.isAt(URI_ELEMENTS, FORMAT_ELEMENT)) {
919             
920             // find the current default format information for type
921
String JavaDoc type = ctx.attributeText(URI_ATTRIBUTES, FORMAT_TYPE);
922             String JavaDoc sig = Utility.getSignature(type);
923             StringConversion base = null;
924             if (sig.length() == 1) {
925                 
926                 // must be a primitive, check type directly
927
base = defc.getSpecificConversion(type);
928                 if (base == null) {
929                     ctx.throwStartTagException("Unsupported \"" +
930                         FORMAT_TYPE + "\" value");
931                 }
932                 
933             } else {
934                 
935                 // must be an object type, find best match
936
ClassFile cf = ClassCache.getClassFile(type);
937                 base = defc.getConversion(cf);
938                 
939             }
940             
941             // unmarshal with defaults provided by existing format
942
StringConversion format =
943                 unmarshalStringConversion(ctx, base, type);
944             
945             // handle based on presence or absence of name attribute
946
String JavaDoc name = ctx.attributeText(URI_ATTRIBUTES, FORMAT_NAME, null);
947             if (name == null) {
948                 defc.setConversion(format);
949             } else {
950                 defc.setNamedConversion(name, format);
951             }
952             
953             // scan past end of definition
954
ctx.parsePastEndTag(URI_ELEMENTS, FORMAT_ELEMENT);
955         }
956     }
957
958     /**
959      * Unmarshal mapping definitions. Any mapping definitions present are
960      * unmarshalled and added to the supplied definition context.
961      *
962      * @param ctx unmarshalling context information
963      * @param parent containing binding definition structure
964      * @param nss extra namespaces to be included in this mapping definition
965      * (may be <code>null</code>)
966      * @param uord container is unordered structure flag
967      * @throws JiBXException if error in unmarshalling
968      */

969     
970     private static void unmarshalMappings(UnmarshallingContext ctx,
971         IContainer parent, ArrayList JavaDoc nss, boolean uord) throws JiBXException {
972         while (ctx.isAt(URI_ELEMENTS, MAPPING_ELEMENT)) {
973             unmarshalMapping(ctx, parent, nss, uord);
974         }
975     }
976
977     /**
978      * Unmarshal subclass instance for structure definition. This handles all
979      * combinations of attributes on the start tag, generating the appropriate
980      * structure of nested components and other classes to represent the binding
981      * information within the current element. This must be called with the
982      * parse positioned at the start tag of the element to be unmarshalled.
983      *
984      * TODO: At least split this up, or organize a better way to build binding
985      *
986      * @param ctx unmarshalling context information
987      * @param cdef containing context definition
988      * @param contain containing binding definition structure
989      * @param cobj context object information
990      * @param coll collection structure flag
991      * @param uord container is unordered structure flag
992      * @param implic property value implicit flag
993      * @return root of component tree constructed from binding
994      * @throws JiBXException if error in unmarshalling
995      */

996     
997     public static IComponent unmarshalStructure(UnmarshallingContext ctx,
998         IContainer contain, IContextObj cobj, boolean coll, boolean uord,
999         boolean implic) throws JiBXException {
1000        
1001        // get name definition if supplied (check later to see if valid)
1002
NameDefinition name = null;
1003        if (isNamePresent(ctx)) {
1004            name = unmarshalName(ctx, false);
1005        }
1006                
1007        // check for optional flag on structure
1008
boolean opt = isOptionalProperty(ctx);
1009        if (uord && !opt) {
1010            ctx.throwStartTagException
1011                ("All items in unordered structure must be optional");
1012        }
1013        
1014        // check for property definition supplied
1015
IComponent comp;
1016        boolean hasprop = isPropertyPresent(ctx);
1017        boolean thisref = false;
1018        if (!hasprop) {
1019            thisref = ctx.hasAttribute(URI_ATTRIBUTES, COMMON_TYPE);
1020        }
1021        if (hasprop || coll || implic || thisref) {
1022            
1023            // set up the property definition to be used
1024
PropertyDefinition prop = null;
1025            boolean hasobj = hasprop;
1026            if (implic) {
1027                
1028                // make sure no override of implicit property from collection
1029
if (hasprop) {
1030                    ctx.throwStartTagException("Property definition not " +
1031                        "allowed for collection items");
1032                } else {
1033                    String JavaDoc type = ctx.attributeText(URI_ATTRIBUTES,
1034                        COMMON_TYPE, null);
1035                    if (type == null) {
1036                        type = "java.lang.Object";
1037                    } else {
1038                        hasobj = true;
1039                    }
1040                    prop = new PropertyDefinition(type, cobj,
1041                        isOptionalProperty(ctx));
1042                }
1043                
1044            } else if (hasprop || thisref) {
1045                prop = unmarshalProperty(ctx, contain, cobj, opt);
1046            } else {
1047                if (opt && contain.getBindingRoot().isOutput()) {
1048                    ctx.throwStartTagException("Test required for optional " +
1049                        "output structure");
1050                } else {
1051                    prop = new PropertyDefinition(cobj, opt);
1052                }
1053            }
1054            
1055            // make sure optional if container is unordered
1056
if (!opt && uord) {
1057                ctx.throwStartTagException("All items in unordered " +
1058                    "structure must be optional");
1059            }
1060            
1061            // check if using direct object marshalling and unmarshalling
1062
if (isDirectObject(ctx)) {
1063                
1064                // validate and configure direct marshalling and unmarshalling
1065
comp = new DirectProperty(prop, unmarshalDirectObj(ctx,
1066                    prop.getTypeName(), contain, null, -1, name));
1067                
1068            } else if (isMappingRef(ctx)) {
1069                
1070                // validate and configure reference to mapping in context
1071
comp = unmarshalMappingRef(ctx, contain, cobj, prop, name);
1072                
1073            } else {
1074                
1075                // check for object binding needed
1076
IContextObj icobj = cobj;
1077                ObjectBinding bind = null;
1078                boolean typed = false;
1079                if (implic) {
1080                    typed = !prop.getTypeName().equals("java.lang.Object");
1081                } else {
1082                    typed = !prop.getTypeName().equals
1083                        (cobj.getBoundClass().getClassName());
1084                }
1085                if ((hasobj && !prop.isThis()) || (!hasobj && typed)) {
1086                    bind = unmarshalObjectBinding(ctx, cobj, contain,
1087                        prop.getTypeName());
1088                    icobj = bind;
1089                }
1090                
1091                // validate and configure reference to structure in context
1092
if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
1093                    comp = unmarshalStructureRef(ctx, contain, name,
1094                        prop, icobj);
1095                } else {
1096                    
1097                    // validate and configure actual binding definition
1098
DefinitionContext defc = contain.getDefinitionContext();
1099                    IComponent top = bind;
1100                    
1101                    // check for optional label definition
1102
String JavaDoc label = ctx.attributeText(URI_ATTRIBUTES,
1103                        COMMON_LABEL, null);
1104                    
1105                    // set load and store handlers for collection
1106
NestedCollection.CollectionLoad load = null;
1107                    NestedCollection.CollectionStore store = null;
1108                    if (coll) {
1109                        
1110                        // get any method names and type supplied by user
1111
String JavaDoc stname = ctx.attributeText(URI_ATTRIBUTES,
1112                            COLLECTION_STOREMETHOD, null);
1113                        String JavaDoc aname = ctx.attributeText(URI_ATTRIBUTES,
1114                            COLLECTION_ADDMETHOD, null);
1115                        String JavaDoc lname = ctx.attributeText(URI_ATTRIBUTES,
1116                            COLLECTION_LOADMETHOD, null);
1117                        String JavaDoc szname = ctx.attributeText(URI_ATTRIBUTES,
1118                            COLLECTION_SIZEMETHOD, null);
1119                        String JavaDoc iname = ctx.attributeText(URI_ATTRIBUTES,
1120                            COLLECTION_ITERMETHOD, null);
1121                        String JavaDoc itype = ctx.attributeText(URI_ATTRIBUTES,
1122                            COLLECTION_ITEMTYPE, "java.lang.Object");
1123                        
1124                        // verify combinations of attributes supplied
1125
if ((lname == null || szname == null) &&
1126                            !(lname == null && szname == null)) {
1127                            ctx.throwStartTagException(COLLECTION_LOADMETHOD +
1128                                " and " + COLLECTION_SIZEMETHOD +
1129                                " attributes must be used together");
1130                        }
1131                        if (iname != null && lname != null) {
1132                            ctx.throwStartTagException(COLLECTION_ITERMETHOD +
1133                                " and " + COLLECTION_LOADMETHOD +
1134                                " attributes cannot be used together");
1135                        }
1136                        if (aname != null && stname != null) {
1137                            ctx.throwStartTagException(COLLECTION_ADDMETHOD +
1138                                " and " + COLLECTION_STOREMETHOD +
1139                                " attributes cannot be used together");
1140                        }
1141                        
1142                        // set defaults based on collection type
1143
ClassFile cf = ClassCache.getClassFile
1144                            (prop.getTypeName());
1145                        if (cf.isSuperclass("java.util.Vector")||
1146                            cf.isSuperclass("java.util.ArrayList")) {
1147                            if (stname == null && aname == null) {
1148                                aname = "add";
1149                            }
1150                            if (iname == null && lname == null) {
1151                                lname = "get";
1152                                szname = "size";
1153                            }
1154                        } else if (cf.isImplements("Ljava/util/Collection;")) {
1155                            if (stname == null && aname == null) {
1156                                aname = "add";
1157                            }
1158                            if (iname == null && lname == null) {
1159                                iname = "iterator";
1160                            }
1161                        }
1162                        
1163                        // check binding direction(s)
1164
BindingDefinition bdef = contain.getBindingRoot();
1165                        if (bdef.isInput()) {
1166                            
1167                            // define strategy for adding items to collection
1168
if (aname != null) {
1169                                ClassItem meth = cf.getBestMethod(aname,
1170                                    null, new String JavaDoc[] { itype });
1171                                if (meth == null) {
1172                                    ctx.throwStartTagException
1173                                        ("Add method " + aname +
1174                                        " not found in collection type " +
1175                                        cf.getName());
1176                                }
1177                                boolean hasval =
1178                                    !"void".equals(meth.getTypeName());
1179                                store = new NestedCollection.AddStore(meth,
1180                                    hasval);
1181                            } else if (stname != null) {
1182                                ClassItem meth = cf.getBestMethod(stname,
1183                                    null, new String JavaDoc[] { "int", itype });
1184                                if (meth == null) {
1185                                    ctx.throwStartTagException
1186                                        ("Indexed store method " + stname +
1187                                        " not found in collection type " +
1188                                        cf.getName());
1189                                }
1190                                boolean hasval =
1191                                    !"void".equals(meth.getTypeName());
1192                                store = new NestedCollection.IndexedStore(meth,
1193                                    hasval);
1194                            } else {
1195                                ctx.throwStartTagException
1196                                    ("Unknown collection " +
1197                                    "type with no add or store method defined");
1198                            }
1199                            
1200                        }
1201                        if (bdef.isOutput()) {
1202                            
1203                            // define strategy for loading items from collection
1204
if (lname != null) {
1205                                ClassItem smeth = cf.getMethod(szname, "()I");
1206                                if (smeth == null) {
1207                                    ctx.throwStartTagException
1208                                        ("Size method " + szname +
1209                                        " not found in collection type " +
1210                                        cf.getName());
1211                                }
1212                                ClassItem lmeth = cf.getBestMethod(lname,
1213                                    itype, new String JavaDoc[] { "int" });
1214                                if (lmeth == null) {
1215                                    ctx.throwStartTagException
1216                                        ("Load method " + lname +
1217                                        " not found in collection type " +
1218                                        cf.getName());
1219                                }
1220                                load = new NestedCollection.
1221
                                    IndexedLoad(smeth, lmeth);
1222                            } else if (iname != null) {
1223                                String JavaDoc mname = "hasNext";
1224                                String JavaDoc nname = "next";
1225                                ClassItem meth = cf.getMethod(iname,
1226                                    "()Ljava/util/Iterator;");
1227                                if (meth == null) {
1228                                    mname = "hasMoreElements";
1229                                    nname = "nextElement";
1230                                    meth = cf.getMethod(iname,
1231                                        "()Ljava/util/Enumeration;");
1232                                    if (meth == null) {
1233                                        ctx.throwStartTagException
1234                                            ("Iterator method " + iname +
1235                                            " not found in collection type " +
1236                                            cf.getName());
1237                                    }
1238                                }
1239                                load = new NestedCollection.
1240
                                    IteratorLoad(meth,
1241                                    "java.util.Iterator." + mname,
1242                                    "java.util.Iterator." + nname);
1243                            } else {
1244                                ctx.throwStartTagException
1245                                    ("Unknown collection " +
1246                                    "type with no load method defined");
1247                            }
1248                        }
1249                        
1250                    }
1251                    
1252                    // check for collection with item type specified
1253
NestedBase nest;
1254                    String JavaDoc itype = "java.lang.Object";
1255                    if (ctx.hasAttribute(URI_ATTRIBUTES, COLLECTION_ITEMTYPE)) {
1256                        
1257                        // make sure this is a collection
1258
if (!coll) {
1259                            ctx.throwStartTagException(COLLECTION_ITEMTYPE +
1260                                " attribute only allowed on collection");
1261                        }
1262                        
1263                        // save the item type
1264
itype = ctx.attributeText(URI_ATTRIBUTES,
1265                            COLLECTION_ITEMTYPE);
1266                    }
1267                    
1268                    // unmarshal basics of nested structure
1269
if (coll) {
1270                        
1271                        // create collection definition
1272
nest = new NestedCollection(contain, icobj,
1273                            ctx.attributeBoolean(URI_ATTRIBUTES,
1274                            COMMON_ORDERED, true), itype, load, store);
1275                        nest.unmarshal(ctx);
1276                        ctx.parsePastStartTag(URI_ELEMENTS,
1277                            COLLECTION_ELEMENT);
1278                            
1279                    } else {
1280                        
1281                        // create structure definition
1282
nest = new NestedStructure(contain, icobj,
1283                            ctx.attributeBoolean(URI_ATTRIBUTES,
1284                            COMMON_ORDERED, true), false, hasobj);
1285                        nest.unmarshal(ctx);
1286                        ctx.parsePastStartTag(URI_ELEMENTS,
1287                            STRUCTURE_ELEMENT);
1288                    }
1289            
1290                    // unmarshal child bindings with optional label
1291
unmarshalFormats(ctx, nest.getDefinitionContext());
1292                    unmarshalMappings(ctx, contain, null, uord);
1293                    unmarshalStructureChildren(ctx, nest, icobj,
1294                        coll | (implic && !hasobj), itype);
1295                    if (top == null) {
1296                        top = nest;
1297                    }
1298                        
1299                    // check for children defined
1300
boolean childs = nest.hasContent();
1301                    boolean addref = false;
1302                    if (!childs) {
1303                        if (coll) {
1304                            
1305                            // add mapping as only child
1306
if (itype.equals("java.lang.Object")) {
1307                                nest.addComponent
1308                                    (new DirectGeneric(nest, null));
1309                            } else {
1310                                nest.addComponent(new MappingReference(contain,
1311                                    new PropertyDefinition(itype, cobj, false),
1312                                    itype, icobj, null));
1313                            }
1314                            childs = true;
1315                            
1316                        } else if (name != null) {
1317                            
1318                            // must be abstract mappping reference, create child
1319
addref = true;
1320                            
1321                        }
1322                    }
1323                    
1324                    // handle nested children
1325
comp = top;
1326                    if (childs || addref) {
1327                        
1328                        // define component property wrapping object binding
1329
boolean optprop = hasprop && prop.isOptional();
1330                        if (bind != null) {
1331                            boolean skip = name != null && optprop;
1332                            comp = new ComponentProperty(prop, comp, skip);
1333                            bind.setWrappedComponent(nest);
1334                        }
1335                        
1336                        // create reference to mapping as special case
1337
// this allows structure with name but no children to
1338
// use abstract mapping
1339
if (addref) {
1340                            PropertyDefinition thisprop =
1341                                new PropertyDefinition(bind, false);
1342                            nest.addComponent(new MappingReference
1343                                (nest, thisprop, comp.getType(), icobj, null));
1344                        }
1345                        if (name != null) {
1346                            comp = new ElementWrapper(defc, name, comp);
1347                            if (bind != null && !hasprop) {
1348                                ((ElementWrapper)comp).setDirect(true);
1349                                bind.setDirect(true);
1350                            }
1351                            if (optprop) {
1352                                ((ElementWrapper)comp).setOptionalNormal(true);
1353                                boolean isobj = bind != null;
1354                                ((ElementWrapper)comp).
1355                                    setStructureObject(isobj);
1356                                comp = new OptionalStructureWrapper(comp, prop,
1357                                    isobj);
1358                                prop.setOptional(false);
1359                            }
1360                        }
1361                        
1362                    } else {
1363                            
1364                        // treat as mapping, with either type or generic
1365
String JavaDoc type = prop.getTypeName();
1366                        if (prop.equals("java.lang.Object")) {
1367                            comp = new ComponentProperty(prop, new
1368                                DirectGeneric(contain, null), false);
1369                        } else {
1370                            comp = new MappingReference(contain, prop, type,
1371                                icobj, name);
1372                        }
1373                    }
1374                    
1375                    // set object binding as definition for label
1376
if (label != null) {
1377                        defc.addNamedStructure(label, top);
1378                    }
1379                }
1380            }
1381            
1382        } else {
1383            
1384            // structure with no separate object, verify no forbidden attributes
1385
boolean mapping = isMappingRef(ctx);
1386            if (isObjectBinding(ctx)) {
1387                ctx.throwStartTagException("Object attributes not " +
1388                    "allowed without property definition");
1389            } else if (isDirectObject(ctx)) {
1390                ctx.throwStartTagException("Marshaller and unmarshaller not " +
1391                    "allowed without property definition");
1392            }
1393            
1394            // check for reference to structure defined elsewhere
1395
if (mapping) {
1396                
1397                // handle "this" reference as anonymous property
1398
PropertyDefinition prop = new PropertyDefinition(cobj, opt);
1399                    
1400                // handle reference to defined mapping
1401
comp = unmarshalMappingRef(ctx, contain, cobj, prop, name);
1402                String JavaDoc type = comp.getType();
1403                ClassFile cf = cobj.getBoundClass().getClassFile();
1404                implic = ClassItem.isAssignable(cf.getName(), type);
1405                if (!implic) {
1406                    ctx.throwStartTagException
1407                        ("Mapping references require property definition");
1408                }
1409                    
1410            } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
1411                
1412                // make sure forbidden attribute not used
1413
if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_ORDERED)) {
1414                    ctx.throwStartTagException(COMMON_ORDERED + " attribute " +
1415                        " not allowed with " + COMMON_USING + " attribute");
1416                }
1417                
1418                // validate and configure reference to structure in context
1419
comp = unmarshalStructureRef(ctx, contain, name, null, cobj);
1420                                
1421            } else {
1422                
1423                // unmarshal children as nested structure
1424
NestedStructure nest = new NestedStructure(contain, cobj,
1425                    ctx.attributeBoolean(URI_ATTRIBUTES, COMMON_ORDERED, true),
1426                    false, hasprop);
1427                nest.unmarshal(ctx);
1428        
1429                // unmarshal child bindings with optional label
1430
String JavaDoc label = ctx.attributeText(URI_ATTRIBUTES,
1431                    COMMON_LABEL, null);
1432                ctx.parsePastStartTag(URI_ELEMENTS, STRUCTURE_ELEMENT);
1433                unmarshalFormats(ctx, nest.getDefinitionContext());
1434                unmarshalMappings(ctx, contain, null, uord);
1435                unmarshalStructureChildren(ctx, nest, cobj, false,
1436                    "java.lang.Object");
1437                    
1438                // check for children defined
1439
DefinitionContext defc = contain.getDefinitionContext();
1440                if (nest.hasContent()) {
1441                    
1442                    // build structure to access children or with elment wrapper
1443
if (name == null) {
1444                        comp = nest;
1445                    } else {
1446                        comp = new ElementWrapper(defc, name, nest);
1447                        if (opt) {
1448                            ((ElementWrapper)comp).setOptionalNormal(true);
1449                            ((ElementWrapper)comp).setStructureObject(true);
1450                        }
1451                    }
1452                    if (label != null) {
1453                        defc.addNamedStructure(label, nest);
1454                    }
1455                    
1456                } else {
1457                    
1458                    // make sure there's a name defined
1459
if (name == null) {
1460                        ctx.throwException
1461                            ("Property, name, or child component required");
1462                    }
1463                        
1464                    // treat as throwaway portion of document
1465
comp = new ElementWrapper(defc, name, null);
1466                    if (opt) {
1467                        ((ElementWrapper)comp).setOptionalIgnored(true);
1468                    }
1469                    
1470                }
1471            }
1472        }
1473        
1474        // finish by parsing past end tag
1475
ctx.parsePastEndTag(URI_ELEMENTS,
1476            coll ? COLLECTION_ELEMENT : STRUCTURE_ELEMENT);
1477        return comp;
1478    }
1479
1480    /**
1481     * Unmarshal mapping definition. This handles all combinations of attributes
1482     * on the start tag, generating the appropriate structure of nested
1483     * components and other classes to represent the binding information within
1484     * the current element. This must be called with the parse positioned at the
1485     * start tag of the element to be unmarshalled.
1486     *
1487     * @param ctx unmarshalling context information
1488     * @param parent containing binding definition structure
1489     * @param nss extra namespaces to be included in this mapping definition
1490     * (may be <code>null</code>)
1491     * @param uord container is unordered structure flag
1492     * @return mapping definition constructed from binding
1493     * @throws JiBXException if error in unmarshalling
1494     */

1495
1496    public static IMapping unmarshalMapping(UnmarshallingContext ctx,
1497        IContainer parent, ArrayList JavaDoc nss, boolean uord) throws JiBXException {
1498        
1499        // first check for an abstract mapping
1500
boolean abs = ctx.attributeBoolean(URI_ATTRIBUTES,
1501            MAPPING_ABSTRACT, false);
1502        String JavaDoc type = ctx.attributeText(URI_ATTRIBUTES, MAPPING_CLASS);
1503        
1504        // get name definition if supplied
1505
NameDefinition name = null;
1506        if (isNamePresent(ctx)) {
1507            name = unmarshalName(ctx, false);
1508        }
1509        
1510        // check if using direct object marshalling and unmarshalling
1511
IMapping mapping;
1512        if (isDirectObject(ctx)) {
1513            
1514            // check for definition context needed
1515
DefinitionContext defc = null;
1516            if (nss != null && nss.size() > 0) {
1517            
1518                // add all outer namespaces to context
1519
defc = new DefinitionContext(parent);
1520                if (nss != null && nss.size() > 0) {
1521                    for (int j = 0; j < nss.size(); j++) {
1522                        defc.addNamespace((NamespaceDefinition)nss.get(j));
1523                    }
1524                }
1525            }
1526            
1527            // validate and configure direct marshalling and unmarshalling
1528
int slot = parent.getBindingRoot().getMappedClassIndex(type);
1529            mapping = new MappingDirect(parent, type,
1530                unmarshalDirectObj(ctx, type, parent, defc, slot, name));
1531                        
1532        } else {
1533            
1534            // not direct mapping, check for missing required name
1535
if (!abs && name == null) {
1536                ctx.throwStartTagException("Non-abstract mapping must define " +
1537                    "an element name");
1538            }
1539            
1540            // check for optional label definition
1541
String JavaDoc label = ctx.attributeText(URI_ATTRIBUTES,
1542                COMMON_LABEL, null);
1543            
1544            // create definition context for namespaces and formats
1545
String JavaDoc base = ctx.attributeText(URI_ATTRIBUTES,
1546                MAPPING_EXTENDS, null);
1547            ObjectBinding bind = unmarshalObjectBinding(ctx, null,
1548                parent, type);
1549            NestedStructure nest = new NestedStructure(parent, bind,
1550                ctx.attributeBoolean(URI_ATTRIBUTES, COMMON_ORDERED, true),
1551                true, true);
1552            nest.unmarshal(ctx);
1553            
1554            // add all outer namespaces to context
1555
DefinitionContext defc = nest.getDefinitionContext();
1556            if (nss != null && nss.size() > 0) {
1557                for (int j = 0; j < nss.size(); j++) {
1558                    defc.addNamespace((NamespaceDefinition)nss.get(j));
1559                }
1560            }
1561            
1562            // unmarshal all contained binding information
1563
ctx.parsePastStartTag(URI_ELEMENTS, MAPPING_ELEMENT);
1564            unmarshalNamespaces(ctx, nest.getDefinitionContext());
1565            unmarshalFormats(ctx, nest.getDefinitionContext());
1566            unmarshalMappings(ctx, nest, null, uord);
1567            unmarshalStructureChildren(ctx, nest, bind, false,
1568                "java.lang.Object");
1569            
1570            // validate and configure actual binding definition
1571
bind.setWrappedComponent(nest);
1572            mapping = new MappingDefinition(parent, nest.getDefinitionContext(),
1573                type, name, abs, base, bind);
1574        
1575            // set label if defined
1576
if (label != null) {
1577                defc.addNamedStructure(label, bind);
1578            }
1579        }
1580        
1581        // finish by adding mapping and parsing past end tag
1582
parent.getDefinitionContext().addMapping(mapping);
1583        ctx.parsePastEndTag(URI_ELEMENTS, MAPPING_ELEMENT);
1584        return mapping;
1585    }
1586
1587    /**
1588     * Unmarshal included binding. This handles the actual include element along
1589     * with the actual included binding. The current implementation allows for
1590     * nested includes, but requires that all the included bindings use
1591     * compatible settings for the attributes of the root element, and only
1592     * allows mapping elements as children of the included bindings (no
1593     * namespace or format elements).
1594     *
1595     * @param ctx unmarshalling context information
1596     * @param bdef binding defintion at root of includes
1597     * @param root base URL for binding, or <code>null</code> if unknown
1598     * @param nss list of namespaces defined
1599     * @param paths set of binding paths processed
1600     * @throws JiBXException if error in unmarshalling
1601     */

1602
1603    public static void unmarshalInclude(UnmarshallingContext ctx,
1604        BindingDefinition bdef, URL JavaDoc root, ArrayList JavaDoc nss, HashSet JavaDoc paths)
1605        throws JiBXException {
1606        
1607        // make sure path hasn't already been processed
1608
ctx.parseToStartTag(URI_ELEMENTS, INCLUDE_ELEMENT);
1609        String JavaDoc path = ctx.attributeText(URI_ATTRIBUTES, INCLUDE_PATH);
1610        URL JavaDoc url;
1611        try {
1612            if (root == null) {
1613                url = new URL JavaDoc(path);
1614            } else {
1615                url = new URL JavaDoc(root, path);
1616            }
1617        } catch (MalformedURLException JavaDoc e) {
1618            throw new JiBXException("Unable to handle include path " + path, e);
1619        }
1620        String JavaDoc fpath = url.toExternalForm();
1621        if (paths.add(fpath)) {
1622            try {
1623                
1624                // access the included binding as input stream
1625
UnmarshallingContext ictx = new UnmarshallingContext(0,
1626                    new String JavaDoc[0], new String JavaDoc[0], new String JavaDoc[0], new String JavaDoc[0]);
1627                ictx.setDocument(url.openStream(), null);
1628                
1629                // check for compatible binding direction flags
1630
ictx.parseToStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1631                if (ictx.hasAttribute(URI_ATTRIBUTES, BINDING_DIRECTION)) {
1632                    int dir = ictx.attributeEnumeration(URI_ATTRIBUTES,
1633                        BINDING_DIRECTION, BINDINGDIR_NAMES, BINDINGDIR_NUMS,
1634                        DIRECTION_BOTH);
1635                    boolean compat = true;
1636                    switch (dir) {
1637                        case DIRECTION_BOTH:
1638                            if (!bdef.isInput() || !bdef.isOutput()) {
1639                                compat = false;
1640                            }
1641                            break;
1642                        case DIRECTION_INPUT:
1643                            if (!bdef.isInput() || bdef.isOutput()) {
1644                                compat = false;
1645                            }
1646                            break;
1647                        case DIRECTION_OUTPUT:
1648                            if (bdef.isInput() || !bdef.isOutput()) {
1649                                compat = false;
1650                            }
1651                            break;
1652                    }
1653                    if (!compat) {
1654                        throw new JiBXException("Incompatible binding direction " +
1655                            "option for included binding " + path);
1656                    }
1657                }
1658                
1659                // check other attribute values
1660
if (ictx.hasAttribute(URI_ATTRIBUTES, BINDING_PACKAGE)) {
1661                    throw new JiBXException(BINDING_PACKAGE +
1662                        " attribute not allowed on included binding " + path);
1663                }
1664                if (ictx.hasAttribute(URI_ATTRIBUTES, BINDING_FORWARDS)) {
1665                    throw new JiBXException(BINDING_FORWARDS +
1666                        " attribute not allowed on included binding " + path);
1667                }
1668                if (ictx.hasAttribute(URI_ATTRIBUTES, BINDING_TRACKING)) {
1669                    throw new JiBXException(BINDING_TRACKING +
1670                        " attribute not allowed on included binding " + path);
1671                }
1672                
1673                // check for nested includes
1674
ictx.parsePastStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1675                while (ictx.isAt(URI_ELEMENTS, INCLUDE_ELEMENT)) {
1676                    unmarshalInclude(ictx, bdef, url, nss, paths);
1677                }
1678                
1679                // process all mappings defined in included binding
1680
unmarshalMappings(ictx, bdef, nss, false);
1681                
1682            } catch (IOException JavaDoc e) {
1683                throw new JiBXException
1684                    ("Error accessing included binding with path " + path, e);
1685            }
1686        }
1687        
1688        // finish by skipping past end of tag in main binding
1689
ctx.parsePastEndTag(URI_ELEMENTS, INCLUDE_ELEMENT);
1690    }
1691    
1692    /**
1693     * Unmarshal binding definition. This handles the entire binding definition
1694     * document.
1695     *
1696     * @param ctx unmarshalling context information
1697     * @param name default name for binding
1698     * @param root base URL for binding, or <code>null</code> if unknown
1699     * @throws JiBXException if error in unmarshalling
1700     */

1701
1702    public static BindingDefinition unmarshalBindingDefinition
1703        (UnmarshallingContext ctx, String JavaDoc name, URL JavaDoc root)
1704        throws JiBXException {
1705        
1706        // start by reading optional binding name
1707
ctx.parseToStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1708        name = ctx.attributeText(URI_ATTRIBUTES, BINDING_NAME, name);
1709        
1710        // set the binding direction flags
1711
int dir = ctx.attributeEnumeration(URI_ATTRIBUTES, BINDING_DIRECTION,
1712            BINDINGDIR_NAMES, BINDINGDIR_NUMS, DIRECTION_BOTH);
1713        boolean ibind = dir == DIRECTION_BOTH || dir == DIRECTION_INPUT;
1714        boolean obind = dir == DIRECTION_BOTH || dir == DIRECTION_OUTPUT;
1715        
1716        // read other attribute values
1717
String JavaDoc auto = ctx.attributeText(URI_ATTRIBUTES, BINDING_AUTOPREFIX,
1718            BindingDefinition.DEFAULT_AUTOPREFIX);
1719        String JavaDoc tpack = ctx.attributeText(URI_ATTRIBUTES, BINDING_PACKAGE, null);
1720        boolean glob = ctx.attributeBoolean(URI_ATTRIBUTES,
1721            BINDING_GLOBALID, true);
1722        boolean forward = ctx.attributeBoolean(URI_ATTRIBUTES,
1723            BINDING_FORWARDS, true);
1724        boolean track = ctx.attributeBoolean(URI_ATTRIBUTES,
1725            BINDING_TRACKING, false);
1726        
1727        // create actual binding instance
1728
BindingDefinition bdef = new BindingDefinition(name, ibind, obind, auto,
1729            glob, forward, track);
1730        bdef.unmarshal(ctx);
1731        
1732        // unmarshal namespaces defined under root
1733
ctx.parsePastStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1734        ArrayList JavaDoc nss = new ArrayList JavaDoc();
1735        while (ctx.isAt(URI_ELEMENTS, NAMESPACE_ELEMENT)) {
1736            nss.add(unmarshalNamespace(ctx));
1737        }
1738        
1739        // process any included binding definitions
1740
HashSet JavaDoc paths = new HashSet JavaDoc();
1741        if (root != null) {
1742            paths.add(root.toExternalForm());
1743        }
1744        while (ctx.isAt(URI_ELEMENTS, INCLUDE_ELEMENT)) {
1745            unmarshalInclude(ctx, bdef, root, nss, paths);
1746        }
1747        
1748        // finish with common handling for elements which can be nested
1749
unmarshalFormats(ctx, bdef.getDefinitionContext());
1750        unmarshalMappings(ctx, bdef, nss, false);
1751        ctx.parsePastEndTag(URI_ELEMENTS, BINDING_ELEMENT);
1752        return bdef;
1753    }
1754    
1755    /**
1756     * Base class for containers. This just handles unmarshalling and checking
1757     * the values of attributes used by all containers. The container class
1758     * should set the appropriate default values for all these attributes in its
1759     * constructor, using <code>-1</code> (for <code>int</code> values) and
1760     * <code>null</code> (for <code>String</code> values) if the default is to
1761     * simply use setting inherited from a containing component. The binding
1762     * definition root object must always define actual values as the defaults,
1763     * since otherwise the code will fall off the end of the chain of ancestors.
1764     */

1765    
1766    /*package*/ static class ContainerBase {
1767        
1768        /** Containing binding component. */
1769        protected IContainer m_container;
1770        
1771        /** Default style for value expression. */
1772        protected int m_styleDefault;
1773    
1774        /** Auto-link style for default mappings. */
1775        protected int m_autoLink;
1776    
1777        /** Access level for default mappings. */
1778        protected int m_accessLevel;
1779    
1780        /** Prefix text to be stripped from names. */
1781        protected String JavaDoc m_stripPrefix;
1782    
1783        /** Suffix text to be stripped from names. */
1784        protected String JavaDoc m_stripSuffix;
1785    
1786        /** Style used for generating element or attribute names. */
1787        protected int m_nameStyle;
1788
1789        /**
1790         * Constructor.
1791         *
1792         * @param parent containing binding definition context
1793         * @param objc current object context
1794         * @param ord ordered content flag
1795         */

1796
1797        public ContainerBase(IContainer parent) {
1798            m_container = parent;
1799        }
1800
1801        /**
1802         * Unmarshal common container attributes.
1803         *
1804         * @param ctx unmarshalling context information
1805         * @throws JiBXException if error in unmarshalling
1806         */

1807
1808        public void unmarshal(UnmarshallingContext ctx) throws JiBXException {
1809            m_styleDefault = ctx.attributeEnumeration(URI_ATTRIBUTES,
1810                COMMON_STYLE, CONTAINING_STYLE_NAMES, CONTAINING_STYLE_NUMS,
1811                m_styleDefault);
1812            m_autoLink = ctx.attributeEnumeration(URI_ATTRIBUTES,
1813                COMMON_AUTOLINK, AUTO_LINK_NAMES, AUTO_LINK_NUMS, m_autoLink);
1814            m_accessLevel = ctx.attributeEnumeration(URI_ATTRIBUTES,
1815                COMMON_ACCESSLEVEL, ACCESS_LEVEL_NAMES, ACCESS_LEVEL_NUMS,
1816                m_accessLevel);
1817            m_stripPrefix = ctx.attributeText(URI_ATTRIBUTES,
1818                COMMON_STRIPPREFIX, m_stripPrefix);
1819            m_stripSuffix = ctx.attributeText(URI_ATTRIBUTES,
1820                COMMON_STRIPSUFFIX, m_stripSuffix);
1821            m_nameStyle = ctx.attributeEnumeration(URI_ATTRIBUTES,
1822                COMMON_NAMESTYLE, NAME_GENERATE_NAMES, NAME_GENERATE_NUMS,
1823                m_nameStyle);
1824        }
1825    
1826        //
1827
// IContainer interface method definitions (partial list)
1828

1829        public int getStyleDefault() {
1830            if (m_styleDefault >= 0) {
1831                return m_styleDefault;
1832            } else {
1833                return m_container.getStyleDefault();
1834            }
1835        }
1836    }
1837}
Popular Tags