Source Code Cross Referenced for BindingBuilder.java in  » XML » jibx-1.1.5 » org » jibx » binding » def » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » jibx 1.1.5 » org.jibx.binding.def 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:        Copyright (c) 2003-2006, Dennis M. Sosnoski
0003:        All rights reserved.
0004:
0005:        Redistribution and use in source and binary forms, with or without modification,
0006:        are permitted provided that the following conditions are met:
0007:
0008:         * Redistributions of source code must retain the above copyright notice, this
0009:           list of conditions and the following disclaimer.
0010:         * Redistributions in binary form must reproduce the above copyright notice,
0011:           this list of conditions and the following disclaimer in the documentation
0012:           and/or other materials provided with the distribution.
0013:         * Neither the name of JiBX nor the names of its contributors may be used
0014:           to endorse or promote products derived from this software without specific
0015:           prior written permission.
0016:
0017:        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
0018:        ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0019:        WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0020:        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
0021:        ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0022:        (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0023:        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
0024:        ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0025:        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0026:        SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0027:         */
0028:
0029:        package org.jibx.binding.def;
0030:
0031:        import java.io.IOException;
0032:        import java.net.MalformedURLException;
0033:        import java.net.URL;
0034:        import java.util.ArrayList;
0035:        import java.util.HashSet;
0036:
0037:        import org.apache.bcel.classfile.Utility;
0038:        import org.jibx.binding.classes.ClassCache;
0039:        import org.jibx.binding.classes.ClassFile;
0040:        import org.jibx.binding.classes.ClassItem;
0041:        import org.jibx.runtime.JiBXException;
0042:        import org.jibx.runtime.QName;
0043:        import org.jibx.runtime.impl.UnmarshallingContext;
0044:
0045:        /**
0046:         * Binding definition builder. This processes the binding definition file to
0047:         * generate the code generation structure.
0048:         *
0049:         * @author Dennis M. Sosnoski
0050:         * @version 1.0
0051:         */
0052:
0053:        public abstract class BindingBuilder {
0054:            /** Element namespace used for binding definition file. */
0055:            private static final String URI_ELEMENTS = null;
0056:
0057:            /** Attribute namespace used for binding definition file. */
0058:            private static final String URI_ATTRIBUTES = null;
0059:
0060:            /* Common style attribute. */
0061:            private static final String COMMON_STYLE = "value-style";
0062:
0063:            /* Common linkage attributes. */
0064:            private static final String COMMON_AUTOLINK = "auto-link";
0065:            private static final String COMMON_ACCESSLEVEL = "access-level";
0066:            private static final String COMMON_STRIPPREFIX = "strip-prefix";
0067:            private static final String COMMON_STRIPSUFFIX = "strip-suffix";
0068:            private static final String COMMON_NAMESTYLE = "name-style";
0069:
0070:            /* Common name attributes. */
0071:            private static final String COMMON_NAME = "name";
0072:            private static final String COMMON_NAMESPACE = "ns";
0073:
0074:            /* Common object attributes. */
0075:            private static final String COMMON_FACTORY = "factory";
0076:            private static final String COMMON_PRESET = "pre-set";
0077:            private static final String COMMON_POSTSET = "post-set";
0078:            private static final String COMMON_PREGET = "pre-get";
0079:            private static final String COMMON_MARSHALLER = "marshaller";
0080:            private static final String COMMON_UNMARSHALLER = "unmarshaller";
0081:            private static final String COMMON_CREATETYPE = "create-type";
0082:
0083:            /* Common property attributes. */
0084:            private static final String COMMON_FIELD = "field";
0085:            private static final String COMMON_TYPE = "type";
0086:            private static final String COMMON_USAGE = "usage";
0087:            private static final String COMMON_TESTMETHOD = "test-method";
0088:            private static final String COMMON_GETMETHOD = "get-method";
0089:            private static final String COMMON_SETMETHOD = "set-method";
0090:
0091:            /* Common string attributes. */
0092:            private static final String COMMON_DEFAULT = "default";
0093:            private static final String COMMON_SERIALIZER = "serializer";
0094:            private static final String COMMON_DESERIALIZER = "deserializer";
0095:
0096:            /* Common label attributes. */
0097:            private static final String COMMON_LABEL = "label";
0098:            private static final String COMMON_USING = "using";
0099:
0100:            /* Common ordered and choice attributes. */
0101:            private static final String COMMON_ORDERED = "ordered";
0102:            private static final String COMMON_CHOICE = "choice";
0103:            private static final String COMMON_FLEXIBLE = "flexible";
0104:            private static final String COMMON_DUPLICATES = "allow-repeats";
0105:
0106:            /* Common nillable attribute. */
0107:            private static final String COMMON_NILLABLE = "nillable";
0108:
0109:            /** Definitions for "binding" element use "BINDING" prefix. */
0110:            private static final String BINDING_ELEMENT = "binding";
0111:            private static final String BINDING_NAME = "name";
0112:            private static final String BINDING_DIRECTION = "direction";
0113:            private static final String BINDING_GLOBALID = "global-id";
0114:            private static final String BINDING_FORWARDS = "forwards";
0115:            private static final String BINDING_PACKAGE = "package";
0116:            private static final String BINDING_TRACKING = "track-source";
0117:            private static final String BINDING_FORCE = "force-classes";
0118:            // also COMMON_STYLE, and linkage group
0119:
0120:            /** Definitions for "namespace" element use "NAMESPACE" prefix. */
0121:            private static final String NAMESPACE_ELEMENT = "namespace";
0122:            private static final String NAMESPACE_URI = "uri";
0123:            private static final String NAMESPACE_PREFIX = "prefix";
0124:            private static final String NAMESPACE_DEFAULT = "default";
0125:
0126:            /** Definitions for "format" element use "FORMAT" prefix. */
0127:            private static final String FORMAT_ELEMENT = "format";
0128:            private static final String FORMAT_NAME = "label";
0129:            private static final String FORMAT_TYPE = "type";
0130:            // also string group
0131:
0132:            /** Definitions for "mapping" element use "MAPPING" prefix. */
0133:            private static final String MAPPING_ELEMENT = "mapping";
0134:            private static final String MAPPING_CLASS = "class";
0135:            private static final String MAPPING_ABSTRACT = "abstract";
0136:            private static final String MAPPING_EXTENDS = "extends";
0137:            private static final String MAPPING_TYPENAME = "type-name";
0138:            // also COMMON_STYLE, name, object, ordered, and linkage groups
0139:
0140:            /** Definitions for "value" element use "VALUE" prefix. */
0141:            private static final String VALUE_ELEMENT = "value";
0142:            private static final String VALUE_STYLE = "style";
0143:            private static final String VALUE_FORMAT = "format";
0144:            private static final String VALUE_CONSTANT = "constant";
0145:            private static final String VALUE_IDENT = "ident";
0146:            // also name, property, and string groups
0147:
0148:            /** Definitions for "structure" element use "STRUCTURE" prefix. */
0149:            private static final String STRUCTURE_ELEMENT = "structure";
0150:            private static final String STRUCTURE_MAPAS = "map-as";
0151:            // also COMMON_STYLE, name, object, ordered, property, and label groups
0152:
0153:            /** Definitions for "collection" element use "COLLECTION" prefix. */
0154:            private static final String COLLECTION_ELEMENT = "collection";
0155:            private static final String COLLECTION_LOADMETHOD = "load-method";
0156:            private static final String COLLECTION_SIZEMETHOD = "size-method";
0157:            private static final String COLLECTION_STOREMETHOD = "store-method";
0158:            private static final String COLLECTION_ADDMETHOD = "add-method";
0159:            private static final String COLLECTION_ITERMETHOD = "iter-method";
0160:            private static final String COLLECTION_ITEMTYPE = "item-type";
0161:            // also COMMON_STYLE, name, ordered, property, and label groups
0162:
0163:            /** Definitions for "include" element use "INCLUDE" prefix. */
0164:            private static final String INCLUDE_ELEMENT = "include";
0165:            private static final String INCLUDE_PATH = "path";
0166:
0167:            //
0168:            // Value style enumeration.
0169:
0170:            private static final String[] VALUE_STYLE_NAMES = { "attribute",
0171:                    "cdata", "element", "text" };
0172:            private static final int[] VALUE_STYLE_NUMS = {
0173:                    ValueChild.ATTRIBUTE_STYLE, ValueChild.CDATA_STYLE,
0174:                    ValueChild.ELEMENT_STYLE, ValueChild.TEXT_STYLE };
0175:
0176:            private static final String[] CONTAINING_STYLE_NAMES = {
0177:                    "attribute", "element" };
0178:            private static final int[] CONTAINING_STYLE_NUMS = {
0179:                    ValueChild.ATTRIBUTE_STYLE, ValueChild.ELEMENT_STYLE };
0180:
0181:            //
0182:            // Enumeration for auto-link types.
0183:
0184:            /*package*/static final int LINK_NONE = 0;
0185:            /*package*/static final int LINK_FIELDS = 1;
0186:            /*package*/static final int LINK_METHODS = 2;
0187:
0188:            private static final String[] AUTO_LINK_NAMES = { "fields", "none",
0189:                    "methods" };
0190:            private static final int[] AUTO_LINK_NUMS = { LINK_FIELDS,
0191:                    LINK_NONE, LINK_METHODS };
0192:
0193:            //
0194:            // Enumeration for access level.
0195:
0196:            /*package*/static final int ACC_PRIVATE = 0;
0197:            /*package*/static final int ACC_PACKAGE = 1;
0198:            /*package*/static final int ACC_PROTECTED = 2;
0199:            /*package*/static final int ACC_PUBLIC = 3;
0200:
0201:            private static final String[] ACCESS_LEVEL_NAMES = { "package",
0202:                    "private", "protected", "public" };
0203:            private static final int[] ACCESS_LEVEL_NUMS = { ACC_PACKAGE,
0204:                    ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC };
0205:
0206:            //
0207:            // Enumeration for name generation styles.
0208:
0209:            /*package*/static final int NAME_HYPHENS = 0;
0210:            /*package*/static final int NAME_MIXED = 1;
0211:
0212:            private static final String[] NAME_GENERATE_NAMES = { "hyphens",
0213:                    "mixed-case" };
0214:            private static final int[] NAME_GENERATE_NUMS = { NAME_HYPHENS,
0215:                    NAME_MIXED };
0216:
0217:            //
0218:            // Attributes that imply a component object
0219:
0220:            private static final String[] COMPONENT_OBJECT_NAMESPACES = {
0221:                    URI_ATTRIBUTES, URI_ATTRIBUTES, URI_ATTRIBUTES,
0222:                    URI_ATTRIBUTES };
0223:            private static final String[] COMPONENT_OBJECT_NAMES = {
0224:                    COMMON_FACTORY, COMMON_PRESET, COMMON_POSTSET,
0225:                    COMMON_PREGET };
0226:
0227:            //
0228:            // Enumeration for namespace usage.
0229:
0230:            private static final String[] NAMESPACEACCESS_NAMES = { "all",
0231:                    "attributes", "elements", "none" };
0232:            private static final int[] NAMESPACEACCESS_NUMS = {
0233:                    NamespaceDefinition.ALLDEFAULT_USAGE,
0234:                    NamespaceDefinition.ATTRIBUTES_USAGE,
0235:                    NamespaceDefinition.ELEMENTS_USAGE,
0236:                    NamespaceDefinition.NODEFAULT_USAGE };
0237:
0238:            //
0239:            // Ident type enumeration.
0240:
0241:            private static final String[] IDENTTYPE_NAMES = { "auto", "def",
0242:                    "direct", "ref" };
0243:            private static final int[] IDENTTYPE_NUMS = {
0244:                    ValueChild.AUTO_IDENT, ValueChild.DEF_IDENT,
0245:                    ValueChild.DIRECT_IDENT, ValueChild.REF_IDENT };
0246:
0247:            //
0248:            // Binding direction enumeration.
0249:
0250:            private static final int DIRECTION_INPUT = 0;
0251:            private static final int DIRECTION_OUTPUT = 1;
0252:            private static final int DIRECTION_BOTH = 2;
0253:
0254:            private static final String[] BINDINGDIR_NAMES = { "both", "input",
0255:                    "output" };
0256:            private static final int[] BINDINGDIR_NUMS = { DIRECTION_BOTH,
0257:                    DIRECTION_INPUT, DIRECTION_OUTPUT };
0258:
0259:            //
0260:            // Constants for property usage values
0261:
0262:            private static final String USAGE_OPTIONAL = "optional";
0263:            private static final String USAGE_REQUIRED = "required";
0264:
0265:            //
0266:            // Checking and code generation constants
0267:
0268:            private static final String UNMARSHALLER_INTERFACE = "org.jibx.runtime.IUnmarshaller";
0269:            private static final String MARSHALLER_INTERFACE = "org.jibx.runtime.IMarshaller";
0270:            private static final String UNMARSHALLER_INTERFACETYPE = "Lorg/jibx/runtime/IUnmarshaller;";
0271:            private static final String MARSHALLER_INTERFACETYPE = "Lorg/jibx/runtime/IMarshaller;";
0272:
0273:            /**
0274:             * Check if attributes supply a name definition.
0275:             *
0276:             * @param ctx unmarshalling context information
0277:             * @return <code>true</code> if attributes define a name,
0278:             * <code>false</code> if not
0279:             */
0280:
0281:            private static boolean isNamePresent(UnmarshallingContext ctx) {
0282:                return ctx.attributeText(URI_ATTRIBUTES, COMMON_NAME, null) != null;
0283:            }
0284:
0285:            /**
0286:             * Check for property definition present. Just checks the attributes of
0287:             * the current element.
0288:             *
0289:             * @param ctx unmarshalling context information
0290:             */
0291:
0292:            private static boolean isPropertyPresent(UnmarshallingContext ctx) {
0293:                return ctx.attributeText(URI_ATTRIBUTES, COMMON_FIELD, null) != null
0294:                        || ctx.attributeText(URI_ATTRIBUTES, COMMON_GETMETHOD,
0295:                                null) != null
0296:                        || ctx.attributeText(URI_ATTRIBUTES, COMMON_SETMETHOD,
0297:                                null) != null
0298:                        || ctx.attributeText(URI_ATTRIBUTES, COMMON_TESTMETHOD,
0299:                                null) != null;
0300:            }
0301:
0302:            /**
0303:             * Check if attributes define a direct object reference. Just checks the
0304:             * attributes of the current element.
0305:             *
0306:             * @param ctx unmarshalling context information
0307:             */
0308:
0309:            private static boolean isDirectObject(UnmarshallingContext ctx) {
0310:                return ctx.attributeText(URI_ATTRIBUTES, COMMON_MARSHALLER,
0311:                        null) != null
0312:                        || ctx.attributeText(URI_ATTRIBUTES,
0313:                                COMMON_UNMARSHALLER, null) != null;
0314:            }
0315:
0316:            /**
0317:             * Check if attributes define a mapping reference.
0318:             *
0319:             * @param ctx unmarshalling context information
0320:             * @return <code>true</code> if attributes define a mapping reference,
0321:             * <code>false</code> if not
0322:             * @throws JiBXException if error in unmarshalling
0323:             */
0324:
0325:            private static boolean isMappingRef(UnmarshallingContext ctx)
0326:                    throws JiBXException {
0327:                return ctx.hasAttribute(URI_ATTRIBUTES, STRUCTURE_MAPAS);
0328:            }
0329:
0330:            /**
0331:             * Check for component object present. Just checks the attributes of the
0332:             * current element, so this is not definitive - there may still be child
0333:             * binding definitions even without attributes.
0334:             *
0335:             * @param ctx unmarshalling context information
0336:             * @throws JiBXException if error in unmarshalling
0337:             */
0338:
0339:            private static boolean isObjectBinding(UnmarshallingContext ctx)
0340:                    throws JiBXException {
0341:                return ctx.hasAnyAttribute(COMPONENT_OBJECT_NAMESPACES,
0342:                        COMPONENT_OBJECT_NAMES);
0343:            }
0344:
0345:            /**
0346:             * Unmarshal name definition. This unmarshals directly from attributes of
0347:             * the current element.
0348:             *
0349:             * @param ctx unmarshalling context information
0350:             * @param attr flag for attribute name definition
0351:             * @throws JiBXException if error in unmarshalling
0352:             */
0353:
0354:            private static NameDefinition unmarshalName(
0355:                    UnmarshallingContext ctx, boolean attr)
0356:                    throws JiBXException {
0357:                String name = ctx.attributeText(URI_ATTRIBUTES, COMMON_NAME);
0358:                String ns = ctx.attributeText(URI_ATTRIBUTES, COMMON_NAMESPACE,
0359:                        null);
0360:                return new NameDefinition(name, ns, attr);
0361:            }
0362:
0363:            /**
0364:             * Unmarshal namespace definition.
0365:             *
0366:             * @param ctx unmarshalling context information
0367:             * @throws JiBXException if error in unmarshalling
0368:             */
0369:
0370:            private static NamespaceDefinition unmarshalNamespace(
0371:                    UnmarshallingContext ctx) throws JiBXException {
0372:
0373:                // set up the basic information
0374:                String uri = ctx.attributeText(URI_ATTRIBUTES, NAMESPACE_URI);
0375:                String prefix = ctx.attributeText(URI_ATTRIBUTES,
0376:                        NAMESPACE_PREFIX, null);
0377:                if ("".equals(prefix)) {
0378:                    prefix = null;
0379:                }
0380:
0381:                // check default usage attribute
0382:                int usage = ctx.attributeEnumeration(URI_ATTRIBUTES,
0383:                        NAMESPACE_DEFAULT, NAMESPACEACCESS_NAMES,
0384:                        NAMESPACEACCESS_NUMS,
0385:                        NamespaceDefinition.NODEFAULT_USAGE);
0386:
0387:                // finish parsing the element
0388:                ctx.parsePastEndTag(URI_ELEMENTS, NAMESPACE_ELEMENT);
0389:                return new NamespaceDefinition(uri, prefix, usage);
0390:            }
0391:
0392:            /**
0393:             * Unmarshal string conversion. Unmarshals conversion information directly
0394:             * from the attributes of the current start tag.
0395:             *
0396:             * @param ctx unmarshalling context information
0397:             * @param base conversion used as base for this conversion
0398:             * @param type fully qualified class name of type handled by conversion
0399:             * @throws JiBXException if error in unmarshalling
0400:             */
0401:
0402:            private static StringConversion unmarshalStringConversion(
0403:                    UnmarshallingContext ctx, StringConversion base, String type)
0404:                    throws JiBXException {
0405:                String dflt = ctx.attributeText(URI_ATTRIBUTES, COMMON_DEFAULT,
0406:                        null);
0407:                String ser = ctx.attributeText(URI_ATTRIBUTES,
0408:                        COMMON_SERIALIZER, null);
0409:                String dser = ctx.attributeText(URI_ATTRIBUTES,
0410:                        COMMON_DESERIALIZER, null);
0411:                return base.derive(type, ser, dser, dflt);
0412:            }
0413:
0414:            /**
0415:             * Check for optional property. Just checks for the attribute and makes sure
0416:             * it has a valid value if present, returning either the default or the
0417:             * defined value.
0418:             *
0419:             * @param ctx unmarshalling context information
0420:             * @return <code>true</code> if attribute present with value "true",
0421:             * <code>false</code> otherwise
0422:             * @throws JiBXException if error in unmarshalling
0423:             */
0424:
0425:            private static boolean isOptionalProperty(UnmarshallingContext ctx)
0426:                    throws JiBXException {
0427:                boolean opt = false;
0428:                String value = ctx.attributeText(URI_ATTRIBUTES, COMMON_USAGE,
0429:                        USAGE_REQUIRED);
0430:                if (USAGE_OPTIONAL.equals(value)) {
0431:                    opt = true;
0432:                } else if (!USAGE_REQUIRED.equals(value)) {
0433:                    ctx.throwStartTagException("Illegal value for \""
0434:                            + COMMON_USAGE + "\" attribute");
0435:                }
0436:                return opt;
0437:            }
0438:
0439:            /**
0440:             * Unmarshal property definition. This unmarshals directly from attributes
0441:             * of the current element.
0442:             *
0443:             * @param ctx unmarshalling context information
0444:             * @param parent containing binding definition structure
0445:             * @param cobj context object information
0446:             * @param opt force optional value flag
0447:             * @throws JiBXException if error in unmarshalling
0448:             */
0449:
0450:            private static PropertyDefinition unmarshalProperty(
0451:                    UnmarshallingContext ctx, IContainer parent,
0452:                    IContextObj cobj, boolean opt) throws JiBXException {
0453:
0454:                // read basic attribute values for property definition
0455:                String type = ctx.attributeText(URI_ATTRIBUTES, COMMON_TYPE,
0456:                        null);
0457:                if (!(parent instanceof  NestedCollection)
0458:                        && isOptionalProperty(ctx)) {
0459:                    opt = true;
0460:                }
0461:
0462:                // read and validate method and/or field attribute values
0463:                PropertyDefinition pdef = null;
0464:                try {
0465:                    String fname = ctx.attributeText(URI_ATTRIBUTES,
0466:                            COMMON_FIELD, null);
0467:                    String test = ctx.attributeText(URI_ATTRIBUTES,
0468:                            COMMON_TESTMETHOD, null);
0469:                    String get = ctx.attributeText(URI_ATTRIBUTES,
0470:                            COMMON_GETMETHOD, null);
0471:                    String set = ctx.attributeText(URI_ATTRIBUTES,
0472:                            COMMON_SETMETHOD, null);
0473:                    boolean isthis  = fname == null && get == null
0474:                            && set == null;
0475:                    pdef = new PropertyDefinition(parent, cobj, type, isthis ,
0476:                            opt, fname, test, get, set);
0477:
0478:                } catch (JiBXException ex) {
0479:
0480:                    // rethrow error message with position information
0481:                    ctx.throwStartTagException(ex.getMessage());
0482:                }
0483:                return pdef;
0484:            }
0485:
0486:            /**
0487:             * Unmarshal value definition. This handles the complete element supplying
0488:             * the value binding.
0489:             *
0490:             * @param ctx unmarshalling context information
0491:             * @param parent containing binding definition structure
0492:             * @param cobj context object information
0493:             * @param uord unordered collection member flag
0494:             * @param impl implicit value from collection flag
0495:             * @param itype base type for value
0496:             * @throws JiBXException if error in unmarshalling
0497:             */
0498:
0499:            private static ValueChild unmarshalValue(UnmarshallingContext ctx,
0500:                    IContainer parent, IContextObj cobj, boolean uord,
0501:                    boolean impl, String itype) throws JiBXException {
0502:
0503:                // find the style for this value
0504:                int style = ctx.attributeEnumeration(URI_ATTRIBUTES,
0505:                        VALUE_STYLE, VALUE_STYLE_NAMES, VALUE_STYLE_NUMS,
0506:                        parent.getStyleDefault());
0507:
0508:                // set up the basic structures
0509:                boolean isatt = style == ValueChild.ATTRIBUTE_STYLE;
0510:                NameDefinition name = null;
0511:                if (isatt || style == ValueChild.ELEMENT_STYLE) {
0512:                    name = unmarshalName(ctx, isatt);
0513:                    name.fixNamespace(parent.getDefinitionContext());
0514:                } else if (isNamePresent(ctx)) {
0515:                    ctx
0516:                            .throwStartTagException("Name not allowed for text or CDATA value");
0517:                }
0518:                String constant = ctx.attributeText(URI_ATTRIBUTES,
0519:                        VALUE_CONSTANT, null);
0520:
0521:                // handle property information (unless auto ident or implicit value)
0522:                int ident = ctx.attributeEnumeration(URI_ATTRIBUTES,
0523:                        VALUE_IDENT, IDENTTYPE_NAMES, IDENTTYPE_NUMS,
0524:                        ValueChild.DIRECT_IDENT);
0525:                PropertyDefinition prop = null;
0526:                if (ident == ValueChild.AUTO_IDENT) {
0527:                    ctx
0528:                            .throwStartTagException("Automatic id generation not yet supported");
0529:                } else if (impl) {
0530:                    String type = ctx.attributeText(URI_ATTRIBUTES,
0531:                            COMMON_TYPE, itype);
0532:                    prop = new PropertyDefinition(type, cobj,
0533:                            !(parent instanceof  NestedCollection)
0534:                                    && isOptionalProperty(ctx));
0535:                } else {
0536:                    prop = unmarshalProperty(ctx, parent, cobj, ctx
0537:                            .hasAttribute(URI_ATTRIBUTES, COMMON_DEFAULT));
0538:                    /*            if (constant == null && prop.isThis()) {
0539:                     ctx.throwStartTagException("No property for value");
0540:                     } else if (prop.isOptional()) {
0541:                     if (ident == ValueChild.DEF_IDENT) {
0542:                     ctx.throwStartTagException("Object ID cannot be optional");
0543:                     }
0544:                     } else if (uord) {
0545:                     ctx.throwStartTagException("All items in unordered " +
0546:                     "structure must be optional");
0547:                     }   */
0548:                }
0549:                if (ident != ValueChild.DIRECT_IDENT && uord) {
0550:                    ctx.throwStartTagException(VALUE_IDENT
0551:                            + " not allowed in unordered structure");
0552:                }
0553:
0554:                // find the basic converter to use
0555:                StringConversion convert = null;
0556:                String type = (prop == null || constant != null) ? "java.lang.String"
0557:                        : prop.getTypeName();
0558:                String format = ctx.attributeText(URI_ATTRIBUTES, VALUE_FORMAT,
0559:                        null);
0560:                DefinitionContext defc = parent.getDefinitionContext();
0561:                if (format == null) {
0562:
0563:                    // no format name, get specific convertor for type or best match
0564:                    convert = defc.getSpecificConversion(type);
0565:                    if (convert == null) {
0566:
0567:                        // find best match converter for type
0568:                        ClassFile target = ClassCache.getClassFile(type);
0569:                        convert = defc.getConversion(target);
0570:
0571:                        // check for a Java 5 enumeration
0572:                        boolean isenum = false;
0573:                        ClassFile sclas = target;
0574:                        while ((sclas = sclas.getSuperFile()) != null) {
0575:                            if (sclas.getName().equals("java.lang.Enum")) {
0576:                                isenum = true;
0577:                                break;
0578:                            }
0579:                        }
0580:
0581:                        // generate specific converter based on general form
0582:                        if (isenum) {
0583:                            String dser = type + '.' + "valueOf";
0584:                            convert = convert.derive(type, null, dser, null);
0585:                        } else if (convert.getTypeName().equals(
0586:                                "java.lang.Object")) {
0587:                            convert = new ObjectStringConversion(type,
0588:                                    (ObjectStringConversion) convert);
0589:                        }
0590:                    }
0591:
0592:                } else {
0593:
0594:                    // format name supplied, look it up and check compatibility
0595:                    QName qname = QName.deserialize(format, ctx);
0596:                    convert = defc.getNamedConversion(qname);
0597:                    if (convert == null) {
0598:                        ctx.throwStartTagException("Unknown format \"" + format
0599:                                + "\"");
0600:                    }
0601:                    String ctype = convert.getTypeName();
0602:                    if (!ClassItem.isAssignable(type, ctype)
0603:                            && !ClassItem.isAssignable(ctype, type)) {
0604:                        ctx
0605:                                .throwStartTagException("Converter type not compatible with value type");
0606:                    }
0607:                }
0608:
0609:                // check for any special conversion handling
0610:                String dflt = ctx.attributeText(URI_ATTRIBUTES, COMMON_DEFAULT,
0611:                        null);
0612:                String ser = ctx.attributeText(URI_ATTRIBUTES,
0613:                        COMMON_SERIALIZER, null);
0614:                String dser = ctx.attributeText(URI_ATTRIBUTES,
0615:                        COMMON_DESERIALIZER, null);
0616:                if (dflt != null || ser != null || dser != null) {
0617:                    convert = convert.derive(type, ser, dser, dflt);
0618:                }
0619:
0620:                // create the instance to be returned
0621:                boolean nillable = ctx.attributeBoolean(URI_ATTRIBUTES,
0622:                        COMMON_NILLABLE, false);
0623:                if (nillable) {
0624:                    parent.getBindingRoot().setSchemaInstanceUsed();
0625:                }
0626:                ValueChild value = new ValueChild(parent, cobj, name, prop,
0627:                        convert, style, ident, constant, nillable);
0628:
0629:                // handle identifier property flag
0630:                if (ident == ValueChild.DEF_IDENT
0631:                        || ident == ValueChild.AUTO_IDENT) {
0632:                    if (!cobj.setIdChild(value)) {
0633:                        ctx
0634:                                .throwStartTagException("Duplicate ID definition for containing mapping");
0635:                    } else if (!"java.lang.String".equals(type)) {
0636:                        ctx
0637:                                .throwStartTagException("ID property must be a String");
0638:                    }
0639:                }
0640:
0641:                // finish with skipping past end tag
0642:                ctx.parsePastEndTag(URI_ELEMENTS, VALUE_ELEMENT);
0643:                return value;
0644:            }
0645:
0646:            /**
0647:             * Unmarshal direct object component. Just constructs the component to
0648:             * be returned along with the supporting objects, and verifies that no
0649:             * disallowed properties are present.
0650:             *
0651:             * @param ctx unmarshalling context information
0652:             * @param type fully qualified class name of object type handled
0653:             * @param parent containing binding definition structure
0654:             * @param defc definition context to be used (if separate from parent,
0655:             * otherwise <code>null</code>)
0656:             * @param slot marshaller/unmarshaller slot number
0657:             * @param name element name information (<code>null</code> if no element
0658:             * name)
0659:             * @return constructed direct object component
0660:             * @throws JiBXException if error in unmarshalling
0661:             */
0662:
0663:            private static DirectObject unmarshalDirectObj(
0664:                    UnmarshallingContext ctx, String type, IContainer parent,
0665:                    DefinitionContext defc, int slot, NameDefinition name)
0666:                    throws JiBXException {
0667:
0668:                // define and validate marshaller
0669:                ClassFile mcf = null;
0670:                if (parent.getBindingRoot().isOutput()) {
0671:                    String clas = ctx.attributeText(URI_ATTRIBUTES,
0672:                            COMMON_MARSHALLER);
0673:                    mcf = ClassCache.getClassFile(clas);
0674:                    if (!mcf.isImplements(MARSHALLER_INTERFACETYPE)) {
0675:                        ctx.throwStartTagException("Marshaller class " + clas
0676:                                + " does not implement required interface "
0677:                                + MARSHALLER_INTERFACE);
0678:                    }
0679:                }
0680:
0681:                // define and validate unmarshaller
0682:                ClassFile ucf = null;
0683:                if (parent.getBindingRoot().isInput()) {
0684:                    String clas = ctx.attributeText(URI_ATTRIBUTES,
0685:                            COMMON_UNMARSHALLER);
0686:                    ucf = ClassCache.getClassFile(clas);
0687:                    if (!ucf.isImplements(UNMARSHALLER_INTERFACETYPE)) {
0688:                        ctx.throwStartTagException("Unmarshaller class " + clas
0689:                                + " does not implement required interface "
0690:                                + UNMARSHALLER_INTERFACE);
0691:                    }
0692:                }
0693:
0694:                // make sure none of the prohibited attributes are present
0695:                if (isObjectBinding(ctx)) {
0696:                    ctx.throwStartTagException("Other object attributes not "
0697:                            + "allowed when using marshaller or unmarshaller");
0698:                } else if (isMappingRef(ctx)) {
0699:                    ctx.throwStartTagException("Mapping not allowed when "
0700:                            + "using marshaller or unmarshaller");
0701:                } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
0702:                    ctx
0703:                            .throwStartTagException(COMMON_USING
0704:                                    + " attribute not allowed when using marshaller or unmarshaller");
0705:                }
0706:
0707:                // return constructed instance
0708:                return new DirectObject(parent, defc, ClassCache
0709:                        .getClassFile(type), false, mcf, ucf, slot, name);
0710:            }
0711:
0712:            /**
0713:             * Unmarshal mapping reference component. Just constructs the component to
0714:             * be returned along with the supporting objects, and verifies that no
0715:             * disallowed properties are present.
0716:             *
0717:             * @param ctx unmarshalling context information
0718:             * @param parent containing binding definition structure
0719:             * @param objc current object context
0720:             * @param prop property definition
0721:             * @param name reference name definition (only allowed with abstract
0722:             * mappings)
0723:             * @return constructed mapping reference component
0724:             * @throws JiBXException if error in unmarshalling
0725:             */
0726:            private static IComponent unmarshalMappingRef(
0727:                    UnmarshallingContext ctx, IContainer parent,
0728:                    IContextObj objc, PropertyDefinition prop,
0729:                    NameDefinition name) throws JiBXException {
0730:
0731:                // make sure no forbidden attributes are present
0732:                if (isObjectBinding(ctx)) {
0733:                    ctx.throwStartTagException("Other object attributes not "
0734:                            + "allowed when using mapping reference");
0735:                } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
0736:                    ctx
0737:                            .throwStartTagException(COMMON_USING
0738:                                    + " attribute not allowed when using mapping reference");
0739:                }
0740:
0741:                // build the actual component to be returned
0742:                String type = (prop == null) ? null : prop.getTypeName();
0743:                String text = ctx.attributeText(URI_ATTRIBUTES,
0744:                        STRUCTURE_MAPAS, type);
0745:                QName qname = QName.deserialize(text, ctx);
0746:                boolean nillable = ctx.attributeBoolean(URI_ATTRIBUTES,
0747:                        COMMON_NILLABLE, false);
0748:                if (nillable) {
0749:                    parent.getBindingRoot().setSchemaInstanceUsed();
0750:                }
0751:                return new MappingReference(parent, prop, type, text, qname
0752:                        .toString(), objc, name, false, nillable);
0753:            }
0754:
0755:            /**
0756:             * Unmarshal structure reference component. Just constructs the component to
0757:             * be returned along with the supporting objects, and verifies that no
0758:             * disallowed properties are present.
0759:             *
0760:             * @param ctx unmarshalling context information
0761:             * @param contain containing binding component
0762:             * @param name element name information (<code>null</code> if no element
0763:             * name)
0764:             * @param prop property definition (<code>null</code> if no separate
0765:             * property)
0766:             * @param cobj context object
0767:             * @return constructed structure reference component
0768:             * @throws JiBXException if error in unmarshalling
0769:             */
0770:            private static IComponent unmarshalStructureRef(
0771:                    UnmarshallingContext ctx, IContainer contain,
0772:                    NameDefinition name, PropertyDefinition prop,
0773:                    IContextObj cobj) throws JiBXException {
0774:
0775:                // make sure no forbidden attributes are present
0776:                if (isObjectBinding(ctx)) {
0777:                    ctx.throwStartTagException("Other object attributes not "
0778:                            + "allowed when using structure reference");
0779:                }
0780:
0781:                // build the actual component to be returned
0782:                String ident = ctx.attributeText(URI_ATTRIBUTES, COMMON_USING);
0783:                IComponent comp = new StructureReference(contain, ident, prop,
0784:                        name != null, cobj);
0785:                if (name != null) {
0786:                    boolean nillable = ctx.attributeBoolean(URI_ATTRIBUTES,
0787:                            COMMON_NILLABLE, false);
0788:                    if (nillable) {
0789:                        contain.getBindingRoot().setSchemaInstanceUsed();
0790:                    }
0791:                    comp = new ElementWrapper(contain.getDefinitionContext(),
0792:                            name, comp, nillable);
0793:                    if (prop != null && prop.isOptional()) {
0794:                        ((ElementWrapper) comp).setOptionalNormal(true);
0795:                        ((ElementWrapper) comp).setStructureObject(true);
0796:                        comp = new OptionalStructureWrapper(comp, prop, true);
0797:                        prop.setOptional(false);
0798:                    }
0799:                }
0800:                return comp;
0801:            }
0802:
0803:            /**
0804:             * Unmarshal child bindings for a nested structure definition.
0805:             *
0806:             * @param ctx unmarshalling context information
0807:             * @param nest nested structure definition
0808:             * @param objc context object definition
0809:             * @param impl property value implicit flag
0810:             * @param itype item type for child components
0811:             * @throws JiBXException if error in unmarshalling
0812:             */
0813:
0814:            private static void unmarshalStructureChildren(
0815:                    UnmarshallingContext ctx, NestedBase nest,
0816:                    IContextObj objc, boolean impl, String itype)
0817:                    throws JiBXException {
0818:                boolean uord = !nest.isContentOrdered();
0819:                while (true) {
0820:
0821:                    // unmarshal next child binding definition
0822:                    IComponent comp;
0823:                    if (ctx.isAt(URI_ELEMENTS, VALUE_ELEMENT)) {
0824:                        ValueChild child = unmarshalValue(ctx, nest, objc,
0825:                                uord, impl, itype);
0826:                        comp = child;
0827:                    } else if (ctx.isAt(URI_ELEMENTS, STRUCTURE_ELEMENT)) {
0828:                        comp = unmarshalStructure(ctx, nest, objc, false, uord,
0829:                                impl);
0830:                    } else if (ctx.isAt(URI_ELEMENTS, COLLECTION_ELEMENT)) {
0831:                        comp = unmarshalStructure(ctx, nest, objc, true, uord,
0832:                                impl);
0833:                    } else {
0834:                        break;
0835:                    }
0836:
0837:                    // add component to structure
0838:                    nest.addComponent(comp);
0839:                }
0840:            }
0841:
0842:            /**
0843:             * Unmarshal object binding component. Just constructs the component to
0844:             * be returned along with the supporting objects. This handles both the
0845:             * unmarshalling of attributes, and of nested binding components.
0846:             *
0847:             * @param ctx unmarshalling context information
0848:             * @param parent containing binding definition structure
0849:             * @param objc current object context
0850:             * @param type fully qualified name of object class
0851:             * @return constructed structure reference component
0852:             * @throws JiBXException if error in unmarshalling
0853:             */
0854:
0855:            private static ObjectBinding unmarshalObjectBinding(
0856:                    UnmarshallingContext ctx, IContextObj objc,
0857:                    IContainer parent, String type) throws JiBXException {
0858:
0859:                // set method names from attributes of start tag
0860:                String fact = ctx.attributeText(URI_ATTRIBUTES, COMMON_FACTORY,
0861:                        null);
0862:                String pres = ctx.attributeText(URI_ATTRIBUTES, COMMON_PRESET,
0863:                        null);
0864:                String posts = ctx.attributeText(URI_ATTRIBUTES,
0865:                        COMMON_POSTSET, null);
0866:                String preg = ctx.attributeText(URI_ATTRIBUTES, COMMON_PREGET,
0867:                        null);
0868:                String ctype = ctx.attributeText(URI_ATTRIBUTES,
0869:                        COMMON_CREATETYPE, null);
0870:                ObjectBinding bind = null;
0871:                try {
0872:                    bind = new ObjectBinding(parent, objc, type, fact, pres,
0873:                            posts, preg, ctype);
0874:                } catch (JiBXException ex) {
0875:                    ctx.throwStartTagException(ex.getMessage(), ex);
0876:                }
0877:                return bind;
0878:            }
0879:
0880:            /**
0881:             * Unmarshal namespace definitions. Any namespace definitions present are
0882:             * unmarshalled and added to the supplied definition context.
0883:             *
0884:             * @param ctx unmarshalling context information
0885:             * @param defc definition context for defined namespaces
0886:             * @throws JiBXException if error in unmarshalling
0887:             */
0888:
0889:            private static void unmarshalNamespaces(UnmarshallingContext ctx,
0890:                    DefinitionContext defc) throws JiBXException {
0891:                while (ctx.isAt(URI_ELEMENTS, NAMESPACE_ELEMENT)) {
0892:                    defc.addNamespace(unmarshalNamespace(ctx));
0893:                }
0894:            }
0895:
0896:            /**
0897:             * Unmarshal format definitions. Any format definitions present are
0898:             * unmarshalled and added to the supplied definition context.
0899:             *
0900:             * @param ctx unmarshalling context information
0901:             * @param defc definition context for defined formats
0902:             * @throws JiBXException if error in unmarshalling
0903:             */
0904:
0905:            private static void unmarshalFormats(UnmarshallingContext ctx,
0906:                    DefinitionContext defc) throws JiBXException {
0907:
0908:                // process all format definitions at level
0909:                while (ctx.isAt(URI_ELEMENTS, FORMAT_ELEMENT)) {
0910:
0911:                    // find the current default format information for type
0912:                    String type = ctx
0913:                            .attributeText(URI_ATTRIBUTES, FORMAT_TYPE);
0914:                    String sig = Utility.getSignature(type);
0915:                    StringConversion base = null;
0916:                    if (sig.length() == 1) {
0917:
0918:                        // must be a primitive, check type directly
0919:                        base = defc.getSpecificConversion(type);
0920:                        if (base == null) {
0921:                            ctx.throwStartTagException("Unsupported \""
0922:                                    + FORMAT_TYPE + "\" value");
0923:                        }
0924:
0925:                    } else {
0926:
0927:                        // must be an object type, find best match
0928:                        ClassFile cf = ClassCache.getClassFile(type);
0929:                        base = defc.getConversion(cf);
0930:
0931:                    }
0932:
0933:                    // unmarshal with defaults provided by existing format
0934:                    StringConversion format = unmarshalStringConversion(ctx,
0935:                            base, type);
0936:
0937:                    // handle based on presence or absence of name attribute
0938:                    String text = ctx.attributeText(URI_ATTRIBUTES,
0939:                            FORMAT_NAME, null);
0940:                    if (text == null) {
0941:                        defc.setConversion(format);
0942:                    } else {
0943:                        QName qname = QName.deserialize(text, ctx);
0944:                        defc.setNamedConversion(qname, format);
0945:                    }
0946:
0947:                    // scan past end of definition
0948:                    ctx.parsePastEndTag(URI_ELEMENTS, FORMAT_ELEMENT);
0949:                }
0950:            }
0951:
0952:            /**
0953:             * Unmarshal mapping definitions. Any mapping definitions present are
0954:             * unmarshalled and added to the supplied definition context.
0955:             *
0956:             * @param ctx unmarshalling context information
0957:             * @param parent containing binding definition structure
0958:             * @param nss extra namespaces to be included in this mapping definition
0959:             * (may be <code>null</code>)
0960:             * @param uord container is unordered structure flag
0961:             * @throws JiBXException if error in unmarshalling
0962:             */
0963:
0964:            private static void unmarshalMappings(UnmarshallingContext ctx,
0965:                    IContainer parent, ArrayList nss, boolean uord)
0966:                    throws JiBXException {
0967:                while (ctx.isAt(URI_ELEMENTS, MAPPING_ELEMENT)) {
0968:                    unmarshalMapping(ctx, parent, nss, uord);
0969:                }
0970:            }
0971:
0972:            /**
0973:             * Unmarshal subclass instance for structure definition. This handles all
0974:             * combinations of attributes on the start tag, generating the appropriate
0975:             * structure of nested components and other classes to represent the binding
0976:             * information within the current element. This must be called with the
0977:             * parse positioned at the start tag of the element to be unmarshalled.
0978:             * 
0979:             * TODO: At least split this up, or organize a better way to build binding
0980:             *
0981:             * @param ctx unmarshalling context information
0982:             * @param contain containing binding definition structure
0983:             * @param cobj context object information
0984:             * @param coll collection structure flag
0985:             * @param uord container is unordered structure flag
0986:             * @param implic property value implicit flag
0987:             * @return root of component tree constructed from binding
0988:             * @throws JiBXException if error in unmarshalling
0989:             */
0990:
0991:            public static IComponent unmarshalStructure(
0992:                    UnmarshallingContext ctx, IContainer contain,
0993:                    IContextObj cobj, boolean coll, boolean uord, boolean implic)
0994:                    throws JiBXException {
0995:
0996:                // get name definition if supplied (check later to see if valid)
0997:                NameDefinition name = null;
0998:                if (isNamePresent(ctx)) {
0999:                    name = unmarshalName(ctx, false);
1000:                }
1001:
1002:                // check for optional flag on structure
1003:                boolean opt = isOptionalProperty(ctx);
1004:                boolean incoll = false;
1005:                if (contain instanceof  NestedCollection) {
1006:                    incoll = true;
1007:                    opt = false;
1008:                }
1009:
1010:                // check for property definition supplied
1011:                IComponent comp;
1012:                boolean hasprop = isPropertyPresent(ctx);
1013:                boolean this ref = false;
1014:                if (!hasprop) {
1015:                    this ref = incoll
1016:                            || ctx.hasAttribute(URI_ATTRIBUTES, COMMON_TYPE);
1017:                }
1018:                boolean mapping = isMappingRef(ctx);
1019:                if (hasprop || coll || implic || this ref) {
1020:
1021:                    // set up the property definition to be used
1022:                    PropertyDefinition prop = null;
1023:                    boolean hasobj = hasprop;
1024:                    if (implic) {
1025:
1026:                        // make sure no override of implicit property from collection
1027:                        if (hasprop) {
1028:                            ctx
1029:                                    .throwStartTagException("Property definition not "
1030:                                            + "allowed for collection items");
1031:                        } else {
1032:                            String type = ctx.attributeText(URI_ATTRIBUTES,
1033:                                    COMMON_TYPE, null);
1034:                            if (type == null) {
1035:                                if (!mapping) {
1036:                                    if (incoll) {
1037:                                        type = ((NestedCollection) contain)
1038:                                                .getItemType();
1039:                                        hasobj = true;
1040:                                    } else {
1041:                                        type = "java.lang.Object";
1042:                                    }
1043:                                }
1044:                            } else {
1045:                                hasobj = true;
1046:                            }
1047:                            prop = new PropertyDefinition(type, cobj, opt);
1048:                        }
1049:
1050:                    } else if (hasprop || this ref) {
1051:                        prop = unmarshalProperty(ctx, contain, cobj, opt);
1052:                    } else {
1053:                        prop = new PropertyDefinition(cobj, opt);
1054:                    }
1055:
1056:                    // check if using direct object marshalling and unmarshalling
1057:                    if (isDirectObject(ctx)) {
1058:
1059:                        // validate and configure direct marshalling and unmarshalling
1060:                        comp = new DirectProperty(prop, unmarshalDirectObj(ctx,
1061:                                prop.getTypeName(), contain, null, -1, name));
1062:
1063:                    } else if (mapping) {
1064:
1065:                        // validate and configure reference to mapping in context
1066:                        comp = unmarshalMappingRef(ctx, contain, cobj, prop,
1067:                                name);
1068:
1069:                    } else {
1070:
1071:                        // check for object binding needed
1072:                        IContextObj icobj = cobj;
1073:                        ObjectBinding bind = null;
1074:                        boolean typed = false;
1075:                        if (implic) {
1076:                            typed = !prop.getTypeName().equals(
1077:                                    "java.lang.Object");
1078:                        } else {
1079:                            typed = !prop.getTypeName().equals(
1080:                                    cobj.getBoundClass().getClassName());
1081:                        }
1082:                        if ((hasobj && !prop.isThis()) || (!hasobj && typed)) {
1083:                            bind = unmarshalObjectBinding(ctx, cobj, contain,
1084:                                    prop.getTypeName());
1085:                            icobj = bind;
1086:                        }
1087:
1088:                        // validate and configure reference to structure in context
1089:                        if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
1090:                            comp = unmarshalStructureRef(ctx, contain, name,
1091:                                    prop, icobj);
1092:                        } else {
1093:
1094:                            // validate and configure actual binding definition
1095:                            DefinitionContext defc = contain
1096:                                    .getDefinitionContext();
1097:                            IComponent top = bind;
1098:
1099:                            // check for optional label definition
1100:                            String label = ctx.attributeText(URI_ATTRIBUTES,
1101:                                    COMMON_LABEL, null);
1102:
1103:                            // set load and store handlers for collection
1104:                            NestedCollection.CollectionLoad load = null;
1105:                            NestedCollection.CollectionStore store = null;
1106:                            String itype = null;
1107:                            if (coll) {
1108:
1109:                                // get any method names and type supplied by user
1110:                                String stname = ctx.attributeText(
1111:                                        URI_ATTRIBUTES, COLLECTION_STOREMETHOD,
1112:                                        null);
1113:                                String aname = ctx.attributeText(
1114:                                        URI_ATTRIBUTES, COLLECTION_ADDMETHOD,
1115:                                        null);
1116:                                String lname = ctx.attributeText(
1117:                                        URI_ATTRIBUTES, COLLECTION_LOADMETHOD,
1118:                                        null);
1119:                                String szname = ctx.attributeText(
1120:                                        URI_ATTRIBUTES, COLLECTION_SIZEMETHOD,
1121:                                        null);
1122:                                String iname = ctx.attributeText(
1123:                                        URI_ATTRIBUTES, COLLECTION_ITERMETHOD,
1124:                                        null);
1125:                                itype = ctx
1126:                                        .attributeText(URI_ATTRIBUTES,
1127:                                                COLLECTION_ITEMTYPE,
1128:                                                "java.lang.Object");
1129:
1130:                                // verify combinations of attributes supplied
1131:                                if ((lname == null || szname == null)
1132:                                        && !(lname == null && szname == null)) {
1133:                                    ctx
1134:                                            .throwStartTagException(COLLECTION_LOADMETHOD
1135:                                                    + " and "
1136:                                                    + COLLECTION_SIZEMETHOD
1137:                                                    + " attributes must be used together");
1138:                                }
1139:                                if (iname != null && lname != null) {
1140:                                    ctx
1141:                                            .throwStartTagException(COLLECTION_ITERMETHOD
1142:                                                    + " and "
1143:                                                    + COLLECTION_LOADMETHOD
1144:                                                    + " attributes cannot be used together");
1145:                                }
1146:                                if (aname != null && stname != null) {
1147:                                    ctx
1148:                                            .throwStartTagException(COLLECTION_ADDMETHOD
1149:                                                    + " and "
1150:                                                    + COLLECTION_STOREMETHOD
1151:                                                    + " attributes cannot be used together");
1152:                                }
1153:
1154:                                // set defaults based on collection type
1155:                                ClassFile cf = ClassCache.getClassFile(prop
1156:                                        .getTypeName());
1157:                                if (cf.isSuperclass("java.util.Vector")
1158:                                        || cf
1159:                                                .isSuperclass("java.util.ArrayList")) {
1160:                                    if (stname == null && aname == null) {
1161:                                        aname = "add";
1162:                                    }
1163:                                    if (iname == null && lname == null) {
1164:                                        lname = "get";
1165:                                        szname = "size";
1166:                                    }
1167:                                } else if (cf
1168:                                        .isImplements("Ljava/util/Collection;")) {
1169:                                    if (stname == null && aname == null) {
1170:                                        aname = "add";
1171:                                    }
1172:                                    if (iname == null && lname == null) {
1173:                                        iname = "iterator";
1174:                                    }
1175:                                } else if (cf.isArray()) {
1176:                                    String ptype = prop.getTypeName();
1177:                                    itype = ptype.substring(0,
1178:                                            ptype.length() - 2);
1179:                                }
1180:
1181:                                // check binding direction(s)
1182:                                BindingDefinition bdef = contain
1183:                                        .getBindingRoot();
1184:                                boolean isdoub = "long".equals(itype)
1185:                                        || "double".equals(itype);
1186:                                if (bdef.isInput()) {
1187:
1188:                                    // define strategy for adding items to collection
1189:                                    if (aname != null) {
1190:                                        ClassItem meth = cf.getBestMethod(
1191:                                                aname, null,
1192:                                                new String[] { itype });
1193:                                        if (meth == null) {
1194:                                            ctx
1195:                                                    .throwStartTagException("Add method "
1196:                                                            + aname
1197:                                                            + " not found in collection type "
1198:                                                            + cf.getName());
1199:                                        }
1200:                                        boolean hasval = !"void".equals(meth
1201:                                                .getTypeName());
1202:                                        store = new NestedCollection.AddStore(
1203:                                                meth, isdoub, hasval);
1204:                                    } else if (stname != null) {
1205:                                        ClassItem meth = cf.getBestMethod(
1206:                                                stname, null, new String[] {
1207:                                                        "int", itype });
1208:                                        if (meth == null) {
1209:                                            ctx
1210:                                                    .throwStartTagException("Indexed store method "
1211:                                                            + stname
1212:                                                            + " not found in collection type "
1213:                                                            + cf.getName());
1214:                                        }
1215:                                        boolean hasval = !"void".equals(meth
1216:                                                .getTypeName());
1217:                                        store = new NestedCollection.IndexedStore(
1218:                                                meth, isdoub, hasval);
1219:                                    } else if (cf.isArray()) {
1220:                                        store = new NestedCollection.ArrayStore(
1221:                                                itype, isdoub);
1222:                                    } else {
1223:                                        ctx
1224:                                                .throwStartTagException("Unknown collection "
1225:                                                        + "type with no add or store method defined");
1226:                                    }
1227:
1228:                                }
1229:                                if (bdef.isOutput()) {
1230:
1231:                                    // define strategy for loading items from collection
1232:                                    if (lname != null) {
1233:                                        ClassItem smeth = cf.getMethod(szname,
1234:                                                "()I");
1235:                                        if (smeth == null) {
1236:                                            ctx
1237:                                                    .throwStartTagException("Size method "
1238:                                                            + szname
1239:                                                            + " not found in collection type "
1240:                                                            + cf.getName());
1241:                                        }
1242:                                        ClassItem lmeth = cf.getBestMethod(
1243:                                                lname, itype,
1244:                                                new String[] { "int" });
1245:                                        if (lmeth == null) {
1246:                                            ctx
1247:                                                    .throwStartTagException("Load method "
1248:                                                            + lname
1249:                                                            + " not found in collection type "
1250:                                                            + cf.getName());
1251:                                        }
1252:                                        load = new NestedCollection.IndexedLoad(
1253:                                                smeth, isdoub, lmeth);
1254:                                    } else if (iname != null) {
1255:                                        String mname = "hasNext";
1256:                                        String nname = "next";
1257:                                        ClassItem meth = cf.getMethod(iname,
1258:                                                "()Ljava/util/Iterator;");
1259:                                        if (meth == null) {
1260:                                            mname = "hasMoreElements";
1261:                                            nname = "nextElement";
1262:                                            meth = cf
1263:                                                    .getMethod(iname,
1264:                                                            "()Ljava/util/Enumeration;");
1265:                                            if (meth == null) {
1266:                                                ctx
1267:                                                        .throwStartTagException("Iterator method "
1268:                                                                + iname
1269:                                                                + " not found in collection type "
1270:                                                                + cf.getName());
1271:                                            }
1272:                                        }
1273:                                        load = new NestedCollection.IteratorLoad(
1274:                                                meth, isdoub,
1275:                                                "java.util.Iterator." + mname,
1276:                                                "java.util.Iterator." + nname);
1277:                                    } else if (cf.isArray()) {
1278:                                        load = new NestedCollection.ArrayLoad(
1279:                                                itype, isdoub);
1280:                                    } else {
1281:                                        ctx
1282:                                                .throwStartTagException("Unknown collection "
1283:                                                        + "type with no load method defined");
1284:                                    }
1285:                                }
1286:
1287:                            }
1288:
1289:                            // unmarshal basics of nested structure
1290:                            NestedBase nest;
1291:                            boolean ordered = ctx.attributeBoolean(
1292:                                    URI_ATTRIBUTES, COMMON_ORDERED, true);
1293:                            boolean flex = ctx.attributeBoolean(URI_ATTRIBUTES,
1294:                                    COMMON_FLEXIBLE, false);
1295:                            boolean nillable = ctx.attributeBoolean(
1296:                                    URI_ATTRIBUTES, COMMON_NILLABLE, false);
1297:                            if (nillable) {
1298:                                contain.getBindingRoot()
1299:                                        .setSchemaInstanceUsed();
1300:                            }
1301:                            if (coll) {
1302:
1303:                                // create collection definition
1304:                                nest = new NestedCollection(contain, icobj,
1305:                                        ordered, opt, flex, itype, load, store);
1306:                                nest.unmarshal(ctx);
1307:                                ctx.parsePastStartTag(URI_ELEMENTS,
1308:                                        COLLECTION_ELEMENT);
1309:
1310:                            } else {
1311:
1312:                                // create structure definition
1313:                                boolean choice = ctx.attributeBoolean(
1314:                                        URI_ATTRIBUTES, COMMON_CHOICE, false);
1315:                                boolean dupl = ctx.attributeBoolean(
1316:                                        URI_ATTRIBUTES, COMMON_DUPLICATES,
1317:                                        false);
1318:                                nest = new NestedStructure(contain, icobj,
1319:                                        ordered, choice, flex, false, hasobj,
1320:                                        dupl);
1321:                                nest.unmarshal(ctx);
1322:                                ctx.parsePastStartTag(URI_ELEMENTS,
1323:                                        STRUCTURE_ELEMENT);
1324:                            }
1325:
1326:                            // unmarshal child bindings with optional label
1327:                            String ctype = (itype == null) ? "java.lang.Object"
1328:                                    : itype;
1329:                            unmarshalFormats(ctx, nest.getDefinitionContext());
1330:                            unmarshalMappings(ctx, contain, null, uord);
1331:                            unmarshalStructureChildren(ctx, nest, icobj, coll
1332:                                    | (implic && !hasobj), ctype);
1333:                            if (top == null) {
1334:                                top = nest;
1335:                            }
1336:
1337:                            // special check for structure wrapping value
1338:                            boolean impstruct = false;
1339:                            boolean childs = nest.hasContent();
1340:                            if (implic && !coll && childs) {
1341:                                ArrayList contents = nest.getContents();
1342:                                impstruct = true;
1343:                                for (int i = 0; i < contents.size(); i++) {
1344:                                    if (!(contents.get(i) instanceof  ValueChild)) {
1345:                                        impstruct = false;
1346:                                        break;
1347:                                    } else {
1348:                                        ValueChild vchild = (ValueChild) contents
1349:                                                .get(i);
1350:                                        if (!vchild.isImplicit()) {
1351:                                            impstruct = false;
1352:                                            break;
1353:                                        }
1354:                                    }
1355:                                }
1356:                            }
1357:                            if (impstruct) {
1358:                                comp = nest;
1359:                                nest.setObjectContext(cobj);
1360:                                if (name != null) {
1361:                                    comp = new ElementWrapper(defc, name, comp,
1362:                                            nillable);
1363:                                    if (bind != null && implic) {
1364:                                        if (!hasprop) {
1365:                                            ArrayList contents = nest
1366:                                                    .getContents();
1367:                                            impstruct = true;
1368:                                            for (int i = 0; i < contents.size(); i++) {
1369:                                                if (contents.get(i) instanceof  ValueChild) {
1370:                                                    ValueChild vchild = (ValueChild) contents
1371:                                                            .get(i);
1372:                                                    vchild.switchProperty();
1373:                                                }
1374:                                            }
1375:                                        }
1376:                                        prop.setOptional(false);
1377:                                    }
1378:                                }
1379:                            } else {
1380:
1381:                                // check for children defined
1382:                                boolean addref = false;
1383:                                if (!childs) {
1384:                                    if (coll) {
1385:
1386:                                        // add mapping as only child
1387:                                        if (ctype.equals("java.lang.Object")) {
1388:                                            nest
1389:                                                    .addComponent(new DirectGeneric(
1390:                                                            nest, null));
1391:                                        } else {
1392:                                            nest
1393:                                                    .addComponent(new MappingReference(
1394:                                                            contain,
1395:                                                            new PropertyDefinition(
1396:                                                                    ctype,
1397:                                                                    cobj, false),
1398:                                                            ctype, null, null,
1399:                                                            icobj, null, true,
1400:                                                            false));
1401:                                        }
1402:                                        childs = true;
1403:
1404:                                    } else if (name != null) {
1405:
1406:                                        // must be abstract mappping reference, create child
1407:                                        addref = true;
1408:
1409:                                    }
1410:                                }
1411:
1412:                                // handle nested children
1413:                                comp = top;
1414:                                if (childs || addref) {
1415:
1416:                                    // define component property wrapping object binding
1417:                                    boolean optprop = hasprop
1418:                                            && prop.isOptional();
1419:                                    if (bind != null) {
1420:                                        boolean skip = name != null && optprop;
1421:                                        comp = new ComponentProperty(prop,
1422:                                                comp, skip);
1423:                                        bind.setWrappedComponent(nest);
1424:                                    }
1425:
1426:                                    // create reference to mapping as special case
1427:                                    //  this allows structure with name but no children to
1428:                                    //  use abstract mapping
1429:                                    if (addref) {
1430:                                        PropertyDefinition this prop = new PropertyDefinition(
1431:                                                bind, false);
1432:                                        nest.addComponent(new MappingReference(
1433:                                                nest, this prop, comp.getType(),
1434:                                                null, null, icobj, null, false,
1435:                                                false));
1436:                                    }
1437:                                    if (name != null) {
1438:                                        comp = new ElementWrapper(defc, name,
1439:                                                comp, nillable);
1440:                                        if (bind != null && implic) {
1441:                                            if (!hasprop) {
1442:                                                ((ElementWrapper) comp)
1443:                                                        .setDirect(true);
1444:                                            }
1445:                                            prop.setOptional(false);
1446:                                        }
1447:                                        if (optprop) {
1448:                                            ((ElementWrapper) comp)
1449:                                                    .setOptionalNormal(true);
1450:                                            boolean isobj = bind != null;
1451:                                            ((ElementWrapper) comp)
1452:                                                    .setStructureObject(isobj);
1453:                                            ((ElementWrapper) comp)
1454:                                                    .setDirect(isobj);
1455:                                            comp = new OptionalStructureWrapper(
1456:                                                    comp, prop, isobj);
1457:                                            prop.setOptional(false);
1458:                                        } else if (opt && !implic) {
1459:                                            ((ElementWrapper) comp)
1460:                                                    .setOptionalNormal(true);
1461:                                            comp = new OptionalStructureWrapper(
1462:                                                    comp, prop, false);
1463:                                            prop.setOptional(false);
1464:                                        }
1465:                                    }
1466:
1467:                                } else {
1468:
1469:                                    // treat as mapping, with either type or generic
1470:                                    String type = prop.getTypeName();
1471:                                    if (prop.equals("java.lang.Object")) {
1472:                                        comp = new ComponentProperty(
1473:                                                prop,
1474:                                                new DirectGeneric(contain, null),
1475:                                                false);
1476:                                    } else {
1477:                                        comp = new MappingReference(contain,
1478:                                                prop, type, null, null, icobj,
1479:                                                name, false, false);
1480:                                    }
1481:                                }
1482:                            }
1483:
1484:                            // set object binding as definition for label
1485:                            if (label != null) {
1486:                                defc.addNamedStructure(label, top);
1487:                            }
1488:                        }
1489:                    }
1490:
1491:                } else {
1492:
1493:                    // structure with no separate object, verify no forbidden attributes
1494:                    if (isObjectBinding(ctx)) {
1495:                        ctx.throwStartTagException("Object attributes not "
1496:                                + "allowed without property definition");
1497:                    } else if (isDirectObject(ctx)) {
1498:                        ctx
1499:                                .throwStartTagException("Marshaller and unmarshaller not "
1500:                                        + "allowed without property definition");
1501:                    }
1502:
1503:                    // check for reference to structure defined elsewhere
1504:                    if (mapping) {
1505:
1506:                        // handle "this" reference as anonymous property
1507:                        PropertyDefinition prop = new PropertyDefinition(cobj,
1508:                                opt);
1509:
1510:                        // handle reference to defined mapping
1511:                        comp = unmarshalMappingRef(ctx, contain, cobj, prop,
1512:                                name);
1513:                        implic = true;
1514:
1515:                    } else if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_USING)) {
1516:
1517:                        // make sure forbidden attribute not used
1518:                        if (ctx.hasAttribute(URI_ATTRIBUTES, COMMON_ORDERED)) {
1519:                            ctx.throwStartTagException(COMMON_ORDERED
1520:                                    + " attribute " + " not allowed with "
1521:                                    + COMMON_USING + " attribute");
1522:                        }
1523:
1524:                        // validate and configure reference to structure in context
1525:                        comp = unmarshalStructureRef(ctx, contain, name, null,
1526:                                cobj);
1527:
1528:                    } else {
1529:
1530:                        // unmarshal children as nested structure
1531:                        boolean ordered = ctx.attributeBoolean(URI_ATTRIBUTES,
1532:                                COMMON_ORDERED, true);
1533:                        boolean choice = ctx.attributeBoolean(URI_ATTRIBUTES,
1534:                                COMMON_CHOICE, false);
1535:                        boolean flex = ctx.attributeBoolean(URI_ATTRIBUTES,
1536:                                COMMON_FLEXIBLE, false);
1537:                        boolean dupl = ctx.attributeBoolean(URI_ATTRIBUTES,
1538:                                COMMON_DUPLICATES, false);
1539:                        NestedStructure nest = new NestedStructure(contain,
1540:                                cobj, ordered, choice, flex, false, hasprop,
1541:                                dupl);
1542:                        nest.unmarshal(ctx);
1543:
1544:                        // unmarshal child bindings with optional label
1545:                        String label = ctx.attributeText(URI_ATTRIBUTES,
1546:                                COMMON_LABEL, null);
1547:                        ctx.parsePastStartTag(URI_ELEMENTS, STRUCTURE_ELEMENT);
1548:                        unmarshalFormats(ctx, nest.getDefinitionContext());
1549:                        unmarshalMappings(ctx, contain, null, uord);
1550:                        unmarshalStructureChildren(ctx, nest, cobj, false,
1551:                                "java.lang.Object");
1552:
1553:                        // check for children defined
1554:                        DefinitionContext defc = contain.getDefinitionContext();
1555:                        if (nest.hasContent()) {
1556:
1557:                            // build structure to access children or with elment wrapper
1558:                            if (name == null) {
1559:                                comp = nest;
1560:                            } else {
1561:                                comp = new ElementWrapper(defc, name, nest,
1562:                                        false);
1563:                                if (opt) {
1564:                                    ((ElementWrapper) comp)
1565:                                            .setOptionalNormal(true);
1566:                                    ((ElementWrapper) comp)
1567:                                            .setStructureObject(true);
1568:                                }
1569:                            }
1570:                            if (label != null) {
1571:                                defc.addNamedStructure(label, nest);
1572:                            }
1573:
1574:                        } else {
1575:
1576:                            // make sure there's a name defined
1577:                            if (name == null) {
1578:                                ctx
1579:                                        .throwException("Property, name, or child component required");
1580:                            }
1581:
1582:                            // treat as throwaway portion of document
1583:                            comp = new ElementWrapper(defc, name, null, false);
1584:                            if (opt) {
1585:                                ((ElementWrapper) comp)
1586:                                        .setOptionalIgnored(true);
1587:                            }
1588:
1589:                        }
1590:                    }
1591:                }
1592:
1593:                // finish by parsing past end tag
1594:                ctx.parsePastEndTag(URI_ELEMENTS, coll ? COLLECTION_ELEMENT
1595:                        : STRUCTURE_ELEMENT);
1596:                return comp;
1597:            }
1598:
1599:            /**
1600:             * Unmarshal mapping definition. This handles all combinations of attributes
1601:             * on the start tag, generating the appropriate structure of nested
1602:             * components and other classes to represent the binding information within
1603:             * the current element. This must be called with the parse positioned at the
1604:             * start tag of the element to be unmarshalled.
1605:             *
1606:             * @param ctx unmarshalling context information
1607:             * @param parent containing binding definition structure
1608:             * @param nss extra namespaces to be included in this mapping definition
1609:             * (may be <code>null</code>)
1610:             * @param uord container is unordered structure flag
1611:             * @return mapping definition constructed from binding
1612:             * @throws JiBXException if error in unmarshalling
1613:             */
1614:
1615:            public static IMapping unmarshalMapping(UnmarshallingContext ctx,
1616:                    IContainer parent, ArrayList nss, boolean uord)
1617:                    throws JiBXException {
1618:
1619:                // first check for an abstract mapping
1620:                boolean abs = ctx.attributeBoolean(URI_ATTRIBUTES,
1621:                        MAPPING_ABSTRACT, false);
1622:                String type = ctx.attributeText(URI_ATTRIBUTES, MAPPING_CLASS);
1623:
1624:                // get name definition if supplied
1625:                NameDefinition name = null;
1626:                if (isNamePresent(ctx)) {
1627:                    name = unmarshalName(ctx, false);
1628:                }
1629:
1630:                // get type name information
1631:                String text = ctx.attributeText(URI_ATTRIBUTES,
1632:                        MAPPING_TYPENAME, null);
1633:                String tname = null;
1634:                if (text != null) {
1635:                    tname = QName.deserialize(text, ctx).toString();
1636:                }
1637:
1638:                // check if using direct object marshalling and unmarshalling
1639:                IMapping mapping;
1640:                if (isDirectObject(ctx)) {
1641:
1642:                    // check for definition context needed
1643:                    DefinitionContext defc = null;
1644:                    if (nss != null && nss.size() > 0) {
1645:
1646:                        // add all outer namespaces to context
1647:                        defc = new DefinitionContext(parent);
1648:                        if (nss != null && nss.size() > 0) {
1649:                            for (int j = 0; j < nss.size(); j++) {
1650:                                defc.addNamespace((NamespaceDefinition) nss
1651:                                        .get(j));
1652:                            }
1653:                        }
1654:                    }
1655:
1656:                    // validate and configure direct marshalling and unmarshalling
1657:                    int slot = parent.getBindingRoot()
1658:                            .getMappedClassIndex(type);
1659:                    mapping = new MappingDirect(parent, type, tname,
1660:                            unmarshalDirectObj(ctx, type, parent, defc, slot,
1661:                                    name), abs);
1662:
1663:                } else {
1664:
1665:                    // not direct mapping, check for missing required name
1666:                    if (!abs && name == null) {
1667:                        ctx
1668:                                .throwStartTagException("Non-abstract mapping must define "
1669:                                        + "an element name");
1670:                    }
1671:
1672:                    // check for optional definitions
1673:                    String label = ctx.attributeText(URI_ATTRIBUTES,
1674:                            COMMON_LABEL, null);
1675:
1676:                    // create definition context for namespaces and formats
1677:                    String base = ctx.attributeText(URI_ATTRIBUTES,
1678:                            MAPPING_EXTENDS, null);
1679:                    ObjectBinding bind = unmarshalObjectBinding(ctx, null,
1680:                            parent, type);
1681:                    boolean ordered = ctx.attributeBoolean(URI_ATTRIBUTES,
1682:                            COMMON_ORDERED, true);
1683:                    boolean choice = ctx.attributeBoolean(URI_ATTRIBUTES,
1684:                            COMMON_CHOICE, false);
1685:                    boolean flex = ctx.attributeBoolean(URI_ATTRIBUTES,
1686:                            COMMON_FLEXIBLE, false);
1687:                    boolean nillable = ctx.attributeBoolean(URI_ATTRIBUTES,
1688:                            COMMON_NILLABLE, false);
1689:                    if (nillable) {
1690:                        parent.getBindingRoot().setSchemaInstanceUsed();
1691:                    }
1692:                    boolean dupl = ctx.attributeBoolean(URI_ATTRIBUTES,
1693:                            COMMON_DUPLICATES, false);
1694:                    NestedStructure nest = new NestedStructure(parent, bind,
1695:                            ordered, choice, flex, true, true, dupl);
1696:                    nest.unmarshal(ctx);
1697:
1698:                    // add all outer namespaces to context
1699:                    DefinitionContext defc = nest.getDefinitionContext();
1700:                    if (nss != null && nss.size() > 0) {
1701:                        for (int j = 0; j < nss.size(); j++) {
1702:                            defc.addNamespace((NamespaceDefinition) nss.get(j));
1703:                        }
1704:                    }
1705:
1706:                    // unmarshal all contained binding information
1707:                    ctx.parsePastStartTag(URI_ELEMENTS, MAPPING_ELEMENT);
1708:                    unmarshalNamespaces(ctx, nest.getDefinitionContext());
1709:                    unmarshalFormats(ctx, nest.getDefinitionContext());
1710:                    unmarshalMappings(ctx, nest, null, uord);
1711:                    unmarshalStructureChildren(ctx, nest, bind, false,
1712:                            "java.lang.Object");
1713:
1714:                    // validate and configure actual binding definition
1715:                    bind.setWrappedComponent(nest);
1716:                    mapping = new MappingDefinition(parent, nest
1717:                            .getDefinitionContext(), type, name, tname, abs,
1718:                            base, bind, nillable);
1719:
1720:                    // set label if defined
1721:                    if (label != null) {
1722:                        defc.addNamedStructure(label, bind);
1723:                    }
1724:                }
1725:
1726:                // finish by adding mapping and parsing past end tag
1727:                parent.getDefinitionContext().addMapping(mapping);
1728:                ctx.parsePastEndTag(URI_ELEMENTS, MAPPING_ELEMENT);
1729:                return mapping;
1730:            }
1731:
1732:            /**
1733:             * Unmarshal included binding. This handles the actual include element along
1734:             * with the actual included binding. The current implementation allows for
1735:             * nested includes, but requires that all the included bindings use
1736:             * compatible settings for the attributes of the root element, and only
1737:             * allows mapping elements as children of the included bindings (no
1738:             * namespace or format elements).
1739:             *
1740:             * @param ctx unmarshalling context information
1741:             * @param bdef binding defintion at root of includes
1742:             * @param root base URL for binding, or <code>null</code> if unknown
1743:             * @param nslist list of namespaces defined
1744:             * @param paths set of binding paths processed
1745:             * @throws JiBXException if error in unmarshalling
1746:             */
1747:
1748:            public static void unmarshalInclude(UnmarshallingContext ctx,
1749:                    BindingDefinition bdef, URL root, ArrayList nslist,
1750:                    HashSet paths) throws JiBXException {
1751:
1752:                // make sure path hasn't already been processed
1753:                ctx.parseToStartTag(URI_ELEMENTS, INCLUDE_ELEMENT);
1754:                String path = ctx.attributeText(URI_ATTRIBUTES, INCLUDE_PATH);
1755:                URL url;
1756:                try {
1757:                    if (root == null) {
1758:                        url = new URL(path);
1759:                    } else {
1760:                        url = new URL(root, path);
1761:                    }
1762:                } catch (MalformedURLException e) {
1763:                    throw new JiBXException("Unable to handle include path "
1764:                            + path, e);
1765:                }
1766:                String fpath = url.toExternalForm();
1767:                if (paths.add(fpath)) {
1768:                    try {
1769:
1770:                        // access the included binding as input stream
1771:                        UnmarshallingContext ictx = new UnmarshallingContext();
1772:                        ictx.setDocument(url.openStream(), null);
1773:
1774:                        // unmarshal namespaces (to apply to these mappings, only)
1775:                        ictx.parseToStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1776:                        ictx.parsePastStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1777:                        ArrayList nss = new ArrayList(nslist);
1778:                        while (ictx.isAt(URI_ELEMENTS, NAMESPACE_ELEMENT)) {
1779:                            nss.add(unmarshalNamespace(ictx));
1780:                        }
1781:
1782:                        // process any format definitions (for global context)
1783:                        unmarshalFormats(ictx, bdef.getDefinitionContext());
1784:
1785:                        // check for nested includes
1786:                        while (ictx.isAt(URI_ELEMENTS, INCLUDE_ELEMENT)) {
1787:                            unmarshalInclude(ictx, bdef, url, nss, paths);
1788:                        }
1789:
1790:                        // process all mappings defined in included binding
1791:                        unmarshalMappings(ictx, bdef, nss, false);
1792:
1793:                    } catch (IOException e) {
1794:                        throw new JiBXException(
1795:                                "Error accessing included binding with path "
1796:                                        + path, e);
1797:                    }
1798:                }
1799:
1800:                // finish by skipping past end of tag in main binding
1801:                ctx.parsePastEndTag(URI_ELEMENTS, INCLUDE_ELEMENT);
1802:            }
1803:
1804:            /**
1805:             * Unmarshal binding definition. This handles the entire binding definition
1806:             * document.
1807:             *
1808:             * @param ctx unmarshalling context information
1809:             * @param name default name for binding
1810:             * @param root base URL for binding, or <code>null</code> if unknown
1811:             * @throws JiBXException if error in unmarshalling
1812:             */
1813:
1814:            public static BindingDefinition unmarshalBindingDefinition(
1815:                    UnmarshallingContext ctx, String name, URL root)
1816:                    throws JiBXException {
1817:
1818:                // start by reading optional binding name
1819:                ctx.parseToStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1820:                name = ctx.attributeText(URI_ATTRIBUTES, BINDING_NAME, name);
1821:
1822:                // set the binding direction flags
1823:                int dir = ctx.attributeEnumeration(URI_ATTRIBUTES,
1824:                        BINDING_DIRECTION, BINDINGDIR_NAMES, BINDINGDIR_NUMS,
1825:                        DIRECTION_BOTH);
1826:                boolean ibind = dir == DIRECTION_BOTH || dir == DIRECTION_INPUT;
1827:                boolean obind = dir == DIRECTION_BOTH
1828:                        || dir == DIRECTION_OUTPUT;
1829:
1830:                // read other attribute values
1831:                String tpack = ctx.attributeText(URI_ATTRIBUTES,
1832:                        BINDING_PACKAGE, null);
1833:                boolean glob = ctx.attributeBoolean(URI_ATTRIBUTES,
1834:                        BINDING_GLOBALID, true);
1835:                boolean forward = ctx.attributeBoolean(URI_ATTRIBUTES,
1836:                        BINDING_FORWARDS, true);
1837:                boolean track = ctx.attributeBoolean(URI_ATTRIBUTES,
1838:                        BINDING_TRACKING, false);
1839:                boolean force = ctx.attributeBoolean(URI_ATTRIBUTES,
1840:                        BINDING_FORCE, false);
1841:
1842:                // create actual binding instance
1843:                BindingDefinition bdef = new BindingDefinition(name, ibind,
1844:                        obind, tpack, glob, forward, track, force);
1845:                bdef.unmarshal(ctx);
1846:
1847:                // unmarshal namespaces and formats defined under root
1848:                ctx.parsePastStartTag(URI_ELEMENTS, BINDING_ELEMENT);
1849:                ArrayList nss = new ArrayList();
1850:                while (ctx.isAt(URI_ELEMENTS, NAMESPACE_ELEMENT)) {
1851:                    nss.add(unmarshalNamespace(ctx));
1852:                }
1853:                unmarshalFormats(ctx, bdef.getDefinitionContext());
1854:
1855:                // process any included binding definitions
1856:                HashSet paths = new HashSet();
1857:                if (root != null) {
1858:                    paths.add(root.toExternalForm());
1859:                }
1860:                while (ctx.isAt(URI_ELEMENTS, INCLUDE_ELEMENT)) {
1861:                    unmarshalInclude(ctx, bdef, root, nss, paths);
1862:                }
1863:
1864:                // finish with common handling for elements which can be nested
1865:                unmarshalMappings(ctx, bdef, nss, false);
1866:                ctx.parsePastEndTag(URI_ELEMENTS, BINDING_ELEMENT);
1867:                return bdef;
1868:            }
1869:
1870:            /**
1871:             * Base class for containers. This just handles unmarshalling and checking
1872:             * the values of attributes used by all containers. The container class
1873:             * should set the appropriate default values for all these attributes in its
1874:             * constructor, using <code>-1</code> (for <code>int</code> values) and
1875:             * <code>null</code> (for <code>String</code> values) if the default is to
1876:             * simply use setting inherited from a containing component. The binding
1877:             * definition root object must always define actual values as the defaults,
1878:             * since otherwise the code will fall off the end of the chain of ancestors.
1879:             */
1880:
1881:            /*package*/static class ContainerBase {
1882:
1883:                /** Containing binding component. */
1884:                protected IContainer m_container;
1885:
1886:                /** Default style for value expression. */
1887:                protected int m_styleDefault;
1888:
1889:                /** Auto-link style for default mappings. */
1890:                protected int m_autoLink;
1891:
1892:                /** Access level for default mappings. */
1893:                protected int m_accessLevel;
1894:
1895:                /** Prefix text to be stripped from names. */
1896:                protected String m_stripPrefix;
1897:
1898:                /** Suffix text to be stripped from names. */
1899:                protected String m_stripSuffix;
1900:
1901:                /** Style used for generating element or attribute names. */
1902:                protected int m_nameStyle;
1903:
1904:                /**
1905:                 * Constructor.
1906:                 *
1907:                 * @param parent containing binding definition context
1908:                 */
1909:
1910:                public ContainerBase(IContainer parent) {
1911:                    m_container = parent;
1912:                }
1913:
1914:                /**
1915:                 * Unmarshal common container attributes.
1916:                 *
1917:                 * @param ctx unmarshalling context information
1918:                 * @throws JiBXException if error in unmarshalling
1919:                 */
1920:
1921:                public void unmarshal(UnmarshallingContext ctx)
1922:                        throws JiBXException {
1923:                    m_styleDefault = ctx.attributeEnumeration(URI_ATTRIBUTES,
1924:                            COMMON_STYLE, CONTAINING_STYLE_NAMES,
1925:                            CONTAINING_STYLE_NUMS, m_styleDefault);
1926:                    m_autoLink = ctx.attributeEnumeration(URI_ATTRIBUTES,
1927:                            COMMON_AUTOLINK, AUTO_LINK_NAMES, AUTO_LINK_NUMS,
1928:                            m_autoLink);
1929:                    m_accessLevel = ctx.attributeEnumeration(URI_ATTRIBUTES,
1930:                            COMMON_ACCESSLEVEL, ACCESS_LEVEL_NAMES,
1931:                            ACCESS_LEVEL_NUMS, m_accessLevel);
1932:                    m_stripPrefix = ctx.attributeText(URI_ATTRIBUTES,
1933:                            COMMON_STRIPPREFIX, m_stripPrefix);
1934:                    m_stripSuffix = ctx.attributeText(URI_ATTRIBUTES,
1935:                            COMMON_STRIPSUFFIX, m_stripSuffix);
1936:                    m_nameStyle = ctx.attributeEnumeration(URI_ATTRIBUTES,
1937:                            COMMON_NAMESTYLE, NAME_GENERATE_NAMES,
1938:                            NAME_GENERATE_NUMS, m_nameStyle);
1939:                }
1940:
1941:                //
1942:                // IContainer interface method definitions (partial list)
1943:
1944:                public int getStyleDefault() {
1945:                    if (m_styleDefault >= 0) {
1946:                        return m_styleDefault;
1947:                    } else {
1948:                        return m_container.getStyleDefault();
1949:                    }
1950:                }
1951:            }
1952:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.