Source Code Cross Referenced for SchemaGenerator.java in  » XML » jibx-1.1.5 » org » jibx » binding » generator » 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.generator 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:        Copyright (c) 2007, 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.generator;
0030:
0031:        import java.io.IOException;
0032:        import java.io.InputStream;
0033:        import java.lang.reflect.InvocationTargetException;
0034:        import java.lang.reflect.Method;
0035:        import java.util.AbstractList;
0036:        import java.util.ArrayList;
0037:        import java.util.Collection;
0038:        import java.util.HashMap;
0039:        import java.util.Iterator;
0040:        import java.util.List;
0041:        import java.util.Map;
0042:
0043:        import org.jibx.binding.model.CollectionElement;
0044:        import org.jibx.binding.model.ContainerElementBase;
0045:        import org.jibx.binding.model.DocumentFormatter;
0046:        import org.jibx.binding.model.IClass;
0047:        import org.jibx.binding.model.IClassItem;
0048:        import org.jibx.binding.model.IClassLocator;
0049:        import org.jibx.binding.model.IComponent;
0050:        import org.jibx.binding.model.MappingElement;
0051:        import org.jibx.binding.model.StructureElement;
0052:        import org.jibx.binding.model.StructureElementBase;
0053:        import org.jibx.binding.model.TemplateElementBase;
0054:        import org.jibx.binding.model.ValidationContext;
0055:        import org.jibx.binding.model.ValidationProblem;
0056:        import org.jibx.binding.model.ValueElement;
0057:        import org.jibx.runtime.QName;
0058:        import org.jibx.schema.ISchemaResolver;
0059:        import org.jibx.schema.TreeWalker;
0060:        import org.jibx.schema.elements.AllElement;
0061:        import org.jibx.schema.elements.AnnotatedBase;
0062:        import org.jibx.schema.elements.AnnotationElement;
0063:        import org.jibx.schema.elements.AttributeElement;
0064:        import org.jibx.schema.elements.AttributeGroupElement;
0065:        import org.jibx.schema.elements.AttributeGroupRefElement;
0066:        import org.jibx.schema.elements.ChoiceElement;
0067:        import org.jibx.schema.elements.CommonCompositorDefinition;
0068:        import org.jibx.schema.elements.ComplexContentElement;
0069:        import org.jibx.schema.elements.ComplexExtensionElement;
0070:        import org.jibx.schema.elements.ComplexTypeElement;
0071:        import org.jibx.schema.elements.DocumentationElement;
0072:        import org.jibx.schema.elements.ElementElement;
0073:        import org.jibx.schema.elements.GroupElement;
0074:        import org.jibx.schema.elements.GroupRefElement;
0075:        import org.jibx.schema.elements.SchemaElement;
0076:        import org.jibx.schema.elements.SequenceElement;
0077:        import org.jibx.schema.elements.SimpleContentElement;
0078:        import org.jibx.schema.elements.SimpleRestrictionElement;
0079:        import org.jibx.schema.elements.SimpleTypeElement;
0080:        import org.jibx.schema.elements.FacetElement.Enumeration;
0081:        import org.jibx.schema.types.Count;
0082:        import org.jibx.schema.validation.PrevalidationVisitor;
0083:        import org.jibx.schema.validation.RegistrationVisitor;
0084:        import org.jibx.schema.validation.ValidationVisitor;
0085:        import org.jibx.util.Types;
0086:        import org.w3c.dom.Node;
0087:
0088:        /**
0089:         * Schema generator from binding definition.
0090:         */
0091:        public class SchemaGenerator {
0092:            /** Locator for class information (<code>null</code> if none). */
0093:            private final IClassLocator m_locator;
0094:
0095:            /** Binding customization information. */
0096:            private final GlobalCustom m_custom;
0097:
0098:            /** Document used for annotations (<code>null</code> if none). */
0099:            private final DocumentFormatter m_formatter;
0100:
0101:            /** Map from fully-qualified class name to qualified simple type name. */
0102:            private final Map m_simpleTypeMap;
0103:
0104:            /** Map from namespace to schema holder. */
0105:            private final Map m_uriSchemaMap;
0106:
0107:            /** Validation context for bindings. */
0108:            private final ValidationContext m_context;
0109:
0110:            /** Details for mappings and enum usages. */
0111:            private final SchemaDetailDirectory m_detailDirectory;
0112:
0113:            /**
0114:             * Constructor.
0115:             * 
0116:             * @param loc locator for class information (<code>null</code> if none)
0117:             * @param custom binding customization information (used for creating names
0118:             * as needed)
0119:             */
0120:            public SchemaGenerator(IClassLocator loc, GlobalCustom custom) {
0121:                m_locator = loc;
0122:                if (loc == null) {
0123:                    m_formatter = null;
0124:                } else {
0125:                    m_formatter = new DocumentFormatter();
0126:                }
0127:                m_custom = custom;
0128:                m_simpleTypeMap = new HashMap();
0129:                m_uriSchemaMap = new HashMap();
0130:                m_context = new ValidationContext(loc);
0131:                m_detailDirectory = new SchemaDetailDirectory(loc, custom,
0132:                        m_context);
0133:            }
0134:
0135:            /**
0136:             * Find the schema to be used for a particular namespace. If this is the
0137:             * first time a particular namespace was requested, a new schema will be
0138:             * created for that namespace and returned, using a default file name.
0139:             *
0140:             * @param uri namespace URI (<code>null</code> if no namespace)
0141:             * @return schema holder
0142:             */
0143:            public SchemaHolder findSchema(String uri) {
0144:                SchemaHolder hold = (SchemaHolder) m_uriSchemaMap.get(uri);
0145:                if (hold == null) {
0146:                    hold = new SchemaHolder(uri);
0147:                    m_uriSchemaMap.put(uri, hold);
0148:                    String sname;
0149:                    if (uri == null) {
0150:                        sname = "nonamespace.xsd";
0151:                    } else {
0152:                        sname = uri.substring(uri.lastIndexOf('/') + 1)
0153:                                + ".xsd";
0154:                    }
0155:                    hold.setFileName(sname);
0156:                }
0157:                return hold;
0158:            }
0159:
0160:            /**
0161:             * Get the qualified name of the simple type used for a component, if a
0162:             * named simple type. If this returns <code>null</code>, the {@link
0163:             * #buildSimpleType(IComponent)} method needs to be able to construct the
0164:             * appropriate simple type definition.
0165:             *
0166:             * @param comp
0167:             * @return qualified type name, <code>null</code> if inline definition
0168:             * needed
0169:             */
0170:            private QName getSimpleTypeQName(IComponent comp) {
0171:                IClass type = comp.getType();
0172:                String tname = comp.getType().getName();
0173:                QName qname = Types.schemaType(tname);
0174:                if (qname == null) {
0175:                    qname = (QName) m_simpleTypeMap.get(tname);
0176:                    if (qname == null) {
0177:                        if (!type.isSuperclass("java.lang.Enum")) {
0178:                            m_context
0179:                                    .addWarning(
0180:                                            "No schema equivalent known for type - treating as string",
0181:                                            comp);
0182:                            qname = Types.STRING_QNAME;
0183:                        }
0184:                    }
0185:                }
0186:                return qname;
0187:            }
0188:
0189:            /**
0190:             * Add class-level documentation to a schema component.
0191:             *
0192:             * @param info
0193:             * @param root
0194:             */
0195:            private void addDocumentation(IClass info, AnnotatedBase root) {
0196:                if (info != null) {
0197:                    List nodes = m_formatter.docToNodes(info.getJavaDoc());
0198:                    if (nodes != null) {
0199:                        AnnotationElement anno = new AnnotationElement();
0200:                        DocumentationElement doc = new DocumentationElement();
0201:                        for (Iterator iter = nodes.iterator(); iter.hasNext();) {
0202:                            Node node = (Node) iter.next();
0203:                            doc.addContent(node);
0204:                        }
0205:                        anno.getItemsList().add(doc);
0206:                        root.setAnnotation(anno);
0207:                    }
0208:                }
0209:            }
0210:
0211:            /**
0212:             * Set the documentation for a schema component matching a class member.
0213:             *
0214:             * @param elem
0215:             * @param item
0216:             */
0217:            private void setDocumentation(IClassItem item, AnnotatedBase elem) {
0218:                List nodes = m_formatter.docToNodes(item.getJavaDoc());
0219:                if (nodes != null) {
0220:                    AnnotationElement anno = new AnnotationElement();
0221:                    DocumentationElement doc = new DocumentationElement();
0222:                    for (Iterator iter = nodes.iterator(); iter.hasNext();) {
0223:                        Node node = (Node) iter.next();
0224:                        doc.addContent(node);
0225:                    }
0226:                    anno.getItemsList().add(doc);
0227:                    elem.setAnnotation(anno);
0228:                }
0229:            }
0230:
0231:            /**
0232:             * Add documentation for a particular field or property.
0233:             *
0234:             * @param struct
0235:             * @param elem
0236:             */
0237:            private void addItemDocumentation(StructureElementBase struct,
0238:                    AnnotatedBase elem) {
0239:                IClassItem item = struct.getField();
0240:                if (item == null) {
0241:                    item = struct.getGet();
0242:                }
0243:                if (item != null) {
0244:                    setDocumentation(item, elem);
0245:                }
0246:            }
0247:
0248:            /**
0249:             * Add documentation for a particular field or property.
0250:             *
0251:             * @param value
0252:             * @param elem
0253:             */
0254:            private void addItemDocumentation(ValueElement value,
0255:                    AnnotatedBase elem) {
0256:                IClassItem item = value.getField();
0257:                if (item == null) {
0258:                    item = value.getGet();
0259:                }
0260:                if (item != null) {
0261:                    setDocumentation(item, elem);
0262:                }
0263:            }
0264:
0265:            /**
0266:             * Create the simple type definition for a type. This is only used for cases
0267:             * where {@link #getSimpleTypeQName(IComponent)} returns <code>null</code>.
0268:             * The current implementation only supports Java 5 Enum types, but in the
0269:             * future should be extended to support &lt;format>-type conversions with
0270:             * supplied schema definitions.
0271:             *
0272:             * @param type
0273:             * @return type definition
0274:             */
0275:            private SimpleTypeElement buildSimpleType(IClass type) {
0276:                SchemaEnumDetail detail = m_detailDirectory
0277:                        .getSimpleDetail(type.getName());
0278:                try {
0279:                    Class clas = type.loadClass();
0280:                    Method method = clas.getMethod("values", (Class[]) null);
0281:                    try {
0282:                        method.setAccessible(true);
0283:                    } catch (RuntimeException e) { /* deliberately empty */
0284:                    }
0285:                    Enum[] values = (Enum[]) method.invoke(null,
0286:                            (Object[]) null);
0287:                    SimpleTypeElement simple = new SimpleTypeElement();
0288:                    SimpleRestrictionElement restr = new SimpleRestrictionElement();
0289:                    restr.setBase(Types.STRING_QNAME);
0290:                    for (int i = 0; i < values.length; i++) {
0291:                        Enumeration enumel = new Enumeration();
0292:                        enumel.setValue(values[i].name());
0293:                        restr.getFacetsList().add(enumel);
0294:                    }
0295:                    simple.setDerivation(restr);
0296:                    addDocumentation(detail.getCustom().getClassInformation(),
0297:                            simple);
0298:                    return simple;
0299:                } catch (SecurityException e) {
0300:                    e.printStackTrace();
0301:                } catch (NoSuchMethodException e) {
0302:                    e.printStackTrace();
0303:                } catch (IllegalArgumentException e) {
0304:                    e.printStackTrace();
0305:                } catch (IllegalAccessException e) {
0306:                    e.printStackTrace();
0307:                } catch (InvocationTargetException e) {
0308:                    e.printStackTrace();
0309:                }
0310:                return null;
0311:            }
0312:
0313:            /**
0314:             * Convenience method to create the simple type definition for the type of a
0315:             * component.
0316:             *
0317:             * @param comp
0318:             * @return type definition
0319:             */
0320:            private SimpleTypeElement buildSimpleType(IComponent comp) {
0321:                return buildSimpleType(comp.getType());
0322:            }
0323:
0324:            /**
0325:             * General object comparison method. Don't know why Sun hasn't seen fit to
0326:             * include this somewhere, but at least it's easy to write (over and over
0327:             * again).
0328:             * 
0329:             * @param a first object to be compared
0330:             * @param b second object to be compared
0331:             * @return <code>true</code> if both objects are <code>null</code>, or if
0332:             * <code>a.equals(b)</code>; <code>false</code> otherwise
0333:             */
0334:            public static boolean isEqual(Object a, Object b) {
0335:                return (a == null) ? b == null : a.equals(b);
0336:            }
0337:
0338:            /**
0339:             * Check for dependency on another schema.
0340:             *
0341:             * @param qname name referenced by this schema
0342:             * @param hold schema holder
0343:             */
0344:            private void checkDependency(QName qname, SchemaHolder hold) {
0345:                if (qname != null
0346:                        && !isEqual(qname.getUri(), hold.getNamespace())) {
0347:                    String uri = qname.getUri();
0348:                    SchemaHolder tohold = findSchema(uri);
0349:                    hold.addReference(tohold);
0350:                    hold.getPrefix(uri);
0351:                }
0352:            }
0353:
0354:            /**
0355:             * Build a schema element description from a binding content component.
0356:             *
0357:             * @param comp source component
0358:             * @param repeat repeated element flag
0359:             * @param holder 
0360:             * @return element
0361:             */
0362:            private ElementElement buildElement(IComponent comp,
0363:                    boolean repeat, SchemaHolder holder) {
0364:
0365:                // create the basic element structure
0366:                ElementElement elem = new ElementElement();
0367:                if (repeat) {
0368:                    elem.setMinOccurs(Count.COUNT_ZERO);
0369:                    elem.setMaxOccurs(Count.COUNT_UNBOUNDED);
0370:                } else if (comp.isOptional()) {
0371:                    elem.setMinOccurs(Count.COUNT_ZERO);
0372:                }
0373:
0374:                // set or create the element type definition
0375:                boolean isref = false;
0376:                if (comp instanceof  ValueElement) {
0377:                    QName qname = getSimpleTypeQName(comp);
0378:                    if (qname == null) {
0379:                        elem.setInlineType(buildSimpleType(comp));
0380:                    } else {
0381:                        elem.setType(qname);
0382:                    }
0383:                    addItemDocumentation((ValueElement) comp, elem);
0384:                } else if (comp instanceof  CollectionElement) {
0385:                    CollectionElement coll = (CollectionElement) comp;
0386:                    if (coll.children().size() > 0) {
0387:
0388:                        // collection with children, choice or sequence from order
0389:                        ComplexTypeElement type = new ComplexTypeElement();
0390:                        if (coll.isOrdered()) {
0391:
0392:                            // ordered children go to sequence element, repeating
0393:                            SequenceElement seq = new SequenceElement();
0394:                            type.setContentDefinition(seq);
0395:
0396:                        } else {
0397:
0398:                            // unordered children go to repeated choice element
0399:                            ChoiceElement choice = new ChoiceElement();
0400:                            type.setContentDefinition(choice);
0401:
0402:                        }
0403:                        type.setContentDefinition(buildCompositor(coll, 0,
0404:                                true, holder));
0405:                        elem.setInlineType(type);
0406:
0407:                    } else {
0408:
0409:                        // empty collection, item-type must reference a concrete mapping
0410:                        String itype = coll.getItemTypeName();
0411:                        TemplateElementBase ref = coll.getDefinitions()
0412:                                .getSpecificTemplate(itype);
0413:                        if (ref instanceof  MappingElement) {
0414:
0415:                            // item type with concrete mapping, make it an element
0416:                            SchemaMappingDetail detail = m_detailDirectory
0417:                                    .getMappingDetail((MappingElement) ref);
0418:                            checkDependency(detail.getOtherName(), holder);
0419:                            ComplexTypeElement type = new ComplexTypeElement();
0420:                            SequenceElement seq = new SequenceElement();
0421:                            type.setContentDefinition(seq);
0422:                            ElementElement item = new ElementElement();
0423:                            item.setRef(detail.getOtherName());
0424:                            item.setMinOccurs(Count.COUNT_ZERO);
0425:                            item.setMaxOccurs(Count.COUNT_UNBOUNDED);
0426:                            seq.getParticleList().add(item);
0427:                            elem.setInlineType(type);
0428:                            addItemDocumentation(coll, item);
0429:
0430:                        } else {
0431:
0432:                            // TODO: handle this with xs:any strict?
0433:                            m_context
0434:                                    .addWarning(
0435:                                            "Handling not implemented for unspecified mapping",
0436:                                            coll);
0437:                        }
0438:
0439:                    }
0440:                } else {
0441:
0442:                    // must be a structure, check children
0443:                    StructureElement struct = (StructureElement) comp;
0444:                    if (struct.children().size() > 0) {
0445:
0446:                        // structure with children, choice or sequence from order
0447:                        ComplexTypeElement type = new ComplexTypeElement();
0448:                        if (struct.isOrdered()) {
0449:
0450:                            // ordered children go to sequence element
0451:                            SequenceElement seq = new SequenceElement();
0452:                            type.setContentDefinition(seq);
0453:
0454:                        } else {
0455:
0456:                            // unordered children go to repeated choice element
0457:                            ChoiceElement choice = new ChoiceElement();
0458:                            type.setContentDefinition(choice);
0459:                        }
0460:                        type.setContentDefinition(buildCompositor(struct, 0,
0461:                                false, holder));
0462:                        fillAttributes(struct, 0, type.getAttributeList(),
0463:                                holder);
0464:                        elem.setInlineType(type);
0465:
0466:                    } else {
0467:
0468:                        // no children, must be a mapping reference
0469:                        MappingElement ref = (MappingElement) struct
0470:                                .getEffectiveMapping();
0471:                        if (ref == null) {
0472:
0473:                            // TODO: handle this with xs:any strict?
0474:                            m_context
0475:                                    .addWarning(
0476:                                            "Handling not implemented for unspecified mapping",
0477:                                            struct);
0478:
0479:                        } else {
0480:
0481:                            // implicit mapping reference, find the handling
0482:                            SchemaMappingDetail detail = m_detailDirectory
0483:                                    .getMappingDetail(ref);
0484:                            if (detail.isElement()) {
0485:
0486:                                // structure with concrete mapping
0487:                                checkDependency(detail.getOtherName(), holder);
0488:                                elem.setRef(detail.getOtherName());
0489:                                isref = true;
0490:
0491:                            } else {
0492:
0493:                                // set element type to that constructed from mapping
0494:                                checkDependency(detail.getTypeName(), holder);
0495:                                elem.setType(detail.getTypeName());
0496:
0497:                            }
0498:                        }
0499:                    }
0500:                    addItemDocumentation(struct, elem);
0501:                }
0502:                if (!isref) {
0503:                    elem.setName(comp.getName());
0504:                }
0505:                return elem;
0506:            }
0507:
0508:            /**
0509:             * Build compositor for type definition. This creates and returns the
0510:             * appropriate form of compositor for the container, populated with
0511:             * particles matching the child element components of the binding container.
0512:             *
0513:             * @param cont container element defining structure
0514:             * @param offset offset for first child component to process
0515:             * @param repeat repeated item flag
0516:             * @param holder holder for schema under construction
0517:             * @return constructed compositor
0518:             */
0519:            private CommonCompositorDefinition buildCompositor(
0520:                    ContainerElementBase cont, int offset, boolean repeat,
0521:                    SchemaHolder holder) {
0522:
0523:                // start with the appropriate type of compositor
0524:                CommonCompositorDefinition cdef;
0525:                if (cont.isChoice()) {
0526:
0527:                    // choice container goes directly to choice compositor
0528:                    cdef = new ChoiceElement();
0529:
0530:                } else if (cont.isOrdered()) {
0531:
0532:                    // ordered container goes directly to sequence compositor
0533:                    cdef = new SequenceElement();
0534:
0535:                } else if (repeat) {
0536:
0537:                    // unordered repeat treated as repeated choice compositor
0538:                    cdef = new ChoiceElement();
0539:                    cdef.setMaxOccurs(Count.COUNT_UNBOUNDED);
0540:
0541:                } else {
0542:
0543:                    // unordered non-repeat treated as all compositor
0544:                    // TODO: verify conditions for all
0545:                    cdef = new AllElement();
0546:                }
0547:
0548:                // generate schema equivalents for content components of container
0549:                ArrayList comps = cont.getContentComponents();
0550:                for (int i = offset; i < comps.size(); i++) {
0551:                    IComponent comp = (IComponent) comps.get(i);
0552:                    if (comp.hasName()) {
0553:
0554:                        // create element for named content component
0555:                        ElementElement element = buildElement(comp, repeat,
0556:                                holder);
0557:                        if (comp instanceof  StructureElementBase) {
0558:                            addItemDocumentation((StructureElementBase) comp,
0559:                                    element);
0560:                        }
0561:                        cdef.getParticleList().add(element);
0562:
0563:                    } else if (comp instanceof  ContainerElementBase) {
0564:                        ContainerElementBase contain = (ContainerElementBase) comp;
0565:                        boolean iscoll = comp instanceof  CollectionElement;
0566:                        if (contain.children().size() > 0) {
0567:
0568:                            // no element name, but children; handle with recursive call
0569:                            CommonCompositorDefinition part = buildCompositor(
0570:                                    contain, 0, iscoll, holder);
0571:                            cdef.getParticleList().add(part);
0572:
0573:                        } else if (iscoll) {
0574:
0575:                            // collection without a wrapper element
0576:                            CollectionElement coll = (CollectionElement) comp;
0577:                            String itype = coll.getItemTypeName();
0578:                            TemplateElementBase ref = coll.getDefinitions()
0579:                                    .getSpecificTemplate(itype);
0580:                            if (ref instanceof  MappingElement) {
0581:
0582:                                // item type with concrete mapping, make it an element
0583:                                SchemaMappingDetail detail = m_detailDirectory
0584:                                        .getMappingDetail((MappingElement) ref);
0585:                                checkDependency(detail.getOtherName(), holder);
0586:                                ElementElement item = new ElementElement();
0587:                                item.setRef(detail.getOtherName());
0588:                                item.setMinOccurs(Count.COUNT_ZERO);
0589:                                item.setMaxOccurs(Count.COUNT_UNBOUNDED);
0590:                                addItemDocumentation(coll, item);
0591:                                cdef.getParticleList().add(item);
0592:
0593:                            } else {
0594:
0595:                                // TODO: handle this with xs:any strict?
0596:                                m_context
0597:                                        .addWarning(
0598:                                                "Handling not implemented for unspecified mapping",
0599:                                                coll);
0600:                            }
0601:
0602:                        } else if (comp instanceof  StructureElement) {
0603:
0604:                            // no children, must be mapping reference
0605:                            StructureElement struct = (StructureElement) comp;
0606:                            MappingElement ref = (MappingElement) struct
0607:                                    .getEffectiveMapping();
0608:                            if (ref == null) {
0609:
0610:                                // TODO: handle this with xs:any strict?
0611:                                m_context
0612:                                        .addWarning(
0613:                                                "Handling not implemented for unspecified mapping",
0614:                                                struct);
0615:
0616:                            } else {
0617:
0618:                                // handle mapping reference based on form and name use
0619:                                SchemaMappingDetail detail = m_detailDirectory
0620:                                        .getMappingDetail(ref);
0621:                                checkDependency(detail.getOtherName(), holder);
0622:                                if (ref.isAbstract()) {
0623:
0624:                                    // abstract inline treated as group
0625:                                    GroupRefElement group = new GroupRefElement();
0626:                                    group.setRef(detail.getOtherName());
0627:                                    if (comp.isOptional()) {
0628:                                        group.setMinOccurs(Count.COUNT_ZERO);
0629:                                    }
0630:                                    cdef.getParticleList().add(group);
0631:
0632:                                } else {
0633:
0634:                                    // concrete treated as element reference
0635:                                    ElementElement elem = new ElementElement();
0636:                                    elem.setRef(detail.getOtherName());
0637:                                    if (comp.isOptional()) {
0638:                                        elem.setMinOccurs(Count.COUNT_ZERO);
0639:                                    }
0640:                                    addItemDocumentation(struct, elem);
0641:                                    cdef.getParticleList().add(elem);
0642:
0643:                                }
0644:                            }
0645:                        } else {
0646:                            m_context.addError("Unsupported binding construct",
0647:                                    comp);
0648:                        }
0649:
0650:                    } else {
0651:                        m_context.addError("Unsupported component", comp);
0652:                    }
0653:                }
0654:
0655:                // simplify by eliminating this level if only child a compositor
0656:                if ((cont.isOrdered() || cont.isChoice())
0657:                        && cdef.getParticleList().size() == 1) {
0658:                    Object child = cdef.getParticleList().get(0);
0659:                    if (child instanceof  CommonCompositorDefinition) {
0660:                        cdef = (CommonCompositorDefinition) child;
0661:                    }
0662:                }
0663:                return cdef;
0664:            }
0665:
0666:            /**
0667:             * Build attributes as part of complex type definition.
0668:             *
0669:             * @param cont container element defining structure
0670:             * @param offset offset for first child component to process
0671:             * @param attrs complex type attribute list
0672:             * @param holder holder for schema under construction
0673:             */
0674:            private void fillAttributes(ContainerElementBase cont, int offset,
0675:                    AbstractList attrs, SchemaHolder holder) {
0676:
0677:                // add child attribute components
0678:                ArrayList comps = cont.getAttributeComponents();
0679:                for (int i = 0; i < comps.size(); i++) {
0680:                    IComponent comp = (IComponent) comps.get(i);
0681:                    if (comp instanceof  ValueElement) {
0682:
0683:                        // simple attribute definition
0684:                        AttributeElement attr = new AttributeElement();
0685:                        attr.setName(comp.getName());
0686:                        QName qname = getSimpleTypeQName(comp);
0687:                        if (qname == null) {
0688:                            attr.setInlineType(buildSimpleType(comp));
0689:                        } else {
0690:                            attr.setType(qname);
0691:                        }
0692:                        if (!comp.isOptional()) {
0693:                            attr.setUse(AttributeElement.REQUIRED_USE);
0694:                        }
0695:                        addItemDocumentation((ValueElement) comp, attr);
0696:                        attrs.add(attr);
0697:
0698:                    } else if (comp instanceof  ContainerElementBase) {
0699:                        ContainerElementBase contain = (ContainerElementBase) comp;
0700:                        if (contain.children().size() > 0) {
0701:
0702:                            // handle children with recursive call
0703:                            fillAttributes(contain, 0, attrs, holder);
0704:
0705:                        } else if (comp instanceof  StructureElement) {
0706:
0707:                            // no children, must be mapping reference
0708:                            StructureElement struct = (StructureElement) comp;
0709:                            if (struct.isOptional()) {
0710:                                m_context
0711:                                        .addError(
0712:                                                "No schema equivalent for optional abstract mapping with attributes",
0713:                                                comp);
0714:                            } else {
0715:                                MappingElement ref = (MappingElement) struct
0716:                                        .getEffectiveMapping();
0717:                                if (ref != null && ref.isAbstract()) {
0718:
0719:                                    // abstract inline treated as group
0720:                                    SchemaMappingDetail detail = m_detailDirectory
0721:                                            .getMappingDetail(ref);
0722:                                    checkDependency(detail.getOtherName(),
0723:                                            holder);
0724:                                    AttributeGroupRefElement group = new AttributeGroupRefElement();
0725:                                    group.setRef(detail.getOtherName());
0726:                                    attrs.add(group);
0727:
0728:                                } else {
0729:                                    throw new IllegalStateException(
0730:                                            "Unsupported binding construct "
0731:                                                    + comp);
0732:                                }
0733:                            }
0734:                        } else {
0735:                            m_context.addError("Unsupported binding construct",
0736:                                    comp);
0737:                        }
0738:
0739:                    } else {
0740:                        m_context.addError("Unsupported component", comp);
0741:                    }
0742:                }
0743:            }
0744:
0745:            /**
0746:             * Check if a container element of the binding represents complex content.
0747:             *
0748:             * @param cont
0749:             * @return <code>true</code> if complex content, <code>false</code> if not
0750:             */
0751:            private static boolean isComplexContent(ContainerElementBase cont) {
0752:                ArrayList conts = cont.getContentComponents();
0753:                for (int i = 0; i < conts.size(); i++) {
0754:                    IComponent comp = (IComponent) conts.get(i);
0755:                    if (comp.hasName()) {
0756:                        return true;
0757:                    } else if (comp instanceof  ContainerElementBase
0758:                            && isComplexContent((ContainerElementBase) comp)) {
0759:                        return true;
0760:                    }
0761:                }
0762:                return false;
0763:            }
0764:
0765:            /**
0766:             * Build the complex type definition for a mapping. 
0767:             *
0768:             * @param detail mapping detail
0769:             * @param hold target schema for definition
0770:             * @return constructed complex type
0771:             */
0772:            private ComplexTypeElement buildComplexType(
0773:                    SchemaMappingDetail detail, SchemaHolder hold) {
0774:
0775:                // create the type and compositor
0776:                ComplexTypeElement type = new ComplexTypeElement();
0777:                MappingElement mapping = detail.getMapping();
0778:                MappingElement base = detail.getExtensionBase();
0779:                if (base == null) {
0780:                    if (detail.isGroup()) {
0781:
0782:                        // create type using references to group and/or attributeGroup
0783:                        SequenceElement seq = new SequenceElement();
0784:                        if (detail.hasChild()) {
0785:                            GroupRefElement gref = new GroupRefElement();
0786:                            gref.setRef(detail.getOtherName());
0787:                            seq.getParticleList().add(gref);
0788:                        }
0789:                        type.setContentDefinition(seq);
0790:                        if (detail.hasAttribute()) {
0791:                            AttributeGroupRefElement gref = new AttributeGroupRefElement();
0792:                            gref.setRef(detail.getOtherName());
0793:                            type.getAttributeList().add(gref);
0794:                        }
0795:
0796:                    } else {
0797:
0798:                        // create type directly
0799:                        type.setContentDefinition(buildCompositor(mapping, 0,
0800:                                false, hold));
0801:                        fillAttributes(mapping, 0, type.getAttributeList(),
0802:                                hold);
0803:
0804:                    }
0805:                } else {
0806:
0807:                    // create type as extension of base type
0808:                    ComplexExtensionElement ext = new ComplexExtensionElement();
0809:                    SchemaMappingDetail basedet = m_detailDirectory
0810:                            .getMappingDetail(base);
0811:                    ext.setBase(basedet.getTypeName());
0812:                    ext.setContentDefinition(buildCompositor(mapping, 1, false,
0813:                            hold));
0814:                    if (isComplexContent(base) || isComplexContent(mapping)) {
0815:                        ComplexContentElement cont = new ComplexContentElement();
0816:                        cont.setDerivation(ext);
0817:                        type.setContentType(cont);
0818:                    } else {
0819:                        SimpleContentElement cont = new SimpleContentElement();
0820:                        cont.setDerivation(ext);
0821:                        type.setContentType(cont);
0822:                    }
0823:
0824:                }
0825:                return type;
0826:            }
0827:
0828:            /**
0829:             * Add mapping to schema definitions. This generates the appropriate schema
0830:             * representation for the mapping based on the detail flags, which may
0831:             * include group and/or attributeGroup, complexType, and element
0832:             * definitions.
0833:             *
0834:             * @param detail
0835:             */
0836:            private void addMapping(SchemaMappingDetail detail) {
0837:
0838:                // get the documentation to be used for type
0839:                IClass info = null;
0840:                if (m_locator != null) {
0841:                    info = m_locator.getClassInfo(detail.getMapping()
0842:                            .getClassName());
0843:                }
0844:
0845:                // start by generating group/attributeGroup schema components
0846:                MappingElement mapping = detail.getMapping();
0847:                if (detail.isGroup()) {
0848:                    // TODO: extend base type for group/attributeGroup?
0849:                    QName qname = detail.getOtherName();
0850:                    SchemaHolder hold = findSchema(qname.getUri());
0851:                    if (detail.hasChild()) {
0852:                        GroupElement group = new GroupElement();
0853:                        group.setName(qname.getName());
0854:                        group.setDefinition(buildCompositor(mapping, 0, false,
0855:                                hold));
0856:                        addDocumentation(info, group);
0857:                        hold.getSchema().getTopLevelChildren().add(group);
0858:                    }
0859:                    if (detail.hasAttribute()) {
0860:                        AttributeGroupElement attgrp = new AttributeGroupElement();
0861:                        attgrp.setName(qname.getName());
0862:                        fillAttributes(mapping, 0, attgrp.getAttributeList(),
0863:                                hold);
0864:                        addDocumentation(info, attgrp);
0865:                        hold.getSchema().getTopLevelChildren().add(attgrp);
0866:                    }
0867:                }
0868:
0869:                // next generate the complex type definition
0870:                if (detail.isType()) {
0871:
0872:                    // set up the basic definition structure
0873:                    QName qname = detail.getTypeName();
0874:                    SchemaHolder hold = findSchema(qname.getUri());
0875:                    ComplexTypeElement type = buildComplexType(detail, hold);
0876:                    type.setName(qname.getName());
0877:                    addDocumentation(info, type);
0878:                    hold.getSchema().getTopLevelChildren().add(type);
0879:                }
0880:
0881:                // finish by generating element definition
0882:                if (detail.isElement()) {
0883:                    QName qname = detail.getOtherName();
0884:                    SchemaHolder hold = findSchema(qname.getUri());
0885:                    ElementElement elem = new ElementElement();
0886:                    elem.setName(qname.getName());
0887:                    elem.setSubstitutionGroup(detail.getSubstitution());
0888:                    if (detail.isType()) {
0889:                        elem.setType(detail.getTypeName());
0890:                    } else {
0891:
0892:                        // check for just an element wrapper around type reference
0893:                        MappingElement ext = detail.getExtensionBase();
0894:                        if (ext != null
0895:                                && mapping.getContentComponents().size() == 1) {
0896:                            elem.setType(ext.getTypeQName());
0897:                        } else {
0898:
0899:                            // add documentation to element which is not also a type
0900:                            addDocumentation(info, elem);
0901:                            elem.setInlineType(buildComplexType(detail, hold));
0902:                        }
0903:                    }
0904:                    hold.getSchema().getTopLevelChildren().add(elem);
0905:                }
0906:            }
0907:
0908:            /**
0909:             * Generate a list of schemas from a list of bindings. The two lists are not
0910:             * necessarily in any particular relationship to each other.
0911:             *
0912:             * @param holders list of {@link BindingHolder}
0913:             * @return schemas list of {@link SchemaHolder}
0914:             */
0915:            public ArrayList generate(ArrayList holders) {
0916:
0917:                // start by scanning all bindings to build mapping and enum details
0918:                m_detailDirectory.populate(holders);
0919:
0920:                // process all the simple type definitions (formats or enums)
0921:                Collection simples = m_detailDirectory.getSimpleDetails();
0922:                for (Iterator iter = simples.iterator(); iter.hasNext();) {
0923:                    SchemaEnumDetail detail = (SchemaEnumDetail) iter.next();
0924:                    if (detail.isGlobal()) {
0925:                        ClassCustom custom = detail.getCustom();
0926:                        SimpleTypeElement type = buildSimpleType(custom
0927:                                .getClassInformation());
0928:                        type.setName(custom.getTypeName());
0929:                        SchemaHolder hold = findSchema(custom.getNamespace());
0930:                        hold.getSchema().getTopLevelChildren().add(type);
0931:                        m_simpleTypeMap.put(custom.getName(), custom
0932:                                .getTypeQName());
0933:                    }
0934:                }
0935:
0936:                // process all the mapping definitions from directory
0937:                Collection mappings = m_detailDirectory.getComplexDetails();
0938:                for (Iterator iter = mappings.iterator(); iter.hasNext();) {
0939:                    SchemaMappingDetail detail = (SchemaMappingDetail) iter
0940:                            .next();
0941:                    addMapping(detail);
0942:                }
0943:
0944:                // report any problems found in schema generation
0945:                ArrayList probs = m_context.getProblems();
0946:                boolean error = m_context.getErrorCount() > 0
0947:                        || m_context.getFatalCount() > 0;
0948:                if (probs.size() > 0) {
0949:                    System.out.print(error ? "Errors" : "Warnings");
0950:                    System.out.println(" in generated binding:");
0951:                    for (int j = 0; j < probs.size(); j++) {
0952:                        ValidationProblem prob = (ValidationProblem) probs
0953:                                .get(j);
0954:                        System.out
0955:                                .print(prob.getSeverity() >= ValidationProblem.ERROR_LEVEL ? "Error: "
0956:                                        : "Warning: ");
0957:                        System.out.println(prob.getDescription());
0958:                    }
0959:                }
0960:
0961:                // fix all references between schemas
0962:                ArrayList schemas = new ArrayList(m_uriSchemaMap.values());
0963:                for (int i = 0; i < schemas.size(); i++) {
0964:                    SchemaHolder hold = (SchemaHolder) schemas.get(i);
0965:                    hold.fixReferences();
0966:                }
0967:
0968:                // validate the schemas and report any problems
0969:                org.jibx.schema.validation.ValidationContext vctx = new org.jibx.schema.validation.ValidationContext();
0970:                for (int i = 0; i < schemas.size(); i++) {
0971:                    SchemaHolder holder = (SchemaHolder) schemas.get(i);
0972:                    String id = holder.getFileName();
0973:                    SchemaElement schema = holder.getSchema();
0974:                    schema.setResolver(new MemoryResolver(id));
0975:                    vctx.setSchema(id, schema);
0976:                }
0977:                TreeWalker wlkr = new TreeWalker(vctx, vctx);
0978:                vctx.clearTraversed();
0979:                for (int i = 0; i < schemas.size(); i++) {
0980:                    wlkr.walkSchema(
0981:                            ((SchemaHolder) schemas.get(i)).getSchema(),
0982:                            new PrevalidationVisitor(vctx));
0983:                }
0984:                vctx.clearTraversed();
0985:                for (int i = 0; i < schemas.size(); i++) {
0986:                    wlkr.walkSchema(
0987:                            ((SchemaHolder) schemas.get(i)).getSchema(),
0988:                            new RegistrationVisitor(vctx));
0989:                }
0990:                vctx.clearTraversed();
0991:                for (int i = 0; i < schemas.size(); i++) {
0992:                    wlkr.walkSchema(
0993:                            ((SchemaHolder) schemas.get(i)).getSchema(),
0994:                            new ValidationVisitor(vctx));
0995:                }
0996:                probs = vctx.getProblems();
0997:                if (probs.size() > 0) {
0998:                    for (int j = 0; j < probs.size(); j++) {
0999:                        org.jibx.schema.validation.ValidationProblem prob = (org.jibx.schema.validation.ValidationProblem) probs
1000:                                .get(j);
1001:                        System.out
1002:                                .print(prob.getSeverity() >= ValidationProblem.ERROR_LEVEL ? "Error: "
1003:                                        : "Warning: ");
1004:                        System.out.println(prob.getDescription());
1005:                    }
1006:                }
1007:                return schemas;
1008:            }
1009:
1010:            /**
1011:             * Get details of schema handling of a mapping.
1012:             *
1013:             * @param map
1014:             * @return mapping details
1015:             */
1016:            public SchemaMappingDetail getMappingDetail(MappingElement map) {
1017:                return m_detailDirectory.forceMappingDetail(map);
1018:            }
1019:
1020:            private static class MemoryResolver implements  ISchemaResolver {
1021:                private final String m_id;
1022:
1023:                public MemoryResolver(String id) {
1024:                    m_id = id;
1025:                }
1026:
1027:                public InputStream getContent() throws IOException {
1028:                    throw new IOException("Source not available");
1029:                }
1030:
1031:                public String getId() {
1032:                    return m_id;
1033:                }
1034:
1035:                public ISchemaResolver resolve(String loc) throws IOException {
1036:                    return new MemoryResolver(loc);
1037:                }
1038:            }
1039:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.