Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » inst2xsd » util » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   package org.apache.xmlbeans.impl.inst2xsd.util;
   16   
   17   import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
   18   import org.apache.xmlbeans.XmlString;
   19   import org.apache.xmlbeans.XmlQName;
   20   import org.apache.xmlbeans.XmlCursor;
   21   
   22   import javax.xml.namespace.QName;
   23   import java.math.BigInteger;
   24   import java.util.Collection;
   25   import java.util.Iterator;
   26   import java.util.Map;
   27   import java.util.LinkedHashMap;
   28   import java.util.HashMap;
   29   
   30   /**
   31    * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   32    */
   33   public class TypeSystemHolder
   34   {
   35       Map _globalElements;   // QName -> Element
   36       Map _globalAttributes; // QName -> Attribute
   37       Map _globalTypes;      // QName -> Type
   38   
   39       public TypeSystemHolder()
   40       {
   41           _globalElements = new LinkedHashMap();
   42           _globalAttributes = new LinkedHashMap();
   43           _globalTypes = new LinkedHashMap();
   44       }
   45   
   46       public void addGlobalElement(Element element)
   47       {
   48           assert element.isGlobal() && !element.isRef();
   49           _globalElements.put(element.getName(), element);
   50       }
   51   
   52       public Element getGlobalElement(QName name)
   53       {
   54           return (Element)_globalElements.get(name);
   55       }
   56   
   57       public Element[] getGlobalElements()
   58       {
   59           Collection col = _globalElements.values();
   60           return (Element[])col.toArray(new Element[col.size()]);
   61       }
   62   
   63       public void addGlobalAttribute(Attribute attribute)
   64       {
   65           assert attribute.isGlobal() && !attribute.isRef();
   66           _globalAttributes.put(attribute.getName(), attribute);
   67       }
   68   
   69       public Attribute getGlobalAttribute(QName name)
   70       {
   71           return (Attribute)_globalAttributes.get(name);
   72       }
   73   
   74       public Attribute[] getGlobalAttributes()
   75       {
   76           Collection col = _globalAttributes.values();
   77           return (Attribute[])col.toArray(new Attribute[col.size()]);
   78       }
   79   
   80       public void addGlobalType(Type type)
   81       {
   82           assert type.isGlobal() && type.getName()!=null : "type must be a global type before being added.";
   83           _globalTypes.put(type.getName(), type);
   84       }
   85   
   86       public Type getGlobalType(QName name)
   87       {
   88           return (Type)_globalTypes.get(name);
   89       }
   90   
   91       public Type[] getGlobalTypes()
   92       {
   93           Collection col = _globalTypes.values();
   94           return (Type[])col.toArray(new Type[col.size()]);
   95       }
   96   
   97       public SchemaDocument[] getSchemaDocuments()
   98       {
   99           // recompute everything, should cache it and track changes
  100           Map nsToSchemaDocs = new LinkedHashMap();
  101   
  102           for (Iterator iterator = _globalElements.keySet().iterator(); iterator.hasNext();)
  103           {
  104               QName globalElemName = (QName) iterator.next();
  105               String tns = globalElemName.getNamespaceURI();
  106               SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  107   
  108               fillUpGlobalElement((Element)_globalElements.get(globalElemName), schDoc, tns);
  109           }
  110   
  111           for (Iterator iterator = _globalAttributes.keySet().iterator(); iterator.hasNext();)
  112           {
  113               QName globalAttName = (QName) iterator.next();
  114               String tns = globalAttName.getNamespaceURI();
  115               SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  116   
  117               fillUpGlobalAttribute((Attribute)_globalAttributes.get(globalAttName), schDoc, tns);
  118           }
  119   
  120           for (Iterator iterator = _globalTypes.keySet().iterator(); iterator.hasNext();)
  121           {
  122               QName globalTypeName = (QName) iterator.next();
  123               String tns = globalTypeName.getNamespaceURI();
  124               SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  125   
  126               fillUpGlobalType((Type)_globalTypes.get(globalTypeName), schDoc, tns);
  127           }
  128   
  129           Collection schDocColl = nsToSchemaDocs.values();
  130           return (SchemaDocument[])schDocColl.toArray(new SchemaDocument[schDocColl.size()]);
  131       }
  132   
  133       private static SchemaDocument getSchemaDocumentForTNS(Map nsToSchemaDocs, String tns)
  134       {
  135           SchemaDocument schDoc = (SchemaDocument)nsToSchemaDocs.get(tns);
  136           if (schDoc==null)
  137           {
  138               schDoc = SchemaDocument.Factory.newInstance();
  139               nsToSchemaDocs.put(tns, schDoc);
  140           }
  141           return schDoc;
  142       }
  143   
  144       private static org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema getTopLevelSchemaElement(SchemaDocument schDoc,
  145           String tns)
  146       {
  147           org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = schDoc.getSchema();
  148           if (sch==null)
  149           {
  150               sch = schDoc.addNewSchema();
  151               sch.setAttributeFormDefault(org.apache.xmlbeans.impl.xb.xsdschema.FormChoice.Enum.forString("unqualified"));
  152               sch.setElementFormDefault(org.apache.xmlbeans.impl.xb.xsdschema.FormChoice.Enum.forString("qualified"));
  153               if (!tns.equals(""))
  154                   sch.setTargetNamespace(tns);
  155           }
  156           return sch;
  157       }
  158   
  159       // Global Elements
  160       private void fillUpGlobalElement(Element globalElement, SchemaDocument schDoc, String tns)
  161       {
  162           assert tns.equals(globalElement.getName().getNamespaceURI());
  163   
  164           org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  165   
  166           org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement topLevelElem = sch.addNewElement();
  167           topLevelElem.setName(globalElement.getName().getLocalPart());
  168   
  169           if (globalElement.isNillable())
  170               topLevelElem.setNillable(globalElement.isNillable());
  171   
  172           fillUpElementDocumentation(topLevelElem, globalElement.getComment());
  173   
  174           Type elemType = globalElement.getType();
  175           fillUpTypeOnElement(elemType, topLevelElem, tns);
  176       }
  177   
  178       protected void fillUpLocalElement(Element element, org.apache.xmlbeans.impl.xb.xsdschema.LocalElement localSElement, String tns)
  179       {
  180           fillUpElementDocumentation(localSElement, element.getComment());
  181           if (!element.isRef())
  182           {
  183               assert element.getName().getNamespaceURI().equals(tns) ||
  184                   element.getName().getNamespaceURI().length() == 0;
  185               fillUpTypeOnElement(element.getType(), localSElement, tns);
  186               localSElement.setName(element.getName().getLocalPart());
  187           }
  188           else
  189           {
  190               localSElement.setRef(element.getName());
  191               assert !element.isNillable();
  192           }
  193   
  194           if (element.getMaxOccurs()==Element.UNBOUNDED)
  195           {
  196               localSElement.setMaxOccurs("unbounded");
  197           }
  198           if (element.getMinOccurs()!=1)
  199           {
  200               localSElement.setMinOccurs(new BigInteger("" + element.getMinOccurs()));
  201           }
  202   
  203           if (element.isNillable())
  204               localSElement.setNillable(element.isNillable());
  205       }
  206   
  207       private void fillUpTypeOnElement(Type elemType, org.apache.xmlbeans.impl.xb.xsdschema.Element parentSElement, String tns)
  208       {
  209           if (elemType.isGlobal())
  210           {
  211               assert elemType.getName()!=null : "Global type must have a name.";
  212               parentSElement.setType(elemType.getName());
  213           }
  214           else if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT)
  215           {
  216               if (elemType.isEnumeration())
  217                   fillUpEnumeration(elemType, parentSElement);
  218               else
  219                   parentSElement.setType(elemType.getName());
  220           }
  221           else
  222           {
  223               org.apache.xmlbeans.impl.xb.xsdschema.LocalComplexType localComplexType = parentSElement.addNewComplexType();
  224               fillUpContentForComplexType(elemType, localComplexType, tns);
  225           }
  226       }
  227   
  228       private void fillUpEnumeration(Type type, org.apache.xmlbeans.impl.xb.xsdschema.Element parentSElement)
  229       {
  230           assert type.isEnumeration() && !type.isComplexType() : "Enumerations must be on simple types only.";
  231           org.apache.xmlbeans.impl.xb.xsdschema.RestrictionDocument.Restriction restriction = parentSElement.addNewSimpleType().addNewRestriction();
  232           restriction.setBase(type.getName());
  233           if (type.isQNameEnumeration())
  234           {
  235               for (int i = 0; i < type.getEnumerationQNames().size(); i++)
  236               {
  237                   QName value = (QName) type.getEnumerationQNames().get(i);
  238                   XmlQName xqname = XmlQName.Factory.newValue(value);
  239   
  240                   org.apache.xmlbeans.impl.xb.xsdschema.NoFixedFacet enumSElem = restriction.addNewEnumeration();
  241                   XmlCursor xc  = enumSElem.newCursor();
  242   
  243                   String newPrefix = xc.prefixForNamespace(value.getNamespaceURI());
  244                   xc.dispose();
  245   
  246                   enumSElem.setValue( XmlQName.Factory.newValue(
  247                       new QName(value.getNamespaceURI(), value.getLocalPart(), newPrefix)));
  248               }
  249           }
  250           else
  251           {
  252               for (int i = 0; i < type.getEnumerationValues().size(); i++)
  253               {
  254                   String value = (String) type.getEnumerationValues().get(i);
  255                   restriction.addNewEnumeration().setValue(XmlString.Factory.newValue(value));
  256               }
  257           }
  258       }
  259   
  260       private void fillUpAttributesInComplexTypesSimpleContent(Type elemType,
  261           org.apache.xmlbeans.impl.xb.xsdschema.SimpleExtensionType sExtension, String tns)
  262       {
  263           for (int i = 0; i < elemType.getAttributes().size(); i++)
  264           {
  265               Attribute att = (Attribute) elemType.getAttributes().get(i);
  266               org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute = sExtension.addNewAttribute();
  267               fillUpLocalAttribute(att, sAttribute, tns);
  268           }
  269       }
  270   
  271       private void fillUpAttributesInComplexTypesComplexContent(Type elemType,
  272           org.apache.xmlbeans.impl.xb.xsdschema.ComplexType localSComplexType, String tns)
  273       {
  274           for (int i = 0; i < elemType.getAttributes().size(); i++)
  275           {
  276               Attribute att = (Attribute) elemType.getAttributes().get(i);
  277               org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute = localSComplexType.addNewAttribute();
  278               fillUpLocalAttribute(att, sAttribute, tns);
  279           }
  280       }
  281   
  282       protected void fillUpLocalAttribute(Attribute att, org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute, String tns)
  283       {
  284           if (att.isRef())
  285           {
  286               sAttribute.setRef(att.getRef().getName());
  287           }
  288           else
  289           {
  290               assert att.getName().getNamespaceURI()==tns || att.getName().getNamespaceURI().equals("");
  291               sAttribute.setType(att.getType().getName());
  292               sAttribute.setName(att.getName().getLocalPart());
  293               if (att.isOptional())
  294                   sAttribute.setUse(org.apache.xmlbeans.impl.xb.xsdschema.Attribute.Use.OPTIONAL);
  295           }
  296       }
  297   
  298       protected void fillUpContentForComplexType(Type type, org.apache.xmlbeans.impl.xb.xsdschema.ComplexType sComplexType, String tns)
  299       {
  300           if (type.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT)
  301           {
  302               org.apache.xmlbeans.impl.xb.xsdschema.SimpleContentDocument.SimpleContent simpleContent = sComplexType.addNewSimpleContent();
  303   
  304               assert type.getExtensionType()!=null && type.getExtensionType().getName()!=null : "Extension type must exist and be named for a COMPLEX_TYPE_SIMPLE_CONTENT";
  305   
  306               org.apache.xmlbeans.impl.xb.xsdschema.SimpleExtensionType ext = simpleContent.addNewExtension();
  307               ext.setBase(type.getExtensionType().getName());
  308   
  309               fillUpAttributesInComplexTypesSimpleContent(type, ext, tns);
  310           }
  311           else
  312           {
  313               if (type.getContentType()==Type.COMPLEX_TYPE_MIXED_CONTENT)
  314               {
  315                   sComplexType.setMixed(true);
  316               }
  317   
  318               org.apache.xmlbeans.impl.xb.xsdschema.ExplicitGroup explicitGroup;
  319               if (type.getContentType()==Type.COMPLEX_TYPE_EMPTY_CONTENT)
  320                   explicitGroup = null;
  321               else if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_SEQUENCE)
  322               {
  323                   explicitGroup = sComplexType.addNewSequence();
  324               }
  325               else if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_CHOICE_UNBOUNDED)
  326               {
  327                   explicitGroup = sComplexType.addNewChoice();
  328                   explicitGroup.setMaxOccurs("unbounded");
  329                   explicitGroup.setMinOccurs(new BigInteger("0"));
  330               }
  331               else { throw new IllegalStateException("Unknown particle type in complex and mixed content"); }
  332   
  333               for (int i = 0; i < type.getElements().size(); i++)
  334               {
  335                   Element child = (Element) type.getElements().get(i);
  336                   assert !child.isGlobal();
  337                   org.apache.xmlbeans.impl.xb.xsdschema.LocalElement childLocalElement = explicitGroup.addNewElement();
  338                   fillUpLocalElement(child, childLocalElement, tns);
  339               }
  340   
  341               fillUpAttributesInComplexTypesComplexContent(type, sComplexType, tns);
  342           }
  343       }
  344   
  345       // Global Attributes
  346       private void fillUpGlobalAttribute(Attribute globalAttribute, SchemaDocument schDoc, String tns)
  347       {
  348           assert tns.equals(globalAttribute.getName().getNamespaceURI());
  349           org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  350   
  351           org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute topLevelAtt = sch.addNewAttribute();
  352           topLevelAtt.setName(globalAttribute.getName().getLocalPart());
  353   
  354           Type elemType = globalAttribute.getType();
  355   
  356           if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT)
  357           {
  358               topLevelAtt.setType(elemType.getName());
  359           }
  360           else
  361           {
  362               //org.apache.xmlbeans.impl.xb.xsdschema.LocalSimpleType localSimpleType = topLevelAtt.addNewSimpleType();
  363               throw new IllegalStateException();
  364           }
  365       }
  366   
  367       private static void fillUpElementDocumentation(org.apache.xmlbeans.impl.xb.xsdschema.Element element, String comment)
  368       {
  369           if (comment!=null && comment.length()>0)
  370           {
  371               org.apache.xmlbeans.impl.xb.xsdschema.DocumentationDocument.Documentation documentation = element.addNewAnnotation().addNewDocumentation();
  372               documentation.set(org.apache.xmlbeans.XmlString.Factory.newValue(comment));
  373           }
  374       }
  375   
  376       // Global Types
  377       private void fillUpGlobalType(Type globalType, SchemaDocument schDoc, String tns)
  378       {
  379           assert tns.equals(globalType.getName().getNamespaceURI());
  380           org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  381   
  382           org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType topLevelComplexType = sch.addNewComplexType();
  383           topLevelComplexType.setName(globalType.getName().getLocalPart());
  384   
  385           fillUpContentForComplexType(globalType, topLevelComplexType, tns);
  386       }
  387   
  388       public String toString()
  389       {
  390           return "TypeSystemHolder{" +
  391               "\n\n_globalElements=" + _globalElements +
  392               "\n\n_globalAttributes=" + _globalAttributes +
  393               "\n\n_globalTypes=" + _globalTypes +
  394               "\n}";
  395       }
  396   }

Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » inst2xsd » util » [javadoc | source]