<!-- 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. -->
<xs:schema
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config"
   targetNamespace="http://xml.apache.org/xmlbeans/2004/02/xbean/config"
   elementFormDefault="qualified">
  
  <xs:import namespace="http://www.w3.org/2001/XMLSchema"/> 

  <xs:element name="config">
    <xs:annotation>
      <xs:documentation>
         The config element is the top-level element for an .xsdconfig file.
         It contains configuration information that guides the xsd compiler
         when it generates Java classes. You can specify package names to
         be used for whole xml namespaces; you can specify class names
         to use for individual schema types; and you can supply extension
         interfaces and implementations to be extended by the generated
         Java classes.
      </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">

        <xs:element name="namespace" type="xb:nsconfig">
          <xs:annotation>
            <xs:documentation>
              Specifies configuration for a namespace.
            </xs:documentation>
          </xs:annotation>
        </xs:element>

        <xs:element name="qname" type="xb:qnameconfig">
          <xs:annotation>
            <xs:documentation>
              Specifies java mapping for a qname.
            </xs:documentation>
          </xs:annotation>
        </xs:element>

        <xs:element name="extension" type="xb:extensionconfig">
          <xs:annotation>
              <xs:documentation>
                  Specifies extensions for the generated types in the 'for' attribute.
              </xs:documentation>
          </xs:annotation>
        </xs:element>

        <xs:element name="usertype" type="xb:usertypeconfig">
          <xs:annotation>
              <xs:documentation>
                  Specifies a custom java type mapping for a derived simple type.
                  A static handler must be specified that converts between the
                  custom java type and the built-in simple type it derives from.
              </xs:documentation>
          </xs:annotation>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="nsconfig">

    <xs:sequence>

      <xs:element name="package" type="xs:string" minOccurs="0">
        <xs:annotation>
          <xs:documentation>
            The package name to be used for types generated in this
            namespace.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      
      <xs:element name="prefix" type="xs:string" minOccurs="0">
        <xs:annotation>
          <xs:documentation>
            A prefix to be used to prepend to top-level Java type names
            generated in this namespace.  (The prefix is not used for
            inner Java type definitions.)
          </xs:documentation>
        </xs:annotation>
      </xs:element>

      <xs:element name="suffix" type="xs:string" minOccurs="0">
        <xs:annotation>
          <xs:documentation>
            A suffix to be used to append to top-level Java type names
            generated in this namespace. (The suffix is not used for
            inner Java type definitions.)
          </xs:documentation>
        </xs:annotation>
      </xs:element>

    </xs:sequence>

    <xs:attribute name="uri" type="xb:namespaceList">
      <xs:annotation>
        <xs:documentation>
          A list of any number of namespace URIs or ##local for the no-namespace,
          or ##any for all namespaces.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

    <xs:attribute name="uriprefix" type="xb:namespacePrefixList">
      <xs:annotation>
        <xs:documentation>
          A list of any number of namespace URIs.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>

  </xs:complexType>

  <xs:complexType name="qnameconfig">
    <xs:sequence/>
    <xs:attribute name="name" type="xs:QName"/>
    <xs:attribute name="javaname" type="xs:string"/>
    <xs:attribute name="target" type="xb:qnametargetlist" default="type document-type accessor-element accessor-attribute">
        <xs:annotation>
            <xs:documentation>
              Specified on what type of Schema component does the qname mapping apply:
                - type - on global types with that QName and "local" types contained within attributes/elements
                  with the specified name
                - document-type - on "document" types generated from global elements/attributes with
                  the specified name
                - accessor-element - on getters/setters generated from elements with the specified name
                - accessor-attribute - on getters/setters generated from attributes with the specified name
            </xs:documentation>
        </xs:annotation>
    </xs:attribute>
  </xs:complexType>

  <xs:simpleType name="namespacePrefixList">
    <xs:annotation>
      <xs:documentation>
        A list of namespace URIs.
      </xs:documentation>
    </xs:annotation>
    <xs:list itemType="xs:anyURI" />
  </xs:simpleType>

  <xs:simpleType name="namespaceList">
    <xs:annotation>
     <xs:documentation>
     A list of namespace URIs, with ##local for no-uri; or ##any for all URIs.
     </xs:documentation>
    </xs:annotation>
    <xs:union>
     <xs:simpleType>
      <xs:restriction base="xs:token">
       <xs:enumeration value="##any"/>
      </xs:restriction>
     </xs:simpleType>
     <xs:simpleType>
      <xs:list>
       <xs:simpleType>
        <xs:union memberTypes="xs:anyURI">
         <xs:simpleType>
          <xs:restriction base="xs:token">
           <xs:enumeration value="##local"/>
          </xs:restriction>
         </xs:simpleType>
        </xs:union>
       </xs:simpleType>
      </xs:list>
     </xs:simpleType>
    </xs:union>
   </xs:simpleType>

    <xs:complexType name="usertypeconfig">
       <xs:sequence>
           <xs:choice>
               <xs:element name="staticHandler" type="xs:string">
                   <xs:annotation>
                       <xs:documentation>
                           The name of the handler class for this user type.
                           The handler must contain public static methods for
                           translating the user type to and from the derived simple type.
                           Example:
                           - qname example:uuid restricts xs:string
                           - javaname is java.util.UUID
                           - handler interface must have signatures:
                                public void encodeUuid(UUID obj, SimpleValue target)
                                public UUID decodeUuid(SimpleValue obj)
                       </xs:documentation>
                   </xs:annotation>
               </xs:element>
           </xs:choice>
       </xs:sequence>
       <xs:attribute name="name" type="xs:QName"/>
       <xs:attribute name="javaname" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="extensionconfig">
       <xs:sequence>
          <xs:element name="interface" minOccurs="0" maxOccurs="unbounded" >
              <xs:annotation>
                  <xs:documentation>
                      The extension interface (it has to be on the classpath).
                      All the generated types in this domain will implement this interface,
                      the calls will be redirected to the handler.
                  </xs:documentation>
              </xs:annotation>
               <xs:complexType>
                   <xs:choice>
                       <xs:element name="staticHandler" type="xs:string">
                           <xs:annotation>
                               <xs:documentation>
                                   The name of the handler class for this extension interface.
                                   The handler must contain public static methods for each method
                                   in the interface, and they have to have the following signature.
                                   Example:
                                   - method in the extension interface:
                                         public String foo(String s)
                                   - method in the handler:
                                         public static String foo(XmlObject xo, String s)
                               </xs:documentation>
                           </xs:annotation>
                        </xs:element>
                       <!--xs:element name="implementationClass" type="xs:string" /-->
                   </xs:choice>
                   <xs:attribute name="name" type="xs:string">
                       <xs:annotation>
                           <xs:documentation>
                               The extension interface name (it has to be on the classpath).
                           </xs:documentation>
                       </xs:annotation>
                   </xs:attribute>
               </xs:complexType>
           </xs:element>
           <xs:element name="prePostSet" minOccurs="0" maxOccurs="1" >
               <xs:annotation>
                   <xs:documentation>
                       preSet and postSet calls will get generated in the implementation classes. (Only for setter methods).
                   </xs:documentation>
               </xs:annotation>
               <xs:complexType>
                   <xs:sequence>
                       <xs:element name="staticHandler" type="xs:string">
                           <xs:annotation>
                               <xs:documentation>
                                   The name of the handler class for preSet and postSet methods.
                                   The handler must contain the following public static methods.
                                   public static boolean preSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index)
                                   {
                                       ...
                                       return true; // true to execute store implementation code, false to skip it
                                   }

                                   public static void postSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index)
                                   {...}
                               </xs:documentation>
                           </xs:annotation>
                        </xs:element>
                   </xs:sequence>
               </xs:complexType>
           </xs:element>
       </xs:sequence>
       <xs:attribute name="for" type="xb:javaNameList">
         <xs:annotation>
            <xs:documentation>
                '*' or a list of generated java types (interfaces) that reprezents this extension domain.
            </xs:documentation>
         </xs:annotation>
       </xs:attribute>
    </xs:complexType>

     <xs:simpleType name="javaNameList">
         <xs:annotation>
             <xs:documentation>
                 A list of generated java interface names or '*' for all interfaces.
             </xs:documentation>
         </xs:annotation>
         <xs:union>
             <xs:simpleType>
                 <xs:restriction base="xs:token">
                     <xs:enumeration value="*" />
                 </xs:restriction>
             </xs:simpleType>
             <xs:simpleType>
                 <xs:list itemType="xb:javaName" />
             </xs:simpleType>
         </xs:union>
     </xs:simpleType>

     <xs:simpleType name="javaName">
         <xs:restriction base="xs:token" />
     </xs:simpleType>

     <xs:simpleType name="qnametargetlist">
         <xs:list itemType="xb:qnametargetenum"/>
     </xs:simpleType>

     <xs:simpleType name="qnametargetenum">
         <xs:restriction base="xs:token">
             <xs:enumeration value="type"/>
             <xs:enumeration value="document-type"/>
             <xs:enumeration value="accessor-element"/>
             <xs:enumeration value="accessor-attribute"/>
         </xs:restriction>
     </xs:simpleType>
</xs:schema>
