You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlbeans.apache.org by ce...@apache.org on 2004/08/07 22:10:15 UTC

cvs commit: xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util Attribute.java Element.java Type.java TypeSystemHolder.java

cezar       2004/08/07 13:10:15

  Added:       v2/src/tools/org/apache/xmlbeans/impl/inst2xsd Inst2Xsd.java
                        Inst2XsdOptions.java RussianDollStrategy.java
                        SalamiSliceStrategy.java VenetianBlindStrategy.java
                        XsdGenStrategy.java
               v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util
                        Attribute.java Element.java Type.java
                        TypeSystemHolder.java
  Log:
  Instance 2 schema tool.
  
  checkintest: passes
  
  Revision  Changes    Path
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2Xsd.java
  
  Index: Inst2Xsd.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  import org.apache.xmlbeans.SchemaTypeLoader;
  import org.apache.xmlbeans.XmlBeans;
  import org.apache.xmlbeans.XmlException;
  import org.apache.xmlbeans.XmlObject;
  import org.apache.xmlbeans.XmlOptions;
  import org.w3.x2001.xmlSchema.SchemaDocument;
  import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
  
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.Reader;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Iterator;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   *
   * This class generates a set of XMLSchemas from an instance XML document.
   *
   * How it works:
   *  - first: pass through all the instances, building a TypeSystemHolder structure
   *  - second: serialize the TypeSystemHolder structure into   
   */
  public class Inst2Xsd
  {
      public static void main(String[] args)
          throws IOException, XmlException
      {
          if (args.length != 1)
          {
              System.out.println("Usage: Inst2xsd instance.xml");
              return;
          }
  
          File instFile = new File(args[0]);
          Inst2XsdOptions inst2XsdOptions = new Inst2XsdOptions();
          inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_VENETIAN_BLIND);
          SchemaDocument[] schemas = inst2xsd(new Reader[] {new FileReader(instFile)}, inst2XsdOptions);
      }
  
      private Inst2Xsd() {}
  
      public static SchemaDocument[] inst2xsd(Reader[] instReaders, Inst2XsdOptions options)
          throws IOException, XmlException
      {
          XmlObject[] instances = new XmlObject[ instReaders.length ];
          for (int i = 0; i < instReaders.length; i++)
          {
              instances[i] = XmlObject.Factory.parse(instReaders[i]);
          }
          return inst2xsd(instances, options);
      }
  
      public static SchemaDocument[] inst2xsd(XmlObject[] instances, Inst2XsdOptions options)
      {
          if (options==null)
              options = new Inst2XsdOptions();
  
          // create structure
          TypeSystemHolder typeSystemHolder = new TypeSystemHolder();
  
          XsdGenStrategy strategy;
          switch (options.getDesign())
          {
              case Inst2XsdOptions.DESIGN_RUSSIAN_DOLL:
                  strategy = new RussianDollStrategy();
                  break;
  
              case Inst2XsdOptions.DESIGN_SALAMI_SLICE:
                  strategy = new SalamiSliceStrategy();
                  break;
  
              case Inst2XsdOptions.DESIGN_VENETIAN_BLIND:
                  strategy = new VenetianBlindStrategy();
                  break;
  
              default:
                  throw new IllegalArgumentException("Unknown design.");
          }
          // processDoc the instance
          strategy.processDoc(instances, options, typeSystemHolder);
  
          // debug only
          //System.out.println("typeSystemHolder.toString(): " + typeSystemHolder);
          SchemaDocument[] sDocs = typeSystemHolder.getSchemaDocuments();
  
          for (int i = 0; i < sDocs.length; i++)
          {
              System.out.println("--------------------\n\n" + sDocs[i] );
          }
          assert validateInstances(sDocs, instances);
          // end debug only
  
          return sDocs;
      }
  
      private static boolean validateInstances(SchemaDocument[] sDocs, XmlObject[] instances)
      {
          SchemaTypeLoader sLoader;
          Collection compErrors = new ArrayList();
          XmlOptions schemaOptions = new XmlOptions();
          schemaOptions.setErrorListener(compErrors);
          try
          {
              sLoader = XmlBeans.loadXsd(sDocs, schemaOptions);
          }
          catch (Exception e)
          {
              if (compErrors.isEmpty() || !(e instanceof XmlException))
              {
                  e.printStackTrace(System.out);
              }
              System.out.println("Schema invalid");
              for (Iterator errors = compErrors.iterator(); errors.hasNext(); )
                  System.out.println(errors.next());
              return false;
          }
  
          boolean result = true;
  
          for (int i = 0; i < instances.length; i++)
          {
              String instance = instances[i].toString();
  
              XmlObject xobj;
  
              try
              {
                  xobj = sLoader.parse( instance, null, new XmlOptions().setLoadLineNumbers() );
              }
              catch (XmlException e)
              {
                  System.out.println("Error:\n" + instance + " not loadable: " + e);
                  e.printStackTrace(System.out);
                  result = false;
                  continue;
              }
  
              Collection errors = new ArrayList();
  
              if (xobj.schemaType() == XmlObject.type)
              {
                  System.out.println(instance + " NOT valid.  ");
                  System.out.println("  Document type not found." );
                  result = false;
              }
              else if (xobj.validate(new XmlOptions().setErrorListener(errors)))
                  System.out.println("Instance[" + i + "] valid.");
              else
              {
                  System.out.println("Instance[" + i + "] NOT valid.");
                  for (Iterator it = errors.iterator(); it.hasNext(); )
                  {
                      System.out.println("    " + it.next());
                  }
                  result = false;
              }
          }
  
          return result;
      }
  
  }
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2XsdOptions.java
  
  Index: Inst2XsdOptions.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 19, 2004
  
       Options:
         * Design
            o Russian Doll Design
            o Salami Slice Design
            o Venetian Blind Design
         * Simple content types (leafs)
            o smart (default) - try to find out the right simple shema type
            o always xsd:string
         * Use enumeration - when there are multiple valid values in a list
            o never
            o only if not more than ( 20 ) - number option
   */
  public class Inst2XsdOptions
  {
      // design
      public static final int DESIGN_RUSSIAN_DOLL   = 1;
      public static final int DESIGN_SALAMI_SLICE   = 2;
      public static final int DESIGN_VENETIAN_BLIND = 3;
  
      private int _design = DESIGN_RUSSIAN_DOLL;
  
      // schema type for simple content values
      public static final int SIMPLE_CONTENT_TYPES_SMART  = 1;
      public static final int SIMPLE_CONTENT_TYPES_STRING = 2;
  
      private int _simpleContentTypes = SIMPLE_CONTENT_TYPES_SMART;
  
      // use enumeration
      public static final int ENUMERATION_NEVER = 1;
      public static final int ENUMERATION_NOT_MORE_THAN_DEFAULT = 10;
  
      private int _enumerations = ENUMERATION_NOT_MORE_THAN_DEFAULT;
  
  
      public int getDesign()
      {
          return _design;
      }
  
      /**
       * Design
         o Russian Doll Design
         o Salami Slice Design
         o Venetian Blind Design
       * @param designType
       * @see #DESIGN_RUSSIAN_DOLL
       * @see #DESIGN_SALAMI_SLICE
       * @see #DESIGN_VENETIAN_BLIND
       */
      public void setDesign(int designType)
      {
          _design = designType;
      }
  
      public boolean isUseEnumerations()
      {
          return _enumerations>ENUMERATION_NEVER;
      }
  
      public int getUseEnumerations()
      {
          return _enumerations;
      }
  
      public void setUseEnumerations(int useEnumerations)
      {
          _enumerations = useEnumerations;
      }
  
      public int getSimpleContentTypes()
      {
          return _simpleContentTypes;
      }
  
      public void setSimpleContentTypes(int simpleContentTypes)
      {
          _simpleContentTypes = simpleContentTypes;
      }
  }
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/RussianDollStrategy.java
  
  Index: RussianDollStrategy.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  import org.apache.xmlbeans.*;
  import org.apache.xmlbeans.impl.common.PrefixResolver;
  import org.apache.xmlbeans.impl.common.ValidationContext;
  import org.apache.xmlbeans.impl.common.XmlWhitespace;
  import org.apache.xmlbeans.impl.inst2xsd.util.Attribute;
  import org.apache.xmlbeans.impl.inst2xsd.util.Element;
  import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
  import org.apache.xmlbeans.impl.inst2xsd.util.Type;
  import org.apache.xmlbeans.impl.util.XsTypeConverter;
  import org.apache.xmlbeans.impl.values.*;
  
  import javax.xml.namespace.QName;
  import java.util.*;
  
  /**
   * @author Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Jul 26, 2004
   */
  public class RussianDollStrategy
      implements XsdGenStrategy
  {
      public void processDoc(XmlObject[] instances, Inst2XsdOptions options, TypeSystemHolder typeSystemHolder)
      {
          for (int i = 0; i < instances.length; i++)
          {
              XmlObject instance = instances[i];
              XmlCursor xc = instance.newCursor();
              // xc on start doc
  
              StringBuffer comment = new StringBuffer();
  
              while( !xc.isStart() )
              {
                  xc.toNextToken();
                  if( xc.isComment() )
                      comment.append(xc.getTextValue());
              }
              // xc now on the root element
  
              Element withElem = processElement(xc, comment.toString(), options, typeSystemHolder);
              withElem.setGlobal(true);
  
              Element intoElem = typeSystemHolder.getGlobalElement(withElem.getName());
  
              if (intoElem==null)
                  typeSystemHolder.addGlobalElement(withElem);
              else
              {
                  combineTypes(intoElem.getType(), withElem.getType(), options);
                  combineElementComments(intoElem, withElem);
              }
          }
      }
  
      protected Element processElement(XmlCursor xc, String comment,
          Inst2XsdOptions options, TypeSystemHolder typeSystemHolder)
      {
          assert xc.isStart();
          Element element = new Element();
          element.setName(xc.getName());
          element.setGlobal(false);
  
          Type elemType = Type.createUnnamedType(Type.SIMPLE_TYPE_SIMPLE_CONTENT); //assume simple, set later
          element.setType(elemType);
  
          StringBuffer textBuff = new StringBuffer();
          StringBuffer commentBuff = new StringBuffer();
          List children = new ArrayList();
          List attributes = new ArrayList();
  
          loop: do
          {
              XmlCursor.TokenType tt = xc.toNextToken();
              switch (tt.intValue())
              {
                  case XmlCursor.TokenType.INT_ATTR:
                      // todo check for xsi:type
                      attributes.add(processAttribute(xc, options, element.getName().getNamespaceURI(), typeSystemHolder));
                      break;
  
                  case XmlCursor.TokenType.INT_START:
                      children.add(processElement(xc, commentBuff.toString(), options, typeSystemHolder));
                      commentBuff.delete(0, commentBuff.length());
                      break;
  
                  case XmlCursor.TokenType.INT_TEXT:
                      textBuff.append(xc.getChars());
                      break;
  
                  case XmlCursor.TokenType.INT_COMMENT:
                      commentBuff.append(xc.getTextValue());
                      break;
  
                  case XmlCursor.TokenType.INT_NAMESPACE:
                      // ignore for now,
                      // each element and attribute will take care to define itself in the right targetNamespace
                      break;
  
                  case XmlCursor.TokenType.INT_END:
                      break loop;
  
                  case XmlCursor.TokenType.INT_PROCINST:
                      // ignore
                      break;
  
                  case XmlCursor.TokenType.INT_ENDDOC:
                      throw new IllegalStateException();
  
                  case XmlCursor.TokenType.INT_NONE:
                      throw new IllegalStateException();
  
                  case XmlCursor.TokenType.INT_STARTDOC:
                      throw new IllegalStateException();
  
                  default:
                      throw new IllegalStateException("Unknown TokenType.");
              }
          }
          while( true );
  
          String collapsedText =  XmlWhitespace.collapse(textBuff.toString(), XmlWhitespace.WS_COLLAPSE);
  
          String commnetStr = (comment == null ?
              ( commentBuff.length() == 0 ? null : commentBuff.toString() ) :
              ( commentBuff.length() == 0 ? comment : commentBuff.insert(0, comment).toString()) );
          element.setComment(commnetStr);
  
          if (children.size()>0)
          {
              // complex content
              if (collapsedText.length()>0)
              {
                  elemType.setContentType(Type.COMPLEX_TYPE_MIXED_CONTENT);
              }
              else
              {
                  elemType.setContentType(Type.COMPLEX_TYPE_COMPLEX_CONTENT);
              }
              processElementsInComplexType(elemType, children, element.getName().getNamespaceURI(), typeSystemHolder, options);
              processAttributesInComplexType(elemType, attributes);
          }
          else
          {
              // simple content
              xc.toParent();  // hack workaround for being able to call xc.getNamespaceForPrefix()
              if (attributes.size()>0)
              {
                  elemType.setContentType(Type.COMPLEX_TYPE_SIMPLE_CONTENT);
  
                  Type extendedType = Type.createNamedType(
                      processSimpleContentType(textBuff.toString(), options, xc), Type.SIMPLE_TYPE_SIMPLE_CONTENT);
                  elemType.setExtensionType(extendedType);
  
                  processAttributesInComplexType(elemType, attributes);
              }
              else
              {
                  elemType.setContentType(Type.SIMPLE_TYPE_SIMPLE_CONTENT);
                  elemType.setName(processSimpleContentType(textBuff.toString(), options, xc));
  
                  // add enumeration value
                  String enumValue = XmlString.type.getName().equals(elemType.getName()) ? textBuff.toString() : collapsedText;
                  elemType.addEnumerationValue(enumValue);
              }
  
              xc.toEndToken(); // end hack
          }
  
          checkIfReferenceToGlobalTypeIsNeeded( element, typeSystemHolder, options);
  
          xc.toNextToken();  // advance over end element
          return element;
      }
  
      protected void processElementsInComplexType(Type elemType, List children, String parentNamespace,
          TypeSystemHolder typeSystemHolder, Inst2XsdOptions options)
      {
          Map elemNamesToElements = new HashMap();
          Element currentElem = null;
  
          for (Iterator iterator = children.iterator(); iterator.hasNext();)
          {
              Element child = (Element) iterator.next();
  
              if (currentElem==null)
              {   // first element in this type
                  checkIfElementReferenceIsNeeded(child, parentNamespace, typeSystemHolder);
                  elemType.addElement(child);
                  elemNamesToElements.put(child.getName(), child);
                  currentElem = child;
                  continue;
              }
  
              if (currentElem.getName()==child.getName())
              {   // same contiguos element
                  combineTypes(currentElem.getType(), child.getType(), options); // unify types
                  combineElementComments(currentElem, child);
                  // minOcc=0 maxOcc=unbounded
                  currentElem.setMinOccurs(0);
                  currentElem.setMaxOccurs(Element.UNBOUNDED);
              }
              else
              {
                  Element sameElem = (Element)elemNamesToElements.get(child.getName());
                  if (sameElem==null)
                  {   // new element name
                      checkIfElementReferenceIsNeeded(child, parentNamespace, typeSystemHolder);
                      elemType.addElement(child);
                      elemNamesToElements.put(child.getName(), child);
                  }
                  else
                  {   //same non contiguos
                      combineTypes(currentElem.getType(), child.getType(), options);
                      combineElementComments(currentElem, child);
                      elemType.setTopParticleForComplexOrMixedContent(Type.PARTICLE_CHOICE_UNBOUNDED);
                  }
                  currentElem = child;
              }
          }
      }
  
      protected void checkIfElementReferenceIsNeeded(Element child, String parentNamespace, TypeSystemHolder typeSystemHolder)
      {
          if (!child.getName().getNamespaceURI().equals(parentNamespace))
          {
              Element referencedElem = new Element();
              referencedElem.setGlobal(true);
              referencedElem.setName(child.getName());
              referencedElem.setType(child.getType());
  
              typeSystemHolder.addGlobalElement(referencedElem);
  
              child.setRef(referencedElem); // clears child's type
          }
      }
  
      protected void checkIfReferenceToGlobalTypeIsNeeded(Element elem, TypeSystemHolder typeSystemHolder,
          Inst2XsdOptions options)
      {
          // RussianDollDesign doesn't define global types
      }
  
      protected void processAttributesInComplexType(Type elemType, List attributes)
      {
          assert elemType.isComplexType();
          for (Iterator iterator = attributes.iterator(); iterator.hasNext();)
          {
              Attribute att = (Attribute) iterator.next();
              elemType.addAttribute(att);
          }
      }
  
      protected Attribute processAttribute(XmlCursor xc, Inst2XsdOptions options, String parentNamespace,
                                                TypeSystemHolder typeSystemHolder)
      {
          Attribute attribute = new Attribute();
          QName attName = xc.getName();
  
          attribute.setName(attName);
  
          Type simpleContentType = Type.createNamedType(
              processSimpleContentType(xc.getTextValue(), options, xc), Type.SIMPLE_TYPE_SIMPLE_CONTENT);
  
          attribute.setType(simpleContentType);
  
          checkIfAttributeReferenceIsNeeded(attribute, parentNamespace, typeSystemHolder);
  
          return attribute;
      }
  
      protected void checkIfAttributeReferenceIsNeeded(Attribute attribute, String parentNamespace, TypeSystemHolder typeSystemHolder)
      {
          if (!attribute.getName().getNamespaceURI().equals("") &&
              !attribute.getName().getNamespaceURI().equals(parentNamespace))
          {
              // make attribute be a reference to a top level attribute in a different targetNamespace
              Attribute referencedAtt = new Attribute();
              referencedAtt.setGlobal(true);
              referencedAtt.setName(attribute.getName());
              referencedAtt.setType(attribute.getType());
  
              typeSystemHolder.addGlobalAttribute(referencedAtt);
  
              attribute.setRef(referencedAtt);
          }
      }
  
      protected class SCTValidationContext
          implements ValidationContext
      {
          protected boolean valid = true;
  
          public boolean isValid()
          {
              return valid;
          }
  
          public void resetToValid()
          {
              valid = true;
          }
  
          public void invalid(String message)
          {
              valid = false;
          }
      }
  
      private SCTValidationContext _validationContext = new SCTValidationContext();
  
  
      // List of precedence for smart simple primitive type determination
      // byte, short, int, long, integer, float, double, decimal,
      // boolean
      // date, dateTime, time, gDuration,
      // QName ?,
      // anyUri ? - triggered only for http:// or www. constructs,
      // list types ?
      // string
      protected QName processSimpleContentType(String lexicalValue, Inst2XsdOptions options, final XmlCursor xc)
      {
          // check options and return xsd:string or if smart is enabled, look for a better type
          if (options.getSimpleContentTypes()==Inst2XsdOptions.SIMPLE_CONTENT_TYPES_STRING)
              return XmlString.type.getName();
  
          if (options.getSimpleContentTypes()!=Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART)
              throw new IllegalArgumentException("Unknown value for Inst2XsdOptions.getSimpleContentTypes() :" + options.getSimpleContentTypes());
  
          // Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART case
  
  
          try
          {
              XsTypeConverter.lexByte(lexicalValue);
              return XmlByte.type.getName();
          }
          catch (Exception e) {}
  
          try
          {
              XsTypeConverter.lexShort(lexicalValue);
              return XmlShort.type.getName();
          }
          catch (Exception e) {}
  
          try
          {
              XsTypeConverter.lexInt(lexicalValue);
              return XmlInt.type.getName();
          }
          catch (Exception e) {}
  
          try
          {
              XsTypeConverter.lexLong(lexicalValue);
              return XmlLong.type.getName();
          }
          catch (Exception e) {}
  
          try
          {
              XsTypeConverter.lexInteger(lexicalValue);
              return XmlInteger.type.getName();
          }
          catch (Exception e) {}
  
          try
          {
              XsTypeConverter.lexFloat(lexicalValue);
              return XmlFloat.type.getName();
          }
          catch (Exception e) {}
  
  //        // this not needed because it's lexical space is covered by float
  //        try
  //        {
  //            XsTypeConverter.lexDouble(lexicalValue);
  //            return XmlDouble.type.getName();
  //        }
  //        catch (Exception e) {}
  //
  //        try
  //        {
  //            XsTypeConverter.lexDecimal(lexicalValue);
  //            return XmlDecimal.type.getName();
  //        }
  //        catch (Exception e) {}
  
          XmlDateImpl.validateLexical(lexicalValue, XmlDate.type, _validationContext);
          if (_validationContext.isValid())
              return XmlDate.type.getName();
          _validationContext.resetToValid();
  
          XmlDateTimeImpl.validateLexical(lexicalValue, XmlDateTime.type, _validationContext);
          if (_validationContext.isValid())
              return XmlDateTime.type.getName();
          _validationContext.resetToValid();
  
          XmlTimeImpl.validateLexical(lexicalValue, XmlTime.type, _validationContext);
          if (_validationContext.isValid())
              return XmlTime.type.getName();
          _validationContext.resetToValid();
  
          XmlDurationImpl.validateLexical(lexicalValue, XmlDuration.type, _validationContext);
          if (_validationContext.isValid())
              return XmlDuration.type.getName();
          _validationContext.resetToValid();
  
          // check for uri
          if (lexicalValue.startsWith("http://") || lexicalValue.startsWith("www."))
          {
              XmlAnyUriImpl.validateLexical(lexicalValue, _validationContext);
              if (_validationContext.isValid())
                  return XmlAnyURI.type.getName();
              _validationContext.resetToValid();
          }
  
          // check for QName
          if (lexicalValue.indexOf(':')>=0 && lexicalValue.indexOf(':')==lexicalValue.lastIndexOf(':'))
          {
              PrefixResolver prefixResolver = new PrefixResolver()
              {
                  public String getNamespaceForPrefix(String prefix)
                  {  return xc.prefixForNamespace(prefix); }
              };
  
              XmlQNameImpl.validateLexical(lexicalValue, _validationContext, prefixResolver);
              if (_validationContext.isValid())
                  return XmlQName.type.getName();
              _validationContext.resetToValid();
          }
  
          //the check for lists is probably too expensive
  
          return XmlString.type.getName();
      }
  
      protected void combineTypes(Type into, Type with, Inst2XsdOptions options)
      {
          if (into.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT &&
              with.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT)
          {
              combineSimpleTypes(into, with, options);
              return;
          }
  
          if ((into.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              into.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT) &&
              (with.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              with.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT) )
          {
              //complex type simple content
              into.setContentType(Type.COMPLEX_TYPE_SIMPLE_CONTENT);
  
              // take the extension name if it's a complex type
              QName intoTypeName = into.isComplexType() ? into.getExtensionType().getName() : into.getName();
              QName withTypeName = with.isComplexType() ? with.getExtensionType().getName() : with.getName();
  
              QName moreGeneralTypeName = combineToMoreGeneralSimpleType(intoTypeName, withTypeName);
              if (into.isComplexType())
              {
                  Type extendedType = Type.createNamedType(moreGeneralTypeName, Type.SIMPLE_TYPE_SIMPLE_CONTENT);
                  into.setExtensionType(extendedType);
              }
              else
                  into.setName(moreGeneralTypeName);
  
              combineAttributesOfTypes(into, with);
              return;
          }
  
          if (into.getContentType()==Type.COMPLEX_TYPE_COMPLEX_CONTENT &&
              with.getContentType()==Type.COMPLEX_TYPE_COMPLEX_CONTENT)
          {
              combineAttributesOfTypes(into, with);
              combineElementsOfTypes(into, with, false, options);
              return;
          }
  
          if (into.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              into.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT ||
              with.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              with.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT)
          {
              into.setContentType(Type.COMPLEX_TYPE_MIXED_CONTENT);
              combineAttributesOfTypes(into, with);
              combineElementsOfTypes(into, with, true, options);
              return;
          }
  
          if ((into.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              into.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT ||
              into.getContentType()==Type.COMPLEX_TYPE_COMPLEX_CONTENT ||
              into.getContentType()==Type.COMPLEX_TYPE_MIXED_CONTENT) &&
              (with.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT ||
              with.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT ||
              with.getContentType()==Type.COMPLEX_TYPE_COMPLEX_CONTENT ||
              with.getContentType()==Type.COMPLEX_TYPE_MIXED_CONTENT) )
          {
              into.setContentType(Type.COMPLEX_TYPE_MIXED_CONTENT);
              combineAttributesOfTypes(into, with);
              combineElementsOfTypes(into, with, false, options);
              return;
          }
  
          throw new IllegalArgumentException("Unknown content type.");
      }
  
      protected void combineSimpleTypes(Type into, Type with, Inst2XsdOptions options)
      {
          assert (into.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT &&
              with.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT) : "Invalid arguments";
  
          //simple type simple content
  
          into.setName(combineToMoreGeneralSimpleType(into.getName(), with.getName()));
  
          // take care of enumeration values
          if (options.isUseEnumerations())
          {
              for (int i = 0; i < with.getEnumerationValues().size(); i++)
              {
                  String enumValue = (String) with.getEnumerationValues().get(i);
                  into.addEnumerationValue(enumValue);
              }
  
              if (into.getEnumerationValues().size()>options.getUseEnumerations())
              {
                  into.closeEnumeration();
              }
          }
      }
  
      protected QName combineToMoreGeneralSimpleType(QName t1, QName t2)
      {
          if (t1.equals(t2))
              return t1;
  
          if (t2.equals(XmlShort.type.getName()) && t1.equals(XmlByte.type.getName()))
              return t2;
          if (t1.equals(XmlShort.type.getName()) && t2.equals(XmlByte.type.getName()))
              return t1;
  
          if (t2.equals(XmlInt.type.getName()) &&
              (t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) )
              return t2;
          if (t1.equals(XmlInt.type.getName()) &&
              (t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) )
              return t1;
  
          if (t2.equals(XmlLong.type.getName()) &&
              (t1.equals(XmlInt.type.getName()) || t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) )
              return t2;
          if (t1.equals(XmlLong.type.getName()) &&
              (t2.equals(XmlInt.type.getName()) || t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) )
              return t1;
  
          if (t2.equals(XmlInteger.type.getName()) &&
              (t1.equals(XmlLong.type.getName()) || t1.equals(XmlInt.type.getName()) ||
              t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) )
              return t2;
          if (t1.equals(XmlInteger.type.getName()) &&
              (t2.equals(XmlLong.type.getName()) || t2.equals(XmlInt.type.getName()) ||
              t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) )
              return t1;
  
          if (t2.equals(XmlFloat.type.getName()) &&
              (t1.equals(XmlInteger.type.getName()) ||
              t1.equals(XmlLong.type.getName()) || t1.equals(XmlInt.type.getName()) ||
              t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) )
              return t2;
          if (t1.equals(XmlFloat.type.getName()) &&
              (t2.equals(XmlInteger.type.getName()) ||
              t2.equals(XmlLong.type.getName()) || t2.equals(XmlInt.type.getName()) ||
              t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) )
              return t1;
  
          //double, decimal will never get here since they don't get generated
  
          //the rest of the combinations are not compatible, so they will combine in xsd:string
          return XmlString.type.getName();
      }
  
      protected void combineAttributesOfTypes(Type into, Type from)
      {
          // loop through attributes: add fromAtt if they don't exist, combine them if they exist
          outterLoop:
          for (int i = 0; i < from.getAttributes().size(); i++)
          {
              Attribute fromAtt = (Attribute)from.getAttributes().get(i);
              for (int j = 0; j < into.getAttributes().size(); j++)
              {
                  Attribute intoAtt = (Attribute)into.getAttributes().get(j);
                  if (intoAtt.getName().equals(fromAtt.getName()))
                  {
                      intoAtt.getType().setName(
                          combineToMoreGeneralSimpleType(intoAtt.getType().getName(), fromAtt.getType().getName()));
                      continue outterLoop;
                  }
              }
              // fromAtt doesn't exist in into type, will add it right now
              into.addAttribute(fromAtt);
          }
  
          //optional attributes: if there are atts in into that are not in from, make them optional
          outterLoop:
          for (int i = 0; i < into.getAttributes().size(); i++)
          {
              Attribute intoAtt = (Attribute)into.getAttributes().get(i);
              for (int j = 0; j < from.getAttributes().size(); j++)
              {
                  Attribute fromAtt = (Attribute)from.getAttributes().get(j);
                  if (fromAtt.getName().equals(intoAtt.getName()))
                  {
                      continue;
                  }
              }
              // intoAtt doesn't exist in into type, will add it right now
              intoAtt.setOptional(true);
          }
      }
  
      protected void combineElementsOfTypes(Type into, Type from, boolean makeElementsOptional, Inst2XsdOptions options)
      {
          // loop through elements: add fromElem if they don't exist, combine them if they exist
          outterLoop:
          for (int i = 0; i < from.getElements().size(); i++)
          {
              Element fromElem = (Element)from.getElements().get(i);
              for (int j = 0; j < into.getElements().size(); j++)
              {
                  Element intoElem = (Element)into.getElements().get(j);
                  if (intoElem.getName().equals(fromElem.getName()))
                  {
                      combineTypes(intoElem.getType(), fromElem.getType(), options);
                      combineElementComments(intoElem, fromElem);
                      if (fromElem.getMaxOccurs()==Element.UNBOUNDED)
                          intoElem.setMaxOccurs(Element.UNBOUNDED);
                      combineElementComments(intoElem, fromElem);
                      continue outterLoop;
                  }
              }
              // fromElem doesn't exist in into type, will add it right now
              into.addElement(fromElem);
          }
  
          // for all the elements that are in into and not in from they need to be optional
          outterLoop:
          for (int i = 0; i < into.getElements().size(); i++)
          {
              Element intoElem = (Element)into.getElements().get(i);
  
              if (makeElementsOptional)
              {
                  intoElem.setMinOccurs(0);
                  continue;
              }
  
              for (int j = 0; j < from.getElements().size(); j++)
              {
                  Element fromElem = (Element)from.getElements().get(j);
                  if (intoElem.getName().equals(fromElem.getName()))
                  {
                      continue outterLoop;
                  }
              }
              // intoElem doesn't exist in from type, make it optional
              intoElem.setMinOccurs(0);
              //intoElem.setMaxOccurs(Element.UNBOUNDED);
          }
      }
  
      protected void combineElementComments(Element into, Element with)
      {
          if (with.getComment()!=null || with.getComment().length()>0)
          {
              if (into.getComment()==null)
                  into.setComment(with.getComment());
              else
                  into.setComment(into.getComment() + with.getComment());
          }
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/SalamiSliceStrategy.java
  
  Index: SalamiSliceStrategy.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  import org.apache.xmlbeans.impl.inst2xsd.util.Element;
  import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
  
  /**
   * @author Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Jul 26, 2004
   */
  public class SalamiSliceStrategy
      extends RussianDollStrategy
      implements XsdGenStrategy
  {
      protected void checkIfElementReferenceIsNeeded(Element child, String parentNamespace, TypeSystemHolder typeSystemHolder)
      {
          // always add element references
          Element referencedElem = new Element();
          referencedElem.setGlobal(true);
          referencedElem.setName(child.getName());
          referencedElem.setType(child.getType());
  
          typeSystemHolder.addGlobalElement(referencedElem);
  
          child.setRef(referencedElem); // clears child's type
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/VenetianBlindStrategy.java
  
  Index: VenetianBlindStrategy.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  import org.apache.xmlbeans.impl.inst2xsd.util.Element;
  import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
  import org.apache.xmlbeans.impl.inst2xsd.util.Type;
  
  import javax.xml.namespace.QName;
  
  /**
   * @author Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Jul 26, 2004
   */
  public class VenetianBlindStrategy
      extends RussianDollStrategy
      implements XsdGenStrategy
  {
      protected void checkIfReferenceToGlobalTypeIsNeeded(Element elem,
          TypeSystemHolder typeSystemHolder, Inst2XsdOptions options)
      {
          // VenetianBlindDesign defines global complex types
          Type elemType = elem.getType();
          QName elemName = elem.getName();
  
          if (elemType.isGlobal())
              // is already global, do nothing
              return;
  
          if (elemType.isComplexType())
          {
              for (int i = 0; ; i++)
              {
                  elemType.setName(new QName(elemName.getNamespaceURI(), elemName.getLocalPart() + "Type" + (i==0 ? "" : "" + i)));
  
                  Type candidate = typeSystemHolder.getGlobalType(elemType.getName());
                  if (candidate==null)
                  {
                      elemType.setGlobal(true);
                      typeSystemHolder.addGlobalType(elemType);
                      break;
                  }
                  else
                  {
                      if (compatibleTypes(elemType, candidate))
                      {
                          combineTypes(candidate, elemType, options);
                          elem.setType(candidate);
                          break;
                      }
                  }
              }
          }
      }
  
      private boolean compatibleTypes(Type elemType, Type candidate)
      {
          // when two types look like they are the same ?
  
          if (!elemType.isComplexType() && !candidate.isComplexType())
              return true;
  
          if (elemType.isComplexType() && !candidate.isComplexType())
              return false;
          if (!elemType.isComplexType() && candidate.isComplexType())
              return false;
  
          // both complex after this point
  
          //todo: be smarter: look at att and elem names and types - compute a difference index
  
          return true;
      }
  }
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/XsdGenStrategy.java
  
  Index: XsdGenStrategy.java
  ===================================================================
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Jul 26, 2004
   */
  package org.apache.xmlbeans.impl.inst2xsd;
  
  import org.apache.xmlbeans.XmlObject;
  import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
  import org.apache.xmlbeans.impl.inst2xsd.Inst2XsdOptions;
  
  interface XsdGenStrategy
  {
      void processDoc(XmlObject[] instances, Inst2XsdOptions options, TypeSystemHolder typeSystemHolder);
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Attribute.java
  
  Index: Attribute.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd.util;
  
  import javax.xml.namespace.QName;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 18, 2004
   */
  public class Attribute
  {
      private QName _name;
      private Type _type;
      private Attribute _ref = null;
      private boolean _isGlobal = false;
      private boolean _isOptional = false;
  
      public QName getName()
      {
          return _name;
      }
  
      public void setName(QName name)
      {
          _name = name;
      }
  
      public Type getType()
      {
          return isRef() ? getRef().getType() : _type;
      }
  
      public void setType(Type type)
      {
          assert !isRef();
          _type = type;
      }
  
      public boolean isRef()
      {
          return _ref!=null;
      }
  
      public Attribute getRef()
      {
          return _ref;
      }
  
      public void setRef(Attribute ref)
      {
          assert !isGlobal();
          _ref = ref;
          _type = null;
      }
  
      public boolean isGlobal()
      {
          return _isGlobal;
      }
  
      public void setGlobal(boolean isGlobal)
      {
          _isGlobal = isGlobal;
      }
  
      public boolean isOptional()
      {
          return _isOptional;
      }
  
      public void setOptional(boolean isOptional)
      {
          assert isOptional && !isGlobal() : "Global attributes cannot be optional.";
          _isOptional = isOptional;
      }
  
      public String toString()
      {
          return "\n    Attribute{" +
              "_name=" + _name +
              ", _type=" + _type +
              ", _ref=" + (_ref!=null) +
              ", _isGlobal=" + _isGlobal +
              ", _isOptional=" + _isOptional +
              "}";
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Element.java
  
  Index: Element.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd.util;
  
  import javax.xml.namespace.QName;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   */
  public class Element
  {
      private QName _name = null; // if isRef is true is the name of the referenced name
      private Element _ref = null;
      private boolean _isGlobal = false;
      private int _minOccurs = 1;
      private int _maxOccurs = 1;
      public static final int UNBOUNDED = -1;
      private Type _type = null;
      private String _comment = null;
  
      public QName getName()
      {
          return _name;
      }
  
      public void setName(QName name)
      {
          _name = name;
      }
  
      public boolean isRef()
      {
          return _ref!=null;
      }
  
      public Element getRef()
      {
          return _ref;
      }
  
      public void setRef(Element ref)
      {
          assert _isGlobal==false;
          _ref = ref;
          _type = null;
      }
  
      public boolean isGlobal()
      {
          return _isGlobal;
      }
  
      public void setGlobal(boolean isGlobal)
      {
          _isGlobal = isGlobal;
          _minOccurs = 1;
          _maxOccurs = 1;
      }
  
      public int getMinOccurs()
      {
          return _minOccurs;
      }
  
      public void setMinOccurs(int minOccurs)
      {
          _minOccurs = minOccurs;
      }
  
      public int getMaxOccurs()
      {
          return _maxOccurs;
      }
  
      public void setMaxOccurs(int maxOccurs)
      {
          _maxOccurs = maxOccurs;
      }
  
      public Type getType()
      {
          return isRef() ? getRef().getType() : _type;
      }
  
      public void setType(Type type)
      {
          assert !isRef();
          _type = type;
      }
  
      public String getComment()
      {
          return _comment;
      }
  
      public void setComment(String comment)
      {
          _comment = comment;
      }
  
      public String toString()
      {
          return "\n  Element{" +
              " _name = " + _name +
              ", _ref = " + (_ref!=null) +
              ", _isGlobal = " + _isGlobal +
              ", _minOccurs = " + _minOccurs +
              ", _maxOccurs = " + _maxOccurs +
              ", _comment = " + _comment +
              ",\n    _type = " + _type +
              "\n  }";
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Type.java
  
  Index: Type.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd.util;
  
  import javax.xml.namespace.QName;
  import java.util.List;
  import java.util.ArrayList;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   */
  public class Type
  {
      private QName _name;
  
      private int _kind = SIMPLE_TYPE_SIMPLE_CONTENT;
      // _kind value space
      public static final int SIMPLE_TYPE_SIMPLE_CONTENT   = 1; // ie no atts, no elems, just text
      public static final int COMPLEX_TYPE_SIMPLE_CONTENT  = 2; // ie atts*, no elems, text*   - simple type extension
      public static final int COMPLEX_TYPE_COMPLEX_CONTENT = 3; // ie atts*, elems, no text
      public static final int COMPLEX_TYPE_MIXED_CONTENT   = 4; // ie atts*, elems, text
  
      private int _topParticleForComplexOrMixedContent = PARTICLE_SEQUENCE;
      // _topParticleForComplexOrMixedContent
      public static final int PARTICLE_SEQUENCE         = 1;
      public static final int PARTICLE_CHOICE_UNBOUNDED = 2;
  
      private List _elements;  // size>0 COMPLEX
      private List _attributes; // size>0 COMPLEX
  
      private Type _extensionType;
      private boolean _isGlobal = false;
  
      private List _enumerationValues;
      private boolean _acceptsEnumerationValue = true;
  
      private Type()
      {}
  
      public static Type createNamedType(QName name, int contentType)
      {
          assert name!=null;
          Type type = new Type();
          type.setName(name);
          type.setContentType(contentType);
          return type;
      }
  
      public static Type createUnnamedType(int contentType)
      {
          assert contentType==SIMPLE_TYPE_SIMPLE_CONTENT ||
              contentType==COMPLEX_TYPE_SIMPLE_CONTENT ||
              contentType==COMPLEX_TYPE_COMPLEX_CONTENT ||
              contentType==COMPLEX_TYPE_MIXED_CONTENT : "Unknown contentType: " + contentType;
          Type type = new Type();
          type.setContentType(contentType);
          return type;
      }
  
  
      public QName getName()
      {
          return _name;
      }
  
      public void setName(QName name)
      {
          this._name = name;
      }
  
      public int getContentType()
      {
          return _kind;
      }
  
      public void setContentType(int kind)
      {
          this._kind = kind;
      }
  
      public List getElements()
      {
          ensureElements();
          return _elements;
      }
  
      public void addElement(Element element)
      {
          ensureElements();
          _elements.add(element);
      }
  
      private void ensureElements()
      {
          if (_elements==null)
              _elements = new ArrayList();
      }
  
      public List getAttributes()
      {
          ensureAttributes();
          return _attributes;
      }
  
      public void addAttribute(Attribute attribute)
      {
          ensureAttributes();
          _attributes.add(attribute);
      }
  
      public Attribute getAttribute(QName name)
      {
          for (int i = 0; i < _attributes.size(); i++)
          {
              Attribute attribute = (Attribute) _attributes.get(i);
              if (attribute.getName().equals(name))
                  return attribute;
          }
          return null;
      }
  
      private void ensureAttributes()
      {
          if (_attributes==null)
              _attributes = new ArrayList();
      }
  
      public boolean isComplexType()
      {
          return (_kind==COMPLEX_TYPE_COMPLEX_CONTENT ||
              _kind==COMPLEX_TYPE_MIXED_CONTENT||
              _kind==COMPLEX_TYPE_SIMPLE_CONTENT);
      }
  
      public boolean hasSimpleContent()
      {
          return (_kind==SIMPLE_TYPE_SIMPLE_CONTENT ||
              _kind==COMPLEX_TYPE_SIMPLE_CONTENT);
      }
  
      public int getTopParticleForComplexOrMixedContent()
      {
          return _topParticleForComplexOrMixedContent;
      }
  
      public void setTopParticleForComplexOrMixedContent(int _topParticleForComplexOrMixedContent)
      {
          this._topParticleForComplexOrMixedContent = _topParticleForComplexOrMixedContent;
      }
  
      public boolean isGlobal()
      {
          return _isGlobal;
      }
  
      public void setGlobal(boolean isGlobal)
      {
          assert isGlobal && getName()!=null;
          _isGlobal = isGlobal;
      }
  
      public Type getExtensionType()
      {
          return _extensionType;
      }
  
      public void setExtensionType(Type extendedType)
      {
          assert _kind == COMPLEX_TYPE_SIMPLE_CONTENT : "Extension used only for type which are COMPLEX_TYPE_SIMPLE_CONTENT";
          assert extendedType!=null && extendedType.getName()!=null : "Extended type must be a named type.";
          _extensionType = extendedType;
      }
  
      public List getEnumerationValues()
      {
          ensureEnumerationValues();
          return _enumerationValues;
      }
  
      public void addEnumerationValue(String enumerationValue)
      {
          assert _kind==SIMPLE_TYPE_SIMPLE_CONTENT || _kind==COMPLEX_TYPE_SIMPLE_CONTENT : "Enumerations possible only on simple content";
          ensureEnumerationValues();
          if (_acceptsEnumerationValue && !_enumerationValues.contains(enumerationValue))
          {
              _enumerationValues.add(enumerationValue);
          }
      }
  
      private void ensureEnumerationValues()
      {
          if (_enumerationValues==null)
              _enumerationValues = new ArrayList();
      }
  
      public boolean isEnumeration()
      {
          return _acceptsEnumerationValue && _enumerationValues!=null && _enumerationValues.size()>1;
      }
  
      public void closeEnumeration()
      {
          _acceptsEnumerationValue=false;
      }
  
      public String toString()
      {
          return "Type{" +
              "_name = " + _name +
              ", _extensionType = " + _extensionType +
              ", _kind = " + _kind +
              ", _elements = " + _elements +
              ", _attributes = " + _attributes +
              "}";
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v2/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/TypeSystemHolder.java
  
  Index: TypeSystemHolder.java
  ===================================================================
  /*   Copyright 2004 The Apache Software Foundation
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.xmlbeans.impl.inst2xsd.util;
  
  import org.w3.x2001.xmlSchema.SchemaDocument;
  import org.apache.xmlbeans.XmlString;
  
  import javax.xml.namespace.QName;
  import java.math.BigInteger;
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  /**
   * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   */
  public class TypeSystemHolder
  {
      Map _globalElements;   // QName -> Element
      Map _globalAttributes; // QName -> Attribute
      Map _globalTypes;      // QName -> Type
  
      public TypeSystemHolder()
      {
          _globalElements = new HashMap();
          _globalAttributes = new HashMap();
          _globalTypes = new HashMap();
      }
  
      public void addGlobalElement(Element element)
      {
          assert element.isGlobal() && !element.isRef();
          _globalElements.put(element.getName(), element);
      }
  
      public Element getGlobalElement(QName name)
      {
          return (Element)_globalElements.get(name);
      }
  
      public Element[] getGlobalElements()
      {
          Collection col = _globalElements.values();
          return (Element[])col.toArray(new Element[col.size()]);
      }
  
      public void addGlobalAttribute(Attribute attribute)
      {
          assert attribute.isGlobal() && !attribute.isRef();
          _globalAttributes.put(attribute.getName(), attribute);
      }
  
      public Attribute getGlobalAttribute(QName name)
      {
          return (Attribute)_globalAttributes.get(name);
      }
  
      public Attribute[] getGlobalAttributes()
      {
          Collection col = _globalAttributes.values();
          return (Attribute[])col.toArray(new Attribute[col.size()]);
      }
  
      public void addGlobalType(Type type)
      {
          assert type.isGlobal() && type.getName()!=null : "type must be a global type before being added.";
          _globalTypes.put(type.getName(), type);
      }
  
      public Type getGlobalType(QName name)
      {
          return (Type)_globalTypes.get(name);
      }
  
      public Type[] getGlobalTypes()
      {
          Collection col = _globalTypes.values();
          return (Type[])col.toArray(new Type[col.size()]);
      }
  
      public SchemaDocument[] getSchemaDocuments()
      {
          // recompute everything, should cache it and track changes
          Map nsToSchemaDocs = new HashMap();
  
          for (Iterator iterator = _globalElements.keySet().iterator(); iterator.hasNext();)
          {
              QName globalElemName = (QName) iterator.next();
              String tns = globalElemName.getNamespaceURI();
              SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  
              fillUpGlobalElement((Element)_globalElements.get(globalElemName), schDoc, tns);
          }
  
          for (Iterator iterator = _globalAttributes.keySet().iterator(); iterator.hasNext();)
          {
              QName globalAttName = (QName) iterator.next();
              String tns = globalAttName.getNamespaceURI();
              SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  
              fillUpGlobalAttribute((Attribute)_globalAttributes.get(globalAttName), schDoc, tns);
          }
  
          for (Iterator iterator = _globalTypes.keySet().iterator(); iterator.hasNext();)
          {
              QName globalTypeName = (QName) iterator.next();
              String tns = globalTypeName.getNamespaceURI();
              SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns);
  
              fillUpGlobalType((Type)_globalTypes.get(globalTypeName), schDoc, tns);
          }
  
          Collection schDocColl = nsToSchemaDocs.values();
          return (SchemaDocument[])schDocColl.toArray(new SchemaDocument[schDocColl.size()]);
      }
  
      private static SchemaDocument getSchemaDocumentForTNS(Map nsToSchemaDocs, String tns)
      {
          SchemaDocument schDoc = (SchemaDocument)nsToSchemaDocs.get(tns);
          if (schDoc==null)
          {
              schDoc = SchemaDocument.Factory.newInstance();
              nsToSchemaDocs.put(tns, schDoc);
          }
          return schDoc;
      }
  
      private static org.w3.x2001.xmlSchema.SchemaDocument.Schema getTopLevelSchemaElement(SchemaDocument schDoc, 
          String tns)
      {
          org.w3.x2001.xmlSchema.SchemaDocument.Schema sch = schDoc.getSchema();
          if (sch==null)
          {
              sch = schDoc.addNewSchema();
              sch.setAttributeFormDefault(org.w3.x2001.xmlSchema.FormChoice.Enum.forString("unqualified"));
              sch.setElementFormDefault(org.w3.x2001.xmlSchema.FormChoice.Enum.forString("qualified"));
              if (!tns.equals(""))
                  sch.setTargetNamespace(tns);
          }
          return sch;
      }
  
      // Global Elements
      private void fillUpGlobalElement(Element globalElement, SchemaDocument schDoc, String tns)
      {
          assert tns.equals(globalElement.getName().getNamespaceURI());
  
          org.w3.x2001.xmlSchema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  
          org.w3.x2001.xmlSchema.TopLevelElement topLevelElem = sch.addNewElement();
          topLevelElem.setName(globalElement.getName().getLocalPart());
  
          fillUpElementDocumentation(topLevelElem, globalElement.getComment());
  
          Type elemType = globalElement.getType();
          fillUpTypeOnElement(elemType, topLevelElem, tns);
      }
  
      private void fillUpLocalElement(Element element, org.w3.x2001.xmlSchema.LocalElement localSElement, String tns)
      {
          fillUpElementDocumentation(localSElement, element.getComment());
          if (!element.isRef())
          {
              assert element.getName().getNamespaceURI().equals(tns);
              fillUpTypeOnElement(element.getType(), localSElement, tns);
              localSElement.setName(element.getName().getLocalPart());
          }
          else
          {
              localSElement.setRef(element.getName());
          }
  
          if (element.getMaxOccurs()==Element.UNBOUNDED)
          {
              localSElement.setMaxOccurs("unbounded");
          }
          if (element.getMinOccurs()!=1)
          {
              localSElement.setMinOccurs(new BigInteger("" + element.getMinOccurs()));
          }
      }
  
      private void fillUpTypeOnElement(Type elemType, org.w3.x2001.xmlSchema.Element parentSElement, String tns)
      {
          if (elemType.isGlobal())
          {
              assert elemType.getName()!=null : "Global type must have a name.";
              parentSElement.setType(elemType.getName());
          }
          else if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT)
          {
              if (elemType.isEnumeration())
                  fillUpEnumeration(elemType, parentSElement);
              else
                  parentSElement.setType(elemType.getName());
          }
          else
          {
              org.w3.x2001.xmlSchema.LocalComplexType localComplexType = parentSElement.addNewComplexType();
              fillUpContentForComplexType(elemType, localComplexType, tns);
          }
      }
  
      private void fillUpEnumeration(Type type, org.w3.x2001.xmlSchema.Element parentSElement)
      {
          assert type.isEnumeration() && !type.isComplexType() : "Enumerations must be on simple types only.";
          org.w3.x2001.xmlSchema.RestrictionDocument.Restriction restriction = parentSElement.addNewSimpleType().addNewRestriction();
          restriction.setBase(type.getName());
          for (int i = 0; i < type.getEnumerationValues().size(); i++)
          {
              String value = (String) type.getEnumerationValues().get(i);
              restriction.addNewEnumeration().setValue(XmlString.Factory.newValue(value));
          }
      }
  
      private void fillUpAttributesInComplexTypesSimpleContent(Type elemType,
          org.w3.x2001.xmlSchema.SimpleExtensionType sExtension, String tns)
      {
          for (int i = 0; i < elemType.getAttributes().size(); i++)
          {
              Attribute att = (Attribute) elemType.getAttributes().get(i);
              org.w3.x2001.xmlSchema.Attribute sAttribute = sExtension.addNewAttribute();
              fillUpLocalAttribute(att, sAttribute, tns);
          }
      }
  
      private void fillUpAttributesInComplexTypesComplexContent(Type elemType,
          org.w3.x2001.xmlSchema.ComplexType localSComplexType, String tns)
      {
          for (int i = 0; i < elemType.getAttributes().size(); i++)
          {
              Attribute att = (Attribute) elemType.getAttributes().get(i);
              org.w3.x2001.xmlSchema.Attribute sAttribute = localSComplexType.addNewAttribute();
              fillUpLocalAttribute(att, sAttribute, tns);
          }
      }
  
      private void fillUpLocalAttribute(Attribute att, org.w3.x2001.xmlSchema.Attribute sAttribute, String tns)
      {
          if (att.isRef())
          {
              sAttribute.setRef(att.getName());
          }
          else
          {
              assert att.getName().getNamespaceURI()==tns || att.getName().getNamespaceURI().equals("");
              sAttribute.setType(att.getType().getName());
              sAttribute.setName(att.getName().getLocalPart());
              if (att.isOptional())
                  sAttribute.setUse(org.w3.x2001.xmlSchema.Attribute.Use.OPTIONAL);
          }
      }
  
      private void fillUpContentForComplexType(Type type, org.w3.x2001.xmlSchema.ComplexType sComplexType, String tns)
      {
          if (type.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT)
          {
              org.w3.x2001.xmlSchema.SimpleContentDocument.SimpleContent simpleContent = sComplexType.addNewSimpleContent();
  
              assert type.getExtensionType()!=null && type.getExtensionType().getName()!=null : "Extension type must exist and be named for a COMPLEX_TYPE_SIMPLE_CONTENT";
  
              org.w3.x2001.xmlSchema.SimpleExtensionType ext = simpleContent.addNewExtension();
              ext.setBase(type.getExtensionType().getName());
  
              fillUpAttributesInComplexTypesSimpleContent(type, ext, tns);
          }
          else
          {
              if (type.getContentType()==Type.COMPLEX_TYPE_MIXED_CONTENT)
              {
                  sComplexType.setMixed(true);
              }
  
              org.w3.x2001.xmlSchema.ExplicitGroup explicitGroup;
              if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_SEQUENCE)
              {
                  explicitGroup = sComplexType.addNewSequence();
              }
              else if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_CHOICE_UNBOUNDED)
              {
                  explicitGroup = sComplexType.addNewChoice();
                  explicitGroup.setMaxOccurs("unbounded");
                  explicitGroup.setMinOccurs(new BigInteger("0"));
              }
              else { throw new IllegalStateException("Unknown particle type in complex and mixed content"); }
  
              for (int i = 0; i < type.getElements().size(); i++)
              {
                  Element child = (Element) type.getElements().get(i);
                  org.w3.x2001.xmlSchema.LocalElement childLocalElement = explicitGroup.addNewElement();
                  fillUpLocalElement(child, childLocalElement, tns);
              }
  
              fillUpAttributesInComplexTypesComplexContent(type, sComplexType, tns);
          }
      }
  
      // Global Attributes
      private void fillUpGlobalAttribute(Attribute globalAttribute, SchemaDocument schDoc, String tns)
      {
          assert tns.equals(globalAttribute.getName().getNamespaceURI());
          org.w3.x2001.xmlSchema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  
          org.w3.x2001.xmlSchema.TopLevelAttribute topLevelAtt = sch.addNewAttribute();
          topLevelAtt.setName(globalAttribute.getName().getLocalPart());
  
          Type elemType = globalAttribute.getType();
  
          if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT)
          {
              topLevelAtt.setType(elemType.getName());
          }
          else
          {
              //org.w3.x2001.xmlSchema.LocalSimpleType localSimpleType = topLevelAtt.addNewSimpleType();
              throw new IllegalStateException();
          }
      }
  
      private static void fillUpElementDocumentation(org.w3.x2001.xmlSchema.Element element, String comment)
      {
          if (comment!=null && comment.length()>0)
          {
              org.w3.x2001.xmlSchema.DocumentationDocument.Documentation documentation = element.addNewAnnotation().addNewDocumentation();
              documentation.set(org.apache.xmlbeans.XmlString.Factory.newValue(comment));
          }
      }
  
      // Global Types
      private void fillUpGlobalType(Type globalType, SchemaDocument schDoc, String tns)
      {
          assert tns.equals(globalType.getName().getNamespaceURI());
          org.w3.x2001.xmlSchema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns);
  
          org.w3.x2001.xmlSchema.TopLevelComplexType topLevelComplexType = sch.addNewComplexType();
          topLevelComplexType.setName(globalType.getName().getLocalPart());
  
          fillUpContentForComplexType(globalType, topLevelComplexType, tns);
      }
  
      public String toString()
      {
          return "TypeSystemHolder{" +
              "_globalElements=" + _globalElements +
              "}";
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xmlbeans-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xmlbeans-cvs-help@xml.apache.org