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/04/27 02:19:24 UTC

cvs commit: xml-xmlbeans/v1/test/src/extensionsuse/drtcases ExtensionsTest.java

cezar       2004/04/26 17:19:24

  Modified:    v1       build.xml
               v1/external/lib oldxbean.jar
               v1/src/configschema/schema xmlconfig.xsd
               v1/src/typeimpl/org/apache/xmlbeans/impl/schema
                        SchemaTypeCodePrinter.java SchemaTypeImpl.java
                        StscJavaizer.java StscState.java
               v1/src/xmlconfig/org/apache/xmlbeans/impl/config
                        SchemaConfig.java
               v1/test/src/drt/drtcases SubstGroupTests.java
  Added:       v1/src/xmlconfig/org/apache/xmlbeans/impl/config
                        ExtensionHolder.java InterfaceExtension.java
                        NameSet.java NameSetBuilder.java
                        PrePostExtension.java
               v1/test/src/extensions company.xsd company.xsdconfig
               v1/test/src/extensions/myPackage Bar.java BarHandler.java
                        Foo.java FooHandler.java
               v1/test/src/extensionsuse/drtcases ExtensionsTest.java
  Log:
  Interface and pre-post extensions.
  
  CR: Kevin
  DRT: passes
  
  Revision  Changes    Path
  1.25      +48 -1     xml-xmlbeans/v1/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/build.xml,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- build.xml	14 Apr 2004 01:15:34 -0000	1.24
  +++ build.xml	27 Apr 2004 00:19:21 -0000	1.25
  @@ -65,7 +65,7 @@
   
       <mkdir dir="build/test/output"/>
       <echo message="Running xbean product drt tests"/>
  -    <echo message="JUnit output being sent to xbean/build/test/output/drt-product.txt"/>
  +    <echo message="JUnit output being sent to build/test/output/drt-product.txt"/>
       <junit fork="yes" printsummary="yes" haltonfailure="yes" showoutput="yes">
         <jvmarg value="-ea"/>
         <sysproperty key="xbean.rootdir" value="${basedir}"/>
  @@ -85,7 +85,54 @@
         <formatter type="plain"/>
         <test name="drtcases.SmokeTests" outfile="build/test/output/drt-product" />
       </junit>
  +
  +      <antcall target="extensionsTest" />
     </target>
  +
  +    <!-- extensions test -->
  +    <target name="extensionsTest" depends="extensions.compile">
  +        <echo message="JUnit output being sent to build/test/output/drt-product.txt"/>
  +        <junit fork="yes" printsummary="yes" haltonfailure="yes" showoutput="yes">
  +            <jvmarg value="-ea"/>
  +            <classpath>
  +                <pathelement location="external/lib/junit.jar"/>
  +                <pathelement location="build/ar/xbean.jar"/>
  +                <pathelement location="build/private/lib/extensions.jar"/>
  +                <pathelement location="build/test/extensionsuse"/>
  +            </classpath>
  +            <formatter type="plain"/>
  +            <test name="drtcases.ExtensionsTest" outfile="build/test/output/drt-extensions"/>
  +        </junit>
  +    </target>
  +
  +    <target name="extensions.compile" >
  +        <mkdir dir="build/test/extensions"/>
  +        <javac srcdir="test/src/extensions" destdir="build/test/extensions" debug="on">
  +            <classpath>
  +                <pathelement location="build/ar/xbean.jar"/>
  +            </classpath>
  +        </javac>
  +
  +        <java classname="${schema_compiler}" fork="true" failonerror="true">
  +            <jvmarg value="-ea"/>
  +            <classpath>
  +                <pathelement location="build/ar/xbean.jar" />
  +                <pathelement location="build/test/extensions" />
  +            </classpath>
  +            <arg line="-out build/private/lib/extensions.jar test/src/extensions"/>
  +        </java>
  +
  +        <mkdir dir="build/test/extensionsuse"/>
  +        <javac srcdir="test/src/extensionsuse" destdir="build/test/extensionsuse" debug="on">
  +            <classpath>
  +                <pathelement location="build/ar/xbean.jar"/>
  +                <pathelement location="external/lib/junit.jar"/>
  +                <pathelement location="build/private/lib/extensions.jar"/>
  +                <pathelement location="build/test/extensionsuse"/>
  +            </classpath>
  +        </javac>
  +    </target>
  +    <!-- extensions test -->
   
     <target name="builddrt" depends="drt.jar, random.jar, eric"/>
   
  
  
  
  1.9       +7926 -4592xml-xmlbeans/v1/external/lib/oldxbean.jar
  
  	<<Binary file>>
  
  
  1.4       +109 -5    xml-xmlbeans/v1/src/configschema/schema/xmlconfig.xsd
  
  Index: xmlconfig.xsd
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/configschema/schema/xmlconfig.xsd,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- xmlconfig.xsd	26 Feb 2004 00:59:55 -0000	1.3
  +++ xmlconfig.xsd	27 Apr 2004 00:19:23 -0000	1.4
  @@ -16,8 +16,8 @@
      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:import namespace="http://www.w3.org/2001/XMLSchema"/>
   
     <xs:element name="config">
       <xs:annotation>
  @@ -50,6 +50,14 @@
             </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:choice>
       </xs:complexType>
     </xs:element>
  @@ -66,7 +74,7 @@
             </xs:documentation>
           </xs:annotation>
         </xs:element>
  -      
  +
         <xs:element name="prefix" type="xs:string" minOccurs="0">
           <xs:annotation>
             <xs:documentation>
  @@ -89,7 +97,7 @@
   
       </xs:sequence>
   
  -    <xs:attribute name="uri" type="xs:namespaceList">
  +    <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,
  @@ -133,5 +141,101 @@
        </xs:simpleType>
       </xs:union>
      </xs:simpleType>
  -  
  +
  +   <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:schema>
  
  
  
  1.8       +163 -6    xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
  
  Index: SchemaTypeCodePrinter.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- SchemaTypeCodePrinter.java	12 Feb 2004 20:05:55 -0000	1.7
  +++ SchemaTypeCodePrinter.java	27 Apr 2004 00:19:23 -0000	1.8
  @@ -19,9 +19,14 @@
   import java.io.IOException;
   import java.util.Map;
   import java.util.HashMap;
  +import java.util.List;
  +import java.util.Iterator;
   
   import javax.xml.namespace.QName;
   import org.apache.xmlbeans.impl.common.NameUtil;
  +import org.apache.xmlbeans.impl.config.InterfaceExtension;
  +import org.apache.xmlbeans.impl.config.ExtensionHolder;
  +import org.apache.xmlbeans.impl.config.PrePostExtension;
   import org.apache.xmlbeans.SchemaType;
   import org.apache.xmlbeans.SchemaTypeSystem;
   import org.apache.xmlbeans.SchemaProperty;
  @@ -528,12 +533,41 @@
           }
           */
   
  -        emit("public interface " + shortName + " extends " + baseInterface);
  +        emit("public interface " + shortName + " extends " + baseInterface + getExtensionInterfaces(sType) );
           emit("{");
           indent();
           emitSpecializedAccessors(sType);
       }
   
  +    private static String getExtensionInterfaces(SchemaType sType)
  +    {
  +        SchemaTypeImpl sImpl = getImpl(sType);
  +        if (sImpl==null)
  +            return "";
  +
  +        StringBuffer sb = new StringBuffer();
  +
  +        ExtensionHolder extHolder = sImpl.getExtensionHolder();
  +        if (extHolder!=null)
  +        {
  +            List exts = extHolder.getInterfaceExtensionsFor(sType.getFullJavaName());
  +            for (Iterator i = exts.iterator(); i.hasNext(); )
  +            {
  +                InterfaceExtension ext = (InterfaceExtension)i.next();
  +                sb.append(", " + ext.getInterfaceNameForJavaSource() );
  +            }
  +        }
  +        return sb.toString();
  +    }
  +
  +    private static SchemaTypeImpl getImpl(SchemaType sType)
  +    {
  +        if (sType instanceof SchemaTypeImpl)
  +            return (SchemaTypeImpl)sType;
  +        else
  +            return null;
  +    }
  +
       private void emitSpecializedAccessors(SchemaType sType) throws IOException
       {
           if (sType.getSimpleVariety() == SchemaType.ATOMIC &&
  @@ -1532,17 +1566,76 @@
           emit("}");
       }
       
  +    void emitDeclareTarget(boolean declareTarget, String xtype)
  +            throws IOException
  +    {
  +        if (declareTarget)
  +            emit(xtype + " target = null;");
  +    }
  +
       void emitAddTarget(String identifier, boolean isAttr, boolean declareTarget, String xtype)
           throws IOException
       {
  -        if (declareTarget)
  -            emit(xtype + " target;");
           if (isAttr)
               emit("target = (" + xtype + ")get_store().add_attribute_user(" + identifier + ");");
           else
               emit("target = (" + xtype + ")get_store().add_element_user(" + identifier + ");");
       }
   
  +    void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException
  +    {
  +        emitPre(sType, opType, identifier, isAttr, "-1");
  +    }
  +
  +    void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException
  +    {
  +        SchemaTypeImpl sImpl = getImpl(sType);
  +        if (sImpl==null)
  +            return;
  +
  +        ExtensionHolder extHolder = sImpl.getExtensionHolder();
  +        if (extHolder==null)
  +            return;
  +
  +        PrePostExtension ext = extHolder.getPrePostExtensionsFor(sType.getFullJavaName());
  +        if (ext!=null)
  +        {
  +            if (ext.hasPreCall())
  +            {
  +                emit("if ( " + ext.getPreCall(opType, identifier, isAttr, index) + " )");
  +                startBlock();
  +            }
  +        }
  +    }
  +
  +    void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException
  +    {
  +        emitPost(sType, opType, identifier, isAttr, "-1");
  +    }
  +    
  +    void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException
  +    {
  +        SchemaTypeImpl sImpl = getImpl(sType);
  +        if (sImpl==null)
  +            return;
  +
  +        ExtensionHolder extHolder = sImpl.getExtensionHolder();
  +        if (extHolder==null)
  +            return;
  +
  +        PrePostExtension ext = extHolder.getPrePostExtensionsFor(sType.getFullJavaName());
  +        if (ext!=null)
  +        {
  +            if (ext.hasPreCall())
  +            {
  +                endBlock();
  +            }
  +
  +            if (ext.hasPostCall())
  +                emit(ext.getPostCall(opType, identifier, isAttr, index));
  +        }
  +    }
  +
       private static final int NOTHING = 1;
       private static final int ADD_NEW_VALUE = 3;
       private static final int THROW_EXCEPTION = 4;
  @@ -1574,6 +1667,7 @@
           switch (nullBehaviour)
           {
               case ADD_NEW_VALUE:
  +                // target already emited, no need for emitDeclareTarget(false, xtype);
                   emitAddTarget(identifier, isAttr, false, xtype);
                   break;
   
  @@ -1776,7 +1870,8 @@
                          boolean nillable, boolean optional,
                          boolean several, boolean singleton,
                          boolean isunion,
  -                       String identifier, String setIdentifier) throws IOException
  +                       String identifier, String setIdentifier, SchemaType sType )
  +            throws IOException
       {
           String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName));
           if (safeVarName.equals("i"))
  @@ -1799,8 +1894,10 @@
               emit("public void set" + propertyName + "(" + type + " " + safeVarName + ")");
               startBlock();
               emitImplementationPreamble();
  +            emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
               emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType);
               emit(jSet + "(" + safeVarName + ");");
  +            emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
               emitImplementationPostamble();
               endBlock();
   
  @@ -1811,8 +1908,10 @@
                   emit("public void xset" + propertyName + "(" + xtype + " " + safeVarName + ")");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                   emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
                   emit("target.set(" + safeVarName + ");");
  +                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                   emitImplementationPostamble();
                   endBlock();
   
  @@ -1825,7 +1924,10 @@
                   emit("public " + xtype + " addNew" + propertyName + "()");
                   startBlock();
                   emitImplementationPreamble();
  +                emitDeclareTarget(true, xtype);
  +                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emitAddTarget(identifier, isAttr, true, xtype);
  +                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emit("return target;");
                   emitImplementationPostamble();
                   endBlock();
  @@ -1837,8 +1939,10 @@
                   emit("public void setNil" + propertyName + "()");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                   emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
                   emit("target.setNil();");
  +                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1");
                   emitImplementationPostamble();
                   endBlock();
               }
  @@ -1850,10 +1954,12 @@
               emit("public void unset" + propertyName + "()");
               startBlock();
               emitImplementationPreamble();
  +            emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1");
               if (isAttr)
                   emit("get_store().remove_attribute(" + identifier + ");");
               else
                   emit("get_store().remove_element(" + setIdentifier + ", 0);");
  +            emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1");
               emitImplementationPostamble();
               endBlock();
           }
  @@ -1867,6 +1973,7 @@
               emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array)");
               startBlock();
               emitImplementationPreamble();
  +            emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
   
               if (isobj)
               {
  @@ -1882,6 +1989,7 @@
                   else
                       emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" );
               }
  +            emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
               emitImplementationPostamble();
               endBlock();
   
  @@ -1889,8 +1997,10 @@
               emit("public void set" + arrayName + "(int i, " + type + " " + safeVarName + ")");
               startBlock();
               emitImplementationPreamble();
  +            emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
               emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
               emit(jSet + "(" + safeVarName + ");");
  +            emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
               emitImplementationPostamble();
               endBlock();
   
  @@ -1900,8 +2010,10 @@
                   emit("public void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array)");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                   emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" );
   
  +                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr);
                   emitImplementationPostamble();
                   endBlock();
   
  @@ -1909,8 +2021,10 @@
                   emit("public void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ")");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                   emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                   emit("target.set(" + safeVarName + ");");
  +                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                   emitImplementationPostamble();
                   endBlock();
               }
  @@ -1921,8 +2035,10 @@
                   emit("public void setNil" + arrayName + "(int i)");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                   emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
                   emit("target.setNil();");
  +                emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i");
                   emitImplementationPostamble();
                   endBlock();
               }
  @@ -1933,6 +2049,7 @@
                   emit("public void insert" + propertyName + "(int i, " + type + " " + safeVarName + ")");
                   startBlock();
                   emitImplementationPreamble();
  +                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                   emit(jtargetType + " target = ");
                   indent();
                   if (!isSubstGroup)
  @@ -1942,6 +2059,7 @@
                               identifier + ", i);");
                   outdent();
                   emit(jSet + "(" + safeVarName + ");");
  +                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                   emitImplementationPostamble();
                   endBlock();
   
  @@ -1949,8 +2067,11 @@
                   emit("public void add" + propertyName + "(" + type + " " + safeVarName + ")");
                   startBlock();
                   emitImplementationPreamble();
  +                emitDeclareTarget(true, jtargetType);
  +                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emitAddTarget(identifier, isAttr, true, jtargetType);
                   emit(jSet + "(" + safeVarName + ");");
  +                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emitImplementationPostamble();
                   endBlock();
               }
  @@ -1961,8 +2082,10 @@
                   emit("public " + xtype + " insertNew" + propertyName + "(int i)");
                   startBlock();
                   emitImplementationPreamble();
  -                emit(xtype + " target;");
  +                emitDeclareTarget(true, xtype);
  +                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                   emit("target = (" + xtype + ")get_store().insert_element_user(" + identifier + ", i);");
  +                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i");
                   emit("return target;");
                   emitImplementationPostamble();
                   endBlock();
  @@ -1971,7 +2094,10 @@
                   emit("public " + xtype + " addNew" + propertyName + "()");
                   startBlock();
                   emitImplementationPreamble();
  +                emitDeclareTarget(true, xtype);
  +                emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emitAddTarget(identifier, isAttr, true, xtype);
  +                emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr);
                   emit("return target;");
                   emitImplementationPostamble();
                   endBlock();
  @@ -1981,7 +2107,9 @@
               emit("public void remove" + propertyName + "(int i)");
               startBlock();
               emitImplementationPreamble();
  +            emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i");
               emit("get_store().remove_element(" + setIdentifier + ", i);");
  +            emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i");
               emitImplementationPostamble();
               endBlock();
           }
  @@ -2012,6 +2140,8 @@
   
           printConstructor(sType, shortName);
   
  +        printExtensionImplMethods(sType);
  +
           if (!sType.isSimpleType())
           {
               SchemaProperty[] properties;
  @@ -2074,7 +2204,8 @@
                           prop.extendsJavaSingleton(),
                           xmlTypeForPropertyIsUnion(prop),
                           getIdentifier(qNameMap, name),
  -                        getSetIdentifier(qNameMap, name)
  +                        getSetIdentifier(qNameMap, name),
  +                        sType
                       );
                   }
               }
  @@ -2084,6 +2215,32 @@
   
           endBlock();
       }
  +
  +    private void printExtensionImplMethods(SchemaType sType) throws IOException
  +    {
  +        SchemaTypeImpl sImpl = getImpl(sType);
  +        if (sImpl==null)
  +            return;
  +
  +        ExtensionHolder extHolder = sImpl.getExtensionHolder();
  +        if (extHolder==null)
  +            return;
  +
  +        List exts = extHolder.getInterfaceExtensionsFor(sType.getFullJavaName());
  +        for (Iterator i = exts.iterator(); i.hasNext(); )
  +        {
  +            InterfaceExtension ext = (InterfaceExtension)i.next();
  +            for( int j = 0; j<ext.getInterfaceMethodCount(); j++)
  +            {
  +                printJavaDoc("Implementation method for interface " + ext.getInterfaceNameForJavaSource() );
  +                emit(ext.getInterfaceMethodDecl(j));
  +                startBlock();
  +                emit(ext.getInterfaceMethodImpl(j));
  +                endBlock();
  +            }
  +        }
  +    }
  +
       void printNestedTypeImpls(SchemaType sType, SchemaTypeSystem system) throws IOException
       {
           SchemaType[] anonTypes = sType.getAnonymousTypes();
  
  
  
  1.9       +13 -0     xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
  
  Index: SchemaTypeImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- SchemaTypeImpl.java	14 Apr 2004 22:27:50 -0000	1.8
  +++ SchemaTypeImpl.java	27 Apr 2004 00:19:23 -0000	1.9
  @@ -18,6 +18,7 @@
   import org.apache.xmlbeans.impl.values.*;
   import org.apache.xmlbeans.impl.regex.RegularExpression;
   import org.apache.xmlbeans.impl.common.QNameHelper;
  +import org.apache.xmlbeans.impl.config.ExtensionHolder;
   import org.apache.xmlbeans.XmlObject;
   import org.apache.xmlbeans.SchemaGlobalElement;
   import org.apache.xmlbeans.SchemaComponent;
  @@ -75,6 +76,7 @@
       private String _fullJavaName;
       private String _shortJavaImplName;
       private String _fullJavaImplName;
  +    private ExtensionHolder _extensionHolder;
   
       // runtime java type support: volatile because they're cached
       private volatile Class _javaClass;
  @@ -533,6 +535,17 @@
           int index = Math.max(_fullJavaImplName.lastIndexOf('$'),
                                _fullJavaImplName.lastIndexOf('.')) + 1;
           _shortJavaImplName = _fullJavaImplName.substring(index);
  +    }
  +
  +    public void setExtensionHolder(ExtensionHolder extHolder)
  +    {
  +        assertResolved();
  +        _extensionHolder = extHolder;
  +    }
  +
  +    public ExtensionHolder getExtensionHolder()
  +    {
  +        return _extensionHolder;
       }
   
       public String getFullJavaImplName() { return _fullJavaImplName;}
  
  
  
  1.6       +67 -10    xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java
  
  Index: StscJavaizer.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- StscJavaizer.java	8 Apr 2004 19:22:03 -0000	1.5
  +++ StscJavaizer.java	27 Apr 2004 00:19:23 -0000	1.6
  @@ -15,20 +15,29 @@
   
   package org.apache.xmlbeans.impl.schema;
   
  -import org.apache.xmlbeans.impl.common.NameUtil;
  +import org.apache.xmlbeans.QNameSet;
   import org.apache.xmlbeans.QNameSetBuilder;
   import org.apache.xmlbeans.SchemaField;
  -import org.apache.xmlbeans.SchemaType;
   import org.apache.xmlbeans.SchemaParticle;
   import org.apache.xmlbeans.SchemaProperty;
  -import org.apache.xmlbeans.QNameSet;
  -import org.apache.xmlbeans.XmlAnySimpleType;
   import org.apache.xmlbeans.SchemaStringEnumEntry;
  -
  -import java.util.*;
  -import java.math.BigInteger;
  +import org.apache.xmlbeans.SchemaType;
  +import org.apache.xmlbeans.XmlAnySimpleType;
  +import org.apache.xmlbeans.impl.common.NameUtil;
  +import org.apache.xmlbeans.impl.config.InterfaceExtension;
  +import org.apache.xmlbeans.impl.config.ExtensionHolder;
   
   import javax.xml.namespace.QName;
  +import java.math.BigInteger;
  +import java.util.ArrayList;
  +import java.util.Arrays;
  +import java.util.Collection;
  +import java.util.HashMap;
  +import java.util.HashSet;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.Map;
  +import java.util.Set;
   
   public class StscJavaizer
   {
  @@ -79,8 +88,26 @@
               {
                   sImpl.setFullJavaName(pickFullJavaClassName(usedNames, findTopName(sImpl), pickedName, sImpl.isDocumentType(), sImpl.isAttributeType()));
                   sImpl.setFullJavaImplName(pickFullJavaImplName(usedNames, sImpl.getFullJavaName()));
  +                setExtensions(sImpl, state);
               }
           }
  +
  +        verifyInterfaceNameCollisions(usedNames, state);
  +    }
  +
  +    private static void verifyInterfaceNameCollisions(Set usedNames, StscState state)
  +    {
  +        state.getExtensionHolder().verifyInterfaceNameCollisions(usedNames);
  +    }
  +
  +    private static void setExtensions(SchemaTypeImpl sImpl, StscState state)
  +    {
  +        String javaName = sImpl.getFullJavaName();
  +
  +        if (javaName!=null)
  +        {
  +            sImpl.setExtensionHolder(state.getExtensionHolder(javaName));
  +        }
       }
   
       private static boolean isStringType(SchemaType type)
  @@ -121,11 +148,11 @@
       {
           if (sImpl.isJavaized())
               return;
  -        
  +
           SchemaTypeImpl baseType = (SchemaTypeImpl)sImpl.getBaseType();
           if (baseType != null)
               skipJavaizingType(baseType);
  -        
  +
           sImpl.startJavaizing();
           secondPassProcessType(sImpl);
           sImpl.finishJavaizing();
  @@ -193,6 +220,9 @@
               // Handing out java names - this permits us to avoid collisions.
               Set usedPropNames = new HashSet();
   
  +            // count in the methods from extension interfaces
  +            avoidExtensionMethods(usedPropNames, sImpl);
  +
               // Assign names in two passes: first inherited names, then others.
               for (boolean doInherited = true; ; doInherited = false)
               {
  @@ -223,6 +253,33 @@
           sImpl.finishJavaizing();
       }
   
  +    private static final String[] PREFIXES = new String[]
  +    {"get", "xget", "isNil", "isSet", "sizeOf", "set", "xset", "addNew", "setNil", "unset", "insert", "add", "insertNew", "addNew", "remove"};
  +
  +    private static void avoidExtensionMethods(Set usedPropNames, SchemaTypeImpl sImpl)
  +    {
  +        ExtensionHolder extHolder = sImpl.getExtensionHolder();
  +        if (extHolder!=null)
  +        {
  +            List exts = extHolder.getInterfaceExtensionsFor(sImpl.getFullJavaName());
  +            for (int i = 0; i < exts.size(); i++)
  +            {
  +                InterfaceExtension ext = (InterfaceExtension) exts.get(i);
  +                int methodCount = ext.getInterfaceMethodCount();
  +                for (int j=0; j<methodCount; j++)
  +                {
  +                    String methodName = ext.getInterfaceMethodName(j);
  +                    for (int k = 0; k < PREFIXES.length; k++)
  +                    {
  +                        String prefix = PREFIXES[k];
  +                        if (methodName.startsWith(prefix))
  +                            usedPropNames.add(methodName.substring(prefix.length()));
  +                    }
  +                }
  +            }
  +        }
  +    }
  +
       static void assignJavaAnonymousTypeNames(SchemaTypeImpl outerType)
       {
           Set usedTypeNames = new HashSet();
  @@ -289,6 +346,7 @@
                       pickInnerJavaClassName(usedTypeNames, localname, javaname));
               sImpl.setShortJavaImplName(
                       pickInnerJavaImplName(usedTypeNames, localname, javaname == null ? null : javaname + "Impl"));
  +            setExtensions(sImpl, state);
           }
       }
   
  @@ -870,5 +928,4 @@
           assert(sType.getOuterType() == null);
           return sElt.getName();
       }
  -
   }
  
  
  
  1.5       +17 -0     xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java
  
  Index: StscState.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StscState.java	12 Feb 2004 20:05:55 -0000	1.4
  +++ StscState.java	27 Apr 2004 00:19:23 -0000	1.5
  @@ -18,6 +18,7 @@
   import org.apache.xmlbeans.impl.common.XmlErrorContext;
   import org.apache.xmlbeans.impl.common.QNameHelper;
   import org.apache.xmlbeans.impl.config.SchemaConfig;
  +import org.apache.xmlbeans.impl.config.ExtensionHolder;
   import org.apache.xmlbeans.XmlObject;
   import org.apache.xmlbeans.SchemaGlobalElement;
   import org.apache.xmlbeans.SchemaComponent;
  @@ -361,6 +362,22 @@
       public String getJavaname(QName qname)
       {
           return _config.lookupJavanameForQName(qname);
  +    }
  +
  +    /**
  +     * Gets configured extension set, null if javaName is not contained in any extension.
  +     */
  +    public ExtensionHolder getExtensionHolder(String javaName)
  +    {
  +        return _config.extensionHolderFor(javaName);
  +    }
  +
  +    /**
  +     * Gets configured extension set.
  +     */
  +    public ExtensionHolder getExtensionHolder()
  +    {
  +        return _config.getExtensionHolder();
       }
   
       /* SPELLINGS ======================================================*/
  
  
  
  1.5       +79 -9     xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/SchemaConfig.java
  
  Index: SchemaConfig.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/SchemaConfig.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SchemaConfig.java	12 Feb 2004 20:06:01 -0000	1.4
  +++ SchemaConfig.java	27 Apr 2004 00:19:23 -0000	1.5
  @@ -15,18 +15,20 @@
   
   package org.apache.xmlbeans.impl.config;
   
  -import javax.xml.namespace.QName;
  +import org.apache.xml.xmlbeans.x2004.x02.xbean.config.ConfigDocument.Config;
  +import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Extensionconfig;
  +import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Nsconfig;
  +import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Qnameconfig;
  +import org.apache.xmlbeans.XmlObject;
  +import org.apache.xmlbeans.XmlError;
  +import org.apache.xmlbeans.impl.schema.StscState;
   
  -import java.util.Map;
  -import java.util.HashMap;
  +import javax.xml.namespace.QName;
   import java.util.Collections;
  +import java.util.Iterator;
   import java.util.LinkedHashMap;
   import java.util.List;
  -import java.util.Iterator;
  -
  -import org.apache.xml.xmlbeans.x2004.x02.xbean.config.ConfigDocument.Config;
  -import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Nsconfig;
  -import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Qnameconfig;
  +import java.util.Map;
   
   public class SchemaConfig
   {
  @@ -34,6 +36,7 @@
       private Map _prefixMap;
       private Map _suffixMap;
       private Map _qnameMap;
  +    private ExtensionHolder _extensionHolder;
   
       private SchemaConfig()
       {
  @@ -41,6 +44,7 @@
           _prefixMap = Collections.EMPTY_MAP;
           _suffixMap = Collections.EMPTY_MAP;
           _qnameMap = Collections.EMPTY_MAP;
  +        _extensionHolder = null;
       }
       
       public static SchemaConfig forConfigDocuments(Config[] configs)
  @@ -54,6 +58,8 @@
           _prefixMap = new LinkedHashMap();
           _suffixMap = new LinkedHashMap();
           _qnameMap = new LinkedHashMap();
  +        _extensionHolder = new ExtensionHolder();
  +
           for (int i = 0; i < configs.length; i++)
           {
               Config config = configs[i];
  @@ -70,7 +76,16 @@
               {
                   _qnameMap.put(qnc[j].getName(), qnc[j].getJavaname());
               }
  +
  +            Extensionconfig[] ext = config.getExtensionArray();
  +            for (int j = 0; j < ext.length; j++)
  +            {
  +                recordExtensionSetting(ext[j]);
  +            }
           }
  +
  +        _extensionHolder.secondPhaseValidation();
  +        //todo _extensionHolder.normalize();
       }
   
       private static void recordNamespaceSetting(Object key, String value, Map result)
  @@ -92,7 +107,40 @@
               }
           }
       }
  -    
  +
  +    private void recordExtensionSetting(Extensionconfig ext)
  +    {
  +        NameSet xbeanSet = null;
  +        Object key = ext.getFor();
  +
  +
  +        if (key instanceof String && "*".equals(key))
  +            xbeanSet = NameSet.EVERYTHING;
  +        else if (key instanceof List)
  +        {
  +            NameSetBuilder xbeanSetBuilder = new NameSetBuilder();
  +            for (Iterator i = ((List)key).iterator(); i.hasNext(); )
  +            {
  +                String xbeanName = (String)i.next();
  +                xbeanSetBuilder.add(xbeanName);
  +            }
  +            xbeanSet = xbeanSetBuilder.toNameSet();
  +        }
  +
  +        if (xbeanSet==null)
  +            error("Invalid value of attribute 'for' : '" + key + "'.", ext);
  +
  +        Extensionconfig.Interface[] intfXO = ext.getInterfaceArray();
  +
  +        for (int i = 0; i < intfXO.length; i++)
  +        {
  +            _extensionHolder.addInterfaceExtension(InterfaceExtension.newInstance(xbeanSet, intfXO[i]));
  +        }
  +
  +        _extensionHolder.addPrePostExtension(PrePostExtension.newInstance(xbeanSet, ext.getPrePostSet()));
  +    }
  +
  +
       private String lookup(Map map, String uri)
       {
           if (uri == null)
  @@ -103,6 +151,18 @@
           return (String)map.get("##any");
       }
   
  +    //package methods
  +    static void warning(String s, XmlObject xo)
  +    {
  +        StscState.get().error(s, XmlError.SEVERITY_WARNING, xo);
  +    }
  +
  +    static void error(String s, XmlObject xo)
  +    {
  +        StscState.get().error(s, XmlError.SEVERITY_ERROR, xo);
  +    }
  +
  +    //public methods
       public String lookupPackageForNamespace(String uri)
       {
           return lookup(_packageMap, uri);
  @@ -121,5 +181,15 @@
       public String lookupJavanameForQName(QName qname)
       {
           return (String)_qnameMap.get(qname);
  +    }
  +
  +    public ExtensionHolder extensionHolderFor(String fullJavaName)
  +    {
  +        return _extensionHolder.extensionHolderFor(fullJavaName);
  +    }
  +
  +    public ExtensionHolder getExtensionHolder()
  +    {
  +        return _extensionHolder;
       }
   }
  
  
  
  1.1                  xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/ExtensionHolder.java
  
  Index: ExtensionHolder.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.
   */
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  package org.apache.xmlbeans.impl.config;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Set;
  import java.lang.reflect.Method;
  
  /**
   * This class reprezents all the extensions for all xbean sets.
   * This class is the root of the structure that reprezents all the extensions.
   */
  public class ExtensionHolder
  {
      // these lists are expected to be quite small
      private List _interfaceExtensions;
      private List _prePostExtensions;
  
      ExtensionHolder()
      {
          _interfaceExtensions = new ArrayList();
          _prePostExtensions = new ArrayList();
      }
  
      void addInterfaceExtension(InterfaceExtension ext)
      {
          if (ext==null)
              return;
  
          _interfaceExtensions.add(ext);
      }
  
      void addPrePostExtension(PrePostExtension ext)
      {
          if (ext==null)
              return;
  
          _prePostExtensions.add(ext);
      }
  
      // this is used only for detecting method colisions of extending interfaces
      private static class MethodSignature
      {
          private String _intfName;  // Stored only for error output, does not influence the equals or hashCode
          private Method _method;
  
          MethodSignature(String intfName, Method method)
          {
              if (intfName==null || method==null)
                  throw new IllegalArgumentException("Interface: " + intfName + " method: " + method);
  
              _intfName = intfName;
              _method = method;
          }
  
          String getInterfaceName()
          {
              return _intfName;
          }
  
          String getSignature()
          {
              String sig = "";
              Class[] paramTypes = _method.getParameterTypes();
              for (int i = 0; i < paramTypes.length; i++)
              {
                  Class paramType = paramTypes[i];
                  sig += ( i==0 ? "" : " ," ) + paramType.getName();
              }
              return _method.getName() + "(" + sig + ")";
          }
  
          public boolean equals(Object o)
          {
              if ( !(o instanceof MethodSignature))
                  return false;
  
              MethodSignature ms = (MethodSignature)o;
  
              if (!ms._method.getName().equals(_method.getName()) )
                  return false;
  
              Class[] paramTypes = _method.getParameterTypes();
              Class[] msParamTypes = _method.getParameterTypes();
  
              if (msParamTypes.length != paramTypes.length )
                  return false;
  
              for (int i = 0; i < paramTypes.length; i++)
              {
                  if (msParamTypes[i] != paramTypes[i])
                      return false;
              }
  
              return true;
          }
  
          public int hashCode()
          {
              int hash = _method.getName().hashCode();
  
              Class[] paramTypes = _method.getParameterTypes();
  
              for (int i = 0; i < paramTypes.length; i++)
              {
                  hash *= 19;
                  hash += paramTypes[i].hashCode();
              }
  
              return hash;
          }
      }
  
      void secondPhaseValidation()
      {
          // validate interface methods collisions
          Map methodSignatures = new HashMap();
  
          for (int i = 0; i < _interfaceExtensions.size(); i++)
          {
              InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
              for (int j = 0; j < interfaceExtension.getInterfaceMethodCount(); j++)
              {
                  MethodSignature ms = new MethodSignature(interfaceExtension.getInterfaceName(),
                       interfaceExtension.getInterfaceMethod(j));
  
                  if ( methodSignatures.containsKey(ms) )
                  {
                      MethodSignature ms2 = (MethodSignature) methodSignatures.get(ms);
                      SchemaConfig.error("Colliding methods '" + ms.getSignature() + "' in interfaces " +
                          ms.getInterfaceName() + " and " + ms2.getInterfaceName() + ".", null);
  
                      return;
                  }
  
                  // store it into hashmap
                  methodSignatures.put(ms, ms);
              }
          }
  
          // validate that PrePostExtension-s do not intersect
          for (int i = 0; i < _prePostExtensions.size() - 1; i++)
          {
              PrePostExtension a = (PrePostExtension) _prePostExtensions.get(i);
              for (int j = 1; j < _prePostExtensions.size(); j++)
              {
                  PrePostExtension b = (PrePostExtension) _prePostExtensions.get(j);
                  if (a.hasNameSetIntersection(b))
                      SchemaConfig.error("The applicable domain for handler '" + a.getHandlerNameForJavaSource() +
                          "' intersects with the one for '" + b.getHandlerNameForJavaSource() + "'.", null);
              }
          }
      }
  
      void normalize()
      {
          //todo: not yet used, useful for optimizing jar size in case of big interfaces and big schemas
          throw new RuntimeException("NYI");
          // this matters only for InterfaceExtension-s
      }
  
      public void verifyInterfaceNameCollisions(Set genedUsedNames)
      {
          for (int i = 0; i < _interfaceExtensions.size(); i++)
          {
              InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
              if ( genedUsedNames.contains(interfaceExtension.getInterfaceNameForJavaSource().toLowerCase()) )
              {
                  SchemaConfig.error("Extension interface '" + interfaceExtension.getInterfaceNameForJavaSource() + "' creates a name collision with one of the generated interfaces or classes.", null);
              }
              String handlerClassName = interfaceExtension.getHandlerNameForJavaSource();
              if ( handlerClassName!=null &&
                  genedUsedNames.contains(handlerClassName.toLowerCase()) )
              {
                  SchemaConfig.error("Handler class '" + handlerClassName + "' creates a name collision with one of the generated interfaces or classes.", null);
              }
          }
  
          for (int i = 0; i < _prePostExtensions.size(); i++)
          {
              PrePostExtension prePostExtension = (PrePostExtension) _prePostExtensions.get(i);
              String handlerClassName = prePostExtension.getHandlerNameForJavaSource();
              if ( handlerClassName!=null &&
                  genedUsedNames.contains(handlerClassName.toLowerCase()) )
              {
                  SchemaConfig.error("Handler class '" + prePostExtension.getHandlerNameForJavaSource() + "' creates a name collision with one of the generated interfaces or classes.", null);
              }
          }
      }
  
      ExtensionHolder extensionHolderFor(String javaName)
      {
          for (int i = 0; i < _interfaceExtensions.size(); i++)
          {
              InterfaceExtension interfaceExtension = (InterfaceExtension) _interfaceExtensions.get(i);
              if (interfaceExtension.contains(javaName))
                  return this;
          }
  
          for (int i = 0; i < _prePostExtensions.size(); i++)
          {
              PrePostExtension prePostExtension = (PrePostExtension) _prePostExtensions.get(i);
              if (prePostExtension.contains(javaName))
                  return this;
          }
  
          return null;
      }
  
      public List getInterfaceExtensionsFor(String fullJavaName)
      {
          List result = new ArrayList();
          for (int i = 0; i < _interfaceExtensions.size(); i++)
          {
              InterfaceExtension intfExt = (InterfaceExtension) _interfaceExtensions.get(i);
              if (intfExt.contains(fullJavaName))
                  result.add(intfExt);
          }
          return result;
      }
  
      public PrePostExtension getPrePostExtensionsFor(String fullJavaName)
      {
          for (int i = 0; i < _prePostExtensions.size(); i++)
          {
              PrePostExtension prePostExt = (PrePostExtension) _prePostExtensions.get(i);
              if (prePostExt.contains(fullJavaName))
                  return prePostExt;
          }
          return null;
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/InterfaceExtension.java
  
  Index: InterfaceExtension.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.
   */
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Mar 25, 2004
   */
  package org.apache.xmlbeans.impl.config;
  
  import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Extensionconfig;
  import org.apache.xmlbeans.XmlObject;
  
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  
  public class InterfaceExtension
  {
      private NameSet _xbeanSet;
      private Class _interface;
      private Class _delegateToClass;
      private String _delegateToClassName;
      private Method[] _interfaceMethods;
      private Method[] _delegateToMethods;
  
      static InterfaceExtension newInstance(NameSet xbeanSet, Extensionconfig.Interface intfXO)
      {
          InterfaceExtension result = new InterfaceExtension();
  
          result._xbeanSet = xbeanSet;
          result._interface = validateInterface(intfXO.getName(), intfXO);
  
          if (result._interface == null)
          {
              SchemaConfig.error("Interface '" + intfXO.getStaticHandler() + "' not found.", intfXO);
              return null;
          }
  
          result._delegateToClassName = intfXO.getStaticHandler();
          result._delegateToClass = validateClass(result._delegateToClassName, intfXO);
  
          if ( result._delegateToClass==null ) // no HandlerClass
          {
              SchemaConfig.warning("Handler class '" + intfXO.getStaticHandler() + "' not found on classpath, skip validation.", intfXO);
              return result;
          }
  
          if (!result.validateMethods(intfXO))
              return null;
  
          return result;
      }
  
      private static Class validateInterface(String intfStr, XmlObject loc)
      {
          return validateJava(intfStr, true, loc);
      }
  
      static Class validateClass(String clsStr, XmlObject loc)
      {
          return validateJava(clsStr, false, loc);
      }
  
      static Class validateJava(String clsStr, boolean isInterface, XmlObject loc)
      {
          final String ent = isInterface ? "Interface" : "Class";
          try
          {
              Class cls = Class.forName(clsStr);
              if ( (isInterface && !cls.isInterface()) ||
                      (!isInterface && cls.isInterface()))
              {
                  SchemaConfig.error("'" + clsStr + "' must be " +
                      (isInterface ? "an interface" : "a class") + ".", loc);
              }
  
              if (!Modifier.isPublic(cls.getModifiers()))
              {
                  SchemaConfig.error(ent + " '" + clsStr + "' is not public.", loc);
              }
  
              return cls;
          }
          catch (ClassNotFoundException e)
          {
              SchemaConfig.error(ent + " '" + clsStr + "' not found.", loc);
              return null;
          }
      }
  
      private boolean validateMethods(XmlObject loc)
      {
          assert _delegateToClass != null : "Delegate to class handler expected.";
          boolean valid = true;
  
          _interfaceMethods = _interface.getMethods();
          _delegateToMethods = new Method[_interfaceMethods.length];
  
          for (int i = 0; i < _interfaceMethods.length; i++)
          {
              valid &= validateMethod(i, _interfaceMethods[i], loc);
          }
  
          return valid;
      }
  
      private boolean validateMethod(int index, Method method, XmlObject loc)
      {
          String methodName = method.getName();
          Class[] paramTypes = method.getParameterTypes();
          Class returnType = method.getReturnType();
  
          Class[] delegateParams = new Class[paramTypes.length+1];
          delegateParams[0] = XmlObject.class;
          for (int i = 1; i < delegateParams.length; i++)
          {
              delegateParams[i] = paramTypes[i-1];
          }
  
          Method handlerMethod = null;
          try
          {
              handlerMethod = _delegateToClass.getMethod(methodName, delegateParams);
  
              // check for throws exceptions
              Class[] intfExceptions = method.getExceptionTypes();
              Class[] delegateExceptions = handlerMethod.getExceptionTypes();
              if ( delegateExceptions.length!=intfExceptions.length )
              {
                  SchemaConfig.error("Handler method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) +
                      ")' must declare the same exceptions as the interface method '" + _interface.getName() + "." + methodName + "(" + listTypes(paramTypes), loc);
                  return false;
              }
  
              for (int i = 0; i < delegateExceptions.length; i++)
              {
                  if ( delegateExceptions[i]!=intfExceptions[i] )
                  {
                      SchemaConfig.error("Handler method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) +
                          ")' must declare the same exceptions as the interface method '" + _interface.getName() + "." + methodName + "(" + listTypes(paramTypes), loc);
                      return false;
                  }
              }
          }
          catch (NoSuchMethodException e)
          {
              SchemaConfig.error("Handler class '" + _delegateToClass.getName() + "' does not contain method " + methodName + "(" + listTypes(delegateParams) + ")", loc);
              return false;
          }
          catch (SecurityException e)
          {
              SchemaConfig.error("Security violation for class '" + _interface.getName() + "' accesing method " + methodName + "(" + listTypes(delegateParams) + ")", loc);
              return false;
          }
  
          if (!Modifier.isPublic(handlerMethod.getModifiers()) || !Modifier.isStatic(handlerMethod.getModifiers()))
          {
              SchemaConfig.error("Method '" + _delegateToClass.getName() + "." + methodName + "(" + listTypes(delegateParams) + ")' must be declared public and static.", loc);
              return false;
          }
  
          if (!returnType.equals(handlerMethod.getReturnType()))
          {
              SchemaConfig.error("Return type for method '" + handlerMethod.getReturnType() + " " + _delegateToClass.getName() +
                      "." + methodName + "(" + listTypes(delegateParams) + ")' does not match the return type of the interface method :'" + returnType + "'.", loc);
              return false;
          }
  
          _delegateToMethods[index] = method;
  
          return true;
      }
  
      private static String listTypes(Class[] types)
      {
          StringBuffer result = new StringBuffer();
          for (int i = 0; i < types.length; i++)
          {
              Class type = types[i];
              if (i>0)
                  result.append(", ");
              result.append(emitType(type));
          }
          return result.toString();
      }
  
      public static String emitType(Class cls)
      {
          if (cls.isArray())
              return emitType(cls.getComponentType()) + "[]";
          else
              return cls.getName().replace('$', '.');
      }
  
      /* public getters */
      public boolean contains(String fullJavaName)
      {
          return _xbeanSet.contains(fullJavaName);
      }
  
      public String getInterfaceName()
      {
          return _interface.getName();
      }
  
      public String getInterfaceNameForJavaSource()
      {
          return emitType(_interface);
      }
  
      // used only for validation
      public String getHandlerNameForJavaSource()
      {
          if (_delegateToClass==null)
              return null;
  
          return emitType(_delegateToClass);
      }
  
      public int getInterfaceMethodCount()
      {
          return _interfaceMethods.length;
      }
  
      public String getInterfaceMethodName(int methodIndex)
      {
          return _interfaceMethods[methodIndex].getName();
      }
  
      public Method getInterfaceMethod(int methodIndex)
      {
          return _interfaceMethods[methodIndex];
      }
  
      public String getInterfaceMethodDecl(int methodIndex)
      {
          StringBuffer sb = new StringBuffer();
          Method m = _interfaceMethods[methodIndex];
          Class[] paramTypes = m.getParameterTypes();
  
          for (int i = 0; i < paramTypes.length; i++)
          {
              Class paramType = paramTypes[i];
              sb.append( i==0 ? "" : ", " );
              sb.append( emitType(paramType) + " p" + i);
          }
  
          StringBuffer exceptions = new StringBuffer();
          Class[] excClasses = m.getExceptionTypes();
  
          for (int i=0; i<excClasses.length; i++)
              exceptions.append((i==0 ? " throws " : ", ") + emitType(excClasses[i]));
  
          return "public " + emitType(m.getReturnType()) + " " + m.getName() + "(" + sb.toString() + ")" + exceptions.toString();
      }
  
      public String getInterfaceMethodImpl(int methodIndex)
      {
  	// use the methods from the interface for gen the call to the handler
          StringBuffer sb = new StringBuffer();
  
          if (!void.class.equals(_interfaceMethods[methodIndex].getReturnType()))
              sb.append("return ");
  
          sb.append(_delegateToClassName + "." + _delegateToMethods[methodIndex].getName() + "(this");
  
          int paramCount = _interfaceMethods[methodIndex].getParameterTypes().length;
          for (int i=0; i<paramCount; i++)
          {
              sb.append(", p" + i);
          }
  
          sb.append(");");
          return sb.toString();
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSet.java
  
  Index: NameSet.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.
   */
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  package org.apache.xmlbeans.impl.config;
  
  import java.util.Set;
  import java.util.Collections;
  import java.util.HashSet;
  
  /**
   * Reprezents a non finite set of names.
   * @see NameSetBuilder
   */
  public class NameSet
  {
      /**
       * An empty NameSet, it doesn't contain any name
       */
      public static NameSet EMPTY = new NameSet(true, Collections.EMPTY_SET);
      /**
       * The NameSet that contains any name
       */
      public static NameSet EVERYTHING = new NameSet(false, Collections.EMPTY_SET);
  
      /*
      There are two big cases:
      1) - it reprezents "*", ie all except a finite set of names: _isFinite==false
      2) - if reprezents only a finite set of names: _isFinite==true
      */
      private boolean _isFinite;
      private Set _finiteSet;
  
      private NameSet(boolean isFinite, Set finiteSet)
      {
          _isFinite = isFinite;
          _finiteSet = finiteSet;
      }
  
      static NameSet newInstance(boolean isFinite, Set finiteSet)
      {
          if ( finiteSet.size()==0 )
              if ( isFinite )
                  return NameSet.EMPTY;
              else
                  return NameSet.EVERYTHING;
          else
          {
              Set fs = new HashSet();
              fs.addAll(finiteSet);
              return new NameSet(isFinite, fs);
          }
      }
  
      private static Set intersectFiniteSets(Set a, Set b)
      {
          Set intersection = new HashSet();
          //compute the intersection of _finiteSet with withSet
          while (a.iterator().hasNext())
          {
              String name = (String) a.iterator().next();
              if (b.contains(name))
                  intersection.add(name);
          }
          return intersection;
      }
  
      /**
       * Returns the union of this NameSet with the 'with' NameSet.
       */
      public NameSet union(NameSet with)
      {
          if (_isFinite)
          {
              if (with._isFinite)
              {
                  Set union = new HashSet();
                  union.addAll(_finiteSet);
                  union.addAll(with._finiteSet);
                  return newInstance(true, union);
              }
              else
              {
                  Set subst = new HashSet();
                  subst.addAll(with._finiteSet);
                  subst.removeAll(_finiteSet);
                  return newInstance(false, subst);
              }
          }
          else
          {
              if (with._isFinite)
              {
                  Set subst = new HashSet();
                  subst.addAll(_finiteSet);
                  subst.removeAll(with._finiteSet);
                  return newInstance(false, subst);
              }
              else
              {
                  return newInstance(false, intersectFiniteSets(_finiteSet, with._finiteSet));
              }
          }
      }
  
      /**
       * Returns the intersection of this NameSet with the 'with' NameSet
       */
      public NameSet intersect(NameSet with)
      {
          if (_isFinite)
          {
              if (with._isFinite)
              {
                  return newInstance(true, intersectFiniteSets(_finiteSet, with._finiteSet));
              }
              else
              {
                  Set subst = new HashSet();
                  subst.addAll(_finiteSet);
                  subst.removeAll(with._finiteSet);
                  return newInstance(false, subst);
              }
          }
          else
          {
              if (with._isFinite)
              {
                  Set subst = new HashSet();
                  subst.addAll(with._finiteSet);
                  subst.removeAll(_finiteSet);
                  return newInstance(true, subst);
              }
              else
              {
                  Set union = new HashSet();
                  union.addAll(_finiteSet);
                  union.addAll(with._finiteSet);
                  return newInstance(false, union);
              }
          }
      }
  
      /**
       * Returns the result of substracting this NameSet from 'from' NameSet
       * @see NameSet#substract
       */
      public NameSet substractFrom(NameSet from)
      {
          return from.substract(this);
      }
  
      /**
       * Returns the result of substracting 'what' NameSet from this NameSet
       * @see NameSet#substractFrom
       */
      public NameSet substract(NameSet what)
      {
          if (_isFinite)
          {
              if ( what._isFinite )
              {
                  // it's the subst of _finiteSet with what._finiteSet
                  Set subst = new HashSet();
                  subst.addAll(_finiteSet);
                  subst.removeAll(what._finiteSet);
                  return newInstance(true, subst);
              }
              else
              {
                  return newInstance(true, intersectFiniteSets(_finiteSet, what._finiteSet));
              }
          }
          else
          {
              if ( what._isFinite )
              {
                  // it's the union of _finiteSet with what._finiteSet
                  Set union = new HashSet();
                  union.addAll(_finiteSet);
                  union.addAll(what._finiteSet);
                  return newInstance(false, union);
              }
              else
              {
                  // what's in thisSet and it's not in whatSet
                  Set subst = new HashSet();
                  subst.addAll(what._finiteSet);
                  subst.removeAll(_finiteSet);
                  return newInstance(true, subst);
              }
          }
      }
  
      /**
       * Returns an inversion of this NameSet
       */
      public NameSet invert()
      {
          return newInstance(!_isFinite, _finiteSet);
      }
  
      public boolean contains(String name)
      {
          if (_isFinite)
              return _finiteSet.contains(name);
          else
              return !_finiteSet.contains(name);
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSetBuilder.java
  
  Index: NameSetBuilder.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.
   */
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  package org.apache.xmlbeans.impl.config;
  
  import java.util.Set;
  import java.util.HashSet;
  
  /**
   * Used to build {@link NameSet NameSets}.
   */
  public class NameSetBuilder
  {
      private boolean _isFinite;
      private Set _finiteSet;
  
      /**
       * Creates an empty builder for a NameSet.
       */
      public NameSetBuilder()
      {
          _isFinite = true;
          _finiteSet = new HashSet();
      }
  
      /**
       * Inverts the representing NameSet
       */
      public void invert()
      {
          _isFinite = !_isFinite;
      }
  
      /**
       * Adds a name to the representing NameSet
       * @param name
       */
      public void add(String name)
      {
          if (_isFinite )
              _finiteSet.add(name);
          else
              _finiteSet.remove(name);
      }
  
      /**
       * Creates a new NameSet with the current state.
       * @return created NameSet
       */
      public NameSet toNameSet()
      {
          if ( _finiteSet.size()==0 )
              if ( _isFinite )
                  return NameSet.EMPTY;
              else
                  return NameSet.EVERYTHING;
          else
              return NameSet.newInstance(_isFinite, _finiteSet);
      }
  }
  
  
  1.1                  xml-xmlbeans/v1/src/xmlconfig/org/apache/xmlbeans/impl/config/PrePostExtension.java
  
  Index: PrePostExtension.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.
   */
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 12, 2004
   */
  package org.apache.xmlbeans.impl.config;
  
  import org.apache.xmlbeans.XmlObject;
  import org.apache.xml.xmlbeans.x2004.x02.xbean.config.Extensionconfig;
  
  import javax.xml.namespace.QName;
  import java.lang.reflect.Method;
  
  public class PrePostExtension
  {
      public static int OPERATION_SET = 1;
      public static int OPERATION_INSERT = 2;
      public static int OPERATION_REMOVE = 3;
  
      private static final Class[] PARAMTYPES_PREPOST = new Class[]{int.class, XmlObject.class, QName.class, boolean.class, int.class};
      private static final String SIGNATURE = "(int, org.apache.xmlbeans.XmlObject, javax.xml.namespace.QName, boolean, int)";
  
      private NameSet _xbeanSet;
      private Class _delegateToClass;
      private String _delegateToClassName;
      private Method _preSet;
      private Method _postSet;
  
      static PrePostExtension newInstance(NameSet xbeanSet, Extensionconfig.PrePostSet prePostXO)
      {
          if (prePostXO==null)
              return null;
  
          PrePostExtension result = new PrePostExtension();
  
          result._xbeanSet = xbeanSet;
          result._delegateToClassName = prePostXO.getStaticHandler();
          result._delegateToClass = InterfaceExtension.validateClass(result._delegateToClassName, prePostXO);
  
          if ( result._delegateToClass==null ) // no HandlerClass
          {
              SchemaConfig.warning("Handler class '" + prePostXO.getStaticHandler() + "' not found on classpath, skip validation.", prePostXO);
              return result;
          }
  
          if (!result.lookAfterPreAndPost(prePostXO))
              return null;
  
          return result;
      }
  
      private boolean lookAfterPreAndPost(XmlObject loc)
      {
          assert _delegateToClass!=null : "Delegate to class handler expected.";
          boolean valid = true;
  
          try
          {
              _preSet = _delegateToClass.getMethod("preSet", PARAMTYPES_PREPOST);
  
              if (!_preSet.getReturnType().equals(boolean.class))
              {
  		// just emit an warning and don't remember as a preSet
                  SchemaConfig.warning("Method '" + _delegateToClass.getName() +
                      ".preSet" + SIGNATURE + "' " +
                      "should return boolean to be considered for a preSet handler.", loc);
                  _preSet = null;
              }
          }
          catch (NoSuchMethodException e)
          {} // not available is ok, _preSet will be null
          catch (SecurityException e)
          {
              SchemaConfig.error("Security violation for class '" + _delegateToClass.getName() +
                  "' accesing method preSet" + SIGNATURE , loc);
              valid = false;
          }
  
          try
          {
              _postSet = _delegateToClass.getMethod("postSet", PARAMTYPES_PREPOST);
          }
          catch (NoSuchMethodException e)
          {} // not available is ok, _postSet will be null
          catch (SecurityException e)
          {
              SchemaConfig.error("Security violation for class '" + _delegateToClass.getName() +
                  "' accesing method postSet" + SIGNATURE, loc);
              valid = false;
          }
  
          if (_preSet==null && _postSet==null)
          {
              SchemaConfig.error("prePostSet handler specified '" + _delegateToClass.getName() +
                  "' but no preSet" + SIGNATURE + " or " +
                  "postSet" + SIGNATURE + " methods found.", loc);
              valid = false;
          }
  
          return valid;
      }
  
      // public methods
      public boolean contains(String fullJavaName)
      {
          return _xbeanSet.contains(fullJavaName);
      }
  
      public boolean hasPreCall()
      {
          return _preSet!=null;
      }
  
      public boolean hasPostCall()
      {
          return _postSet!=null;
      }
  
      /**
       * Returns the name of the handler in a form that can be put in a java source.
       */
      public String getHandlerNameForJavaSource()
      {
          // used only in validation
          if (_delegateToClass==null)
              return null;
  
          return InterfaceExtension.emitType(_delegateToClass);
      }
  
      /**
       * Returns the gened code for makeing the preSet call
       * @param identifier
       * @param isAttr
       * @param index usualy is 'i', or can be -1 for non array properties
       * @return gened code
       */
      public String getPreCall(int opType, String identifier, boolean isAttr, String index)
      {
          return _delegateToClassName + ".preSet(" + opType + ", this, " + identifier + ", " + isAttr + ", " + index + ")";
      }
  
      /**
       * Returns the gened code for makeing the preSet call
       * @param identifier
       * @param isAttr
       * @param index usualy is 'i', or can be -1 for non array properties
       * @return gened code
       */
      public String getPostCall(int opType, String identifier, boolean isAttr, String index)
      {
          return _delegateToClassName + ".postSet(" + opType + ", this, " + identifier + ", " + isAttr + ", " + index + ");";
      }
  
      public boolean hasNameSetIntersection(PrePostExtension ext)
      {
          return !NameSet.EMPTY.equals(_xbeanSet.intersect(ext._xbeanSet));
      }
  }
  
  
  
  1.4       +5 -22     xml-xmlbeans/v1/test/src/drt/drtcases/SubstGroupTests.java
  
  Index: SubstGroupTests.java
  ===================================================================
  RCS file: /home/cvs/xml-xmlbeans/v1/test/src/drt/drtcases/SubstGroupTests.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SubstGroupTests.java	12 Feb 2004 20:06:05 -0000	1.3
  +++ SubstGroupTests.java	27 Apr 2004 00:19:23 -0000	1.4
  @@ -15,37 +15,20 @@
   
   package drtcases;
   
  -import javax.xml.namespace.QName;
  -import org.apache.xmlbeans.impl.store.Root;
  -import org.apache.xmlbeans.SchemaType;
  -import org.apache.xmlbeans.SchemaTypeLoader;
  -import org.apache.xmlbeans.XmlCursor;
  -import org.apache.xmlbeans.XmlException;
  +import junit.framework.Test;
  +import junit.framework.TestCase;
  +import junit.framework.TestSuite;
   import org.apache.xmlbeans.XmlBeans;
  +import org.apache.xmlbeans.XmlException;
  +import org.apache.xmlbeans.XmlNormalizedString;
   import org.apache.xmlbeans.XmlObject;
  -import org.apache.xmlbeans.XmlOptions;
  -import org.apache.xmlbeans.XMLStreamValidationException;
  -import org.apache.xmlbeans.XmlDecimal;
   import org.apache.xmlbeans.XmlString;
   import org.apache.xmlbeans.XmlToken;
  -import org.apache.xmlbeans.XmlNormalizedString;
  -import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
  -import java.io.File;
  -import java.util.ArrayList;
  -import java.util.List;
  -
  -// Types from substgroup.xsd
   import org.openuri.sgs.ADocument;
   import org.openuri.sgs.BDocument;
   import org.openuri.sgs.CDocument;
   import org.openuri.sgs.RootDocument;
  -
   import org.w3.x2001.xmlSchema.SchemaDocument;
  -
  -import junit.framework.Assert;
  -import junit.framework.Test;
  -import junit.framework.TestCase;
  -import junit.framework.TestSuite;
   
   public class SubstGroupTests extends TestCase
   {
  
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/company.xsd
  
  Index: company.xsd
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <!-- 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. -->
  <xsd:schema targetNamespace="company.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:company="company.xsd">
  	<xsd:element name="company" type="company:CompanyType"/>
  	<xsd:complexType name="CompanyType">
  		<xsd:sequence>
  			<xsd:element name="departments" type="company:DepartmentType" maxOccurs="unbounded"/>
  		</xsd:sequence>
  		<xsd:attribute name="name" type="xsd:string"/>
  		<xsd:attribute name="consultantOfTheMonth" type="xsd:string"/>
  		<xsd:anyAttribute namespace="http://www.omg.org/XMI" processContents="lax"/>
  	</xsd:complexType>
  	<xsd:element name="department" type="company:DepartmentType"/>
  	<xsd:complexType name="DepartmentType">
  		<xsd:sequence>
  		</xsd:sequence>
  		<xsd:attribute name="name" type="xsd:string"/>
  		<xsd:attribute name="location" type="xsd:string"/>
  		<xsd:attribute name="deptID" type="xsd:int"/>
  		<xsd:anyAttribute namespace="http://www.omg.org/XMI" processContents="lax"/>
  	</xsd:complexType>
  </xsd:schema>
  
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/company.xsdconfig
  
  Index: company.xsdconfig
  ===================================================================
  <!-- 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. -->
  <xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">
  
      <xb:extension for="*">
          <xb:interface name="myPackage.Foo">
              <xb:staticHandler>myPackage.FooHandler</xb:staticHandler>
          </xb:interface>
          <xb:prePostSet>
              <xb:staticHandler>myPackage.FooHandler</xb:staticHandler>
          </xb:prePostSet>
      </xb:extension>
  
      <xb:extension for="xsd.company.CompanyDocument">
          <xb:interface name="myPackage.Bar">
              <xb:staticHandler>myPackage.BarHandler</xb:staticHandler>
          </xb:interface>
      </xb:extension>
  
  </xb:config>
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/myPackage/Bar.java
  
  Index: Bar.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 myPackage;
  
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  
  public interface Bar
  {
      byte[] bar(String s) throws MyException;
  
      public static class MyException extends Exception
      {
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/myPackage/BarHandler.java
  
  Index: BarHandler.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 myPackage;
  
  import org.apache.xmlbeans.XmlObject;
  
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  
  public class BarHandler
  {
      public static byte[] bar(XmlObject xo, String s) throws Bar.MyException
      {
          String msg = "{in BarHandler.handleBar(s: " + s + ")}";
          
          if (s==null)
              throw new Bar.MyException();
  
          return msg.getBytes();
      }
  }
  
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/myPackage/Foo.java
  
  Index: Foo.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 myPackage;
  
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  
  public interface Foo
  {
      String foo(String s);
      String getName();
  }
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensions/myPackage/FooHandler.java
  
  Index: FooHandler.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 myPackage;
  
  import org.apache.xmlbeans.XmlObject;
  import org.apache.xmlbeans.XmlCursor;
  
  import javax.xml.namespace.QName;
  
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Apr 25, 2004
   */
  
  public class FooHandler
  {
      public static String foo(XmlObject xo, String s)
      {
          return "{in FooHandler.handleFoo(s: " + s + ")}";
      }
  
      public static String getName(XmlObject xo)
      {
          return "{name in FooHandler}";
      }
  
      // for testing pre and post calls
      public static class PreBookmark extends XmlCursor.XmlBookmark
      {
          String _msg;
  
          PreBookmark(String msg)
          {
              _msg = msg;
          }
  
          public String getMsg()
          {
              return _msg;
          }
      }
  
      public static class PostBookmark extends XmlCursor.XmlBookmark
      {
          String _msg;
  
          PostBookmark(String msg)
          {
              _msg = msg;
          }
  
          public String getMsg()
          {
              return _msg;
          }
      }
  
      public static boolean preSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index)
      {
          XmlCursor xc = xo.newCursor();
          xc.setBookmark(new PreBookmark("{preSet in FooHandler: " + opType + ", " + xo + ", " + prop + ", " + isAttr + ", " + index + "}"));
          xc.dispose();
          return true;
      }
  
      public static void postSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index)
      {
          XmlCursor xc = xo.newCursor();
          xc.setBookmark(new PostBookmark("{postSet in FooHandler: " + opType + ", " + xo + ", " + prop + ", " + isAttr + ", " + index + "}"));
          xc.dispose();
      }
  }
  
  
  1.1                  xml-xmlbeans/v1/test/src/extensionsuse/drtcases/ExtensionsTest.java
  
  Index: ExtensionsTest.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 drtcases;
  
  import junit.framework.TestCase;
  import junit.framework.Test;
  import junit.framework.TestSuite;
  import junit.framework.Assert;
  import xsd.company.CompanyDocument;
  import xsd.company.CompanyType;
  import myPackage.Foo;
  import myPackage.Bar;
  import myPackage.FooHandler;
  import myPackage.FooHandler.PreBookmark;
  import myPackage.FooHandler.PostBookmark;
  import org.apache.xmlbeans.XmlCursor;
  
  /**
   * Author: Cezar Andrei ( cezar.andrei at bea.com )
   * Date: Mar 28, 2004
   */
  public class ExtensionsTest extends TestCase
  {
      public ExtensionsTest(String name) { super(name); }
      public static Test suite() { return new TestSuite(ExtensionsTest.class); }
  
      public void testInterfaces()
      {
  		String expected;
  		String actual;
  
          CompanyDocument cDoc = CompanyDocument.Factory.newInstance();
  
          CompanyType co = cDoc.addNewCompany();
          co.setName2("xbean name");
  
          expected = "xbean name";
          actual = co.getName2();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
          expected = "{name in FooHandler}";
          actual = co.getName();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
          Foo foo = cDoc;
  
          expected = "{in FooHandler.handleFoo(s: param)}";
          actual = foo.foo("param");
          Assert.assertTrue("Expected: '" + expected + "'\n  actual: '" + actual +"'", expected.equals(actual));
  
  
          Bar bar = null;
  
          try
          {
              bar = cDoc;
              byte[] ba = bar.bar("param for bar");
  
  			expected = "{in BarHandler.handleBar(s: param for bar)}";
  			actual = new String(bar.bar("param for bar"));
  			Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
          }
          catch (Bar.MyException e)
          {
              Assert.assertTrue(false);
          }
  
          try
          {
              bar.bar(null);
              Assert.assertTrue(false);
          }
          catch( Bar.MyException e)
          {
              Assert.assertTrue(true);
          }
      }
  
      public void testPrePost()
      {
          String expected;
          String actual;
          XmlCursor xc;
  
          CompanyDocument cDoc = CompanyDocument.Factory.newInstance();
  
          // add new
          CompanyType co = cDoc.addNewCompany();
  
          xc = cDoc.newCursor();
          PreBookmark prebk = (PreBookmark)xc.getBookmark(PreBookmark.class);
  
          expected = "{preSet in FooHandler: 2, <xml-fragment></xml-fragment>, {company.xsd}company, false, -1}";
          actual = prebk.getMsg();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
  
  
          PostBookmark postbk = (PostBookmark)xc.getBookmark(PostBookmark.class);
  
          expected = "{postSet in FooHandler: 2, " + cDoc + ", {company.xsd}company, false, -1}";
          actual = postbk.getMsg();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
          xc.dispose();
  
  
          // set
          co.setName2("xbean name");
  
          xc = co.newCursor();
          prebk = (PreBookmark)xc.getBookmark(PreBookmark.class);
  
          expected = "{preSet in FooHandler: 1, <xml-fragment/>, name, true, -1}";
          actual = prebk.getMsg();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
  
  
          postbk = (PostBookmark)xc.getBookmark(PostBookmark.class);
  
          expected = "{postSet in FooHandler: 1, " + co + ", name, true, -1}";
          actual = postbk.getMsg();
          Assert.assertTrue("Expected: " + expected + "\n  actual: " + actual, expected.equals(actual));
  
          xc.dispose();
      }
  }
  
  
  

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