gdaniels    2003/08/29 22:20:58

  Modified:    java/src/org/apache/axis/description TypeDesc.java
  Added:       java/test/typedesc ComplexBean.java ComplexBean2.java
                        ComplexBean3.java PackageTests.java SimpleBean.java
                        SimpleBean2.java TestTypeDescSynch.java build.xml
  Log:
  Fix http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22819
  
  Thanks to [EMAIL PROTECTED] for the analysis/testcase.
  
  Revision  Changes    Path
  1.35      +16 -7     xml-axis/java/src/org/apache/axis/description/TypeDesc.java
  
  Index: TypeDesc.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/description/TypeDesc.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- TypeDesc.java     31 Jul 2003 06:25:18 -0000      1.34
  +++ TypeDesc.java     30 Aug 2003 05:20:58 -0000      1.35
  @@ -57,7 +57,6 @@
   
   import org.apache.axis.utils.BeanPropertyDescriptor;
   import org.apache.axis.utils.BeanUtils;
  -import org.apache.axis.utils.ClassUtils;
   import org.apache.axis.utils.Messages;
   import org.apache.axis.utils.cache.MethodCache;
   
  @@ -86,6 +85,7 @@
   
       /** Can this instance search for metadata in parents of the type it describes? 
*/
       private boolean canSearchParents = true;
  +    private boolean hasSearchedParents = false;
   
       /**
        * Creates a new <code>TypeDesc</code> instance.  The type desc can search
  @@ -196,7 +196,7 @@
           // complete description of their content model in their own
           // metadata, per the XML schema rules for
           // derivation-by-restriction
  -        if (canSearchParents && searchParents) {
  +        if (canSearchParents && searchParents && !hasSearchedParents) {
               // check superclasses if they exist
               Class cls = javaClass.getSuperclass();
               if (cls != null && !cls.getName().startsWith("java.")) {
  @@ -219,6 +219,8 @@
   // END FIX http://nagoya.apache.org/bugzilla/show_bug.cgi?id=17188
                   }
               }
  +            
  +            hasSearchedParents = true;
           }
   
           return fields;
  @@ -465,13 +467,20 @@
           // may be a faster way to set the property descriptions than
           // using BeanUtils.getPd.  But for now calling getPd is sufficient.
           if (propertyDescriptors == null) {
  -            propertyDescriptors = BeanUtils.getPd(javaClass, this);
  -            if (!lookedForAny) {
  -                anyDesc = BeanUtils.getAnyContentPD(javaClass);
  -                lookedForAny = true;
  -            }
  +            makePropertyDescriptors();
           }
           return propertyDescriptors;
  +    }
  +    
  +    private synchronized void makePropertyDescriptors() {
  +        if (propertyDescriptors != null)
  +            return;
  +
  +        propertyDescriptors = BeanUtils.getPd(javaClass, this);
  +        if (!lookedForAny) {
  +            anyDesc = BeanUtils.getAnyContentPD(javaClass);
  +            lookedForAny = true;
  +        }
       }
   
       public BeanPropertyDescriptor getAnyContentDescriptor() {
  
  
  
  1.1                  xml-axis/java/test/typedesc/ComplexBean.java
  
  Index: ComplexBean.java
  ===================================================================
  package test.typedesc;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.namespace.QName;
  
  public class ComplexBean extends SimpleBean implements java.io.Serializable {
  
      public String c;
      public String d;
      public String e;
      public String f;
  
      private static TypeDesc typeDesc = new TypeDesc(ComplexBean.class);
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("c");
          fd.setXmlName(new QName("foo", "c"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("d");
          fd.setXmlName(new QName("foo", "d"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("e");
        ((AttributeDesc)fd).setAttributeName("ffffff");
          fd.setXmlName(new QName("foo", "e"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("f");
          fd.setXmlName(new QName("foo", "f"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      public ComplexBean() {}
  
      public void setC(String value) {
      }
  
      public String getC() {
        return null;
      }
  
      public void setD(String value) {
      }
  
      public String getD() {
        return null;
      }
  
      public void setE(String value) {
      }
  
      public String getE() {
        return null;
      }
  
      public void setF(String value) {
      }
      
      public String getF() {
        return null;
      }
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/ComplexBean2.java
  
  Index: ComplexBean2.java
  ===================================================================
  package test.typedesc;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.namespace.QName;
  
  public class ComplexBean2 extends SimpleBean2 implements java.io.Serializable {
  
      public String c;
      public String d;
      public String e;
  
      private static TypeDesc typeDesc = new TypeDesc(ComplexBean2.class);
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("c");
          fd.setXmlName(new QName("foo", "c"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("d");
          fd.setXmlName(new QName("foo", "d"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("e");
        ((AttributeDesc)fd).setAttributeName("ffffff");
          fd.setXmlName(new QName("foo", "e"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      public ComplexBean2() {}
  
      public void setC(String value) {
      }
  
      public String getC() {
        return null;
      }
  
      public void setD(String value) {
      }
  
      public String getD() {
        return null;
      }
  
      public void setE(String value) {
      }
  
      public String getE() {
        return null;
      }
  
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/ComplexBean3.java
  
  Index: ComplexBean3.java
  ===================================================================
  package test.typedesc;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.namespace.QName;
  
  public class ComplexBean3 extends SimpleBean2 implements java.io.Serializable {
  
      public String c;
      public String d;
  
      private static TypeDesc typeDesc = new TypeDesc(ComplexBean3.class);
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("c");
          fd.setXmlName(new QName("foo", "c"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("d");
          fd.setXmlName(new QName("foo", "d"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      public ComplexBean3() {}
  
      public void setC(String value) {
      }
  
      public String getC() {
        return null;
      }
  
      public void setD(String value) {
      }
  
      public String getD() {
        return null;
      }
  
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/PackageTests.java
  
  Index: PackageTests.java
  ===================================================================
  package test.typedesc;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  
  public class PackageTests extends TestCase {
  
      public PackageTests(String name) {
          super(name);
      }
  
      public static Test suite() throws Exception {
          TestSuite suite = new TestSuite();
  
          suite.addTestSuite(TestTypeDescSynch.class);
  
          return suite;
      }
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/SimpleBean.java
  
  Index: SimpleBean.java
  ===================================================================
  package test.typedesc;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.namespace.QName;
  
  public class SimpleBean implements java.io.Serializable {
  
      public String a;
      public String b;
  
      private static TypeDesc typeDesc = new TypeDesc(SimpleBean.class);
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("a");
          fd.setXmlName(new QName("foo", "a"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("b");
          fd.setXmlName(new QName("foo", "b"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      public SimpleBean() {}
  
      public void setA(String value) {
      }
      
      public String getA() {
        return null;
      }
  
      public void setB(String value) {
      }
  
      public String getB() {
        return null;
      }
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/SimpleBean2.java
  
  Index: SimpleBean2.java
  ===================================================================
  package test.typedesc;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.namespace.QName;
  
  public class SimpleBean2 implements java.io.Serializable {
  
      public String a;
      public String b;
  
      private static TypeDesc typeDesc = new TypeDesc(SimpleBean2.class);
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("a");
          fd.setXmlName(new QName("foo", "a"));
          typeDesc.addFieldDesc(fd);
  
        fd = new AttributeDesc();
          fd.setFieldName("b");
          fd.setXmlName(new QName("foo", "b"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      public SimpleBean2() {}
  
      public void setA(String value) {
      }
      
      public String getA() {
        return null;
      }
  
      public void setB(String value) {
      }
  
      public String getB() {
        return null;
      }
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/TestTypeDescSynch.java
  
  Index: TestTypeDescSynch.java
  ===================================================================
  package test.typedesc;
  
  import junit.framework.TestCase;
  
  import org.apache.axis.client.Call;
  import org.apache.axis.client.Service;
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.TypeDesc;
  
  import org.apache.axis.encoding.ser.BeanSerializerFactory;
  import org.apache.axis.encoding.ser.BeanDeserializerFactory;
  
  import javax.xml.namespace.QName;
  
  /**
   * Confirm TypeDesc bugs are indeed fixed.
   * 
   * See http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22819 for details
   * 
   * @author [EMAIL PROTECTED]
   */ 
  public class TestTypeDescSynch extends TestCase { 
      
      public TestTypeDescSynch(String name) {
          super(name);
      }
      
      public TestTypeDescSynch() {
          super("Test TypeDesc Synch");
      }
      
      // with won't fail
      public void testFields() throws Exception {
          TypeDesc desc= TypeDesc.getTypeDescForClass(ComplexBean2.class);
          for (int i=0; i < 10; i++) {
              desc.getFields(true);
              
              // Check to make sure we keep to the constant 5 fields (this
              // used to grow each time we called getFields(true)).
              assertEquals(5, desc.getFields().length);
          }
      }
      
      // this should fail
      public void testFields2() throws Exception {
          Service service = new Service();
          Call call  = (Call)service.createCall();
          
          call.registerTypeMapping(ComplexBean3.class, 
                                   new QName("foo2", "bar2"),
                                   BeanSerializerFactory.class,
                                   BeanDeserializerFactory.class,
                                   false);
          
          TypeDesc desc= TypeDesc.getTypeDescForClass(ComplexBean3.class);
          assertEquals(4, desc.getFields().length);
      }
      
      // this might fail
      public void testSynch() throws Exception {
          
          int threads = 30;
          
          ThreadTest[] thread = new ThreadTest[threads];
          for (int i=0;i<threads;i++) {
              thread[i] = new ThreadTest();
              thread[i].start();
          }
          
          Throwable ex = null;
          
          for (int i=0;i<threads;i++) {
              thread[i].join();
              if (ex == null && thread[i].getException() != null) {
                  ex = thread[i].getException();
              }
          }
          
          // either assertion will fail or ArrayIndexOutOfBoundException will
          // be raised (or it might be ok)
          
          TypeDesc desc= TypeDesc.getTypeDescForClass(ComplexBean.class);
          
          assertEquals(6, desc.getFields().length);
          
          if (ex != null) {
              fail(ex.getMessage());
          }
      }
      
      class ThreadTest extends Thread {
          
          Throwable ex = null;
          
          public Throwable getException() {
              return this.ex;
          }
          
          public void run() {
              
              try {
                  
                  /*
                  Service service = new Service();
                  Call call  = (Call)service.createCall();
                  
                  call.registerTypeMapping(ComplexBean.class, 
                  new QName("foo", "bar"),
                  BeanSerializerFactory.class,
                  BeanDeserializerFactory.class,
                  false);
                  */
                  
                  // this - demonstrates the same problem as above
                  // just can check the ArrayIndexOutOfBoundsException
                  BeanSerializerFactory f =
                          new BeanSerializerFactory(ComplexBean.class,
                                                    new QName("foo", "bar"));
              } catch (Exception e) {
                  ex = e;
              }
              
              
          }
      }
      
      public static void main(String args[])
      {
          try {
              TestTypeDescSynch tester = new TestTypeDescSynch("TypeDesc Test");
              tester.testSynch();
              tester.testFields();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  
  
  
  1.1                  xml-axis/java/test/typedesc/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0" ?>
  <!DOCTYPE project [
          <!ENTITY properties SYSTEM "file:../../xmls/properties.xml">
          <!ENTITY paths  SYSTEM "file:../../xmls/path_refs.xml">
          <!ENTITY taskdefs SYSTEM "file:../../xmls/taskdefs.xml">
          <!ENTITY taskdefs_post_compile SYSTEM 
"file:../../xmls/taskdefs_post_compile.xml">
          <!ENTITY targets SYSTEM "file:../../xmls/targets.xml">
  ]>
  
  <!-- ===================================================================
  <description>
     Test/Sample Component file for Axis
  
  Notes:
     This is a build file for use with the Jakarta Ant build tool.
  
  Prerequisites:
  
     jakarta-ant from http://jakarta.apache.org
  
  Build Instructions:
     To compile
          ant compile
     To execute
          ant run
  
  Author:
    Matt Seibert [EMAIL PROTECTED]
  
  Copyright:
    Copyright (c) 2002-2003 Apache Software Foundation.
  </description>
  ==================================================================== -->
  
  <project default="compile">
  
          <property name="axis.home" location="../../" />
        <property name="componentName" value="test/typedesc"/>
  
          &properties;
          &paths;
          &taskdefs;
          &taskdefs_post_compile;
        &targets;
  
  
  <target name="clean">
      <echo message="Removing ${build.dir}/classes/${componentName} and 
${build.dir}/work/${componentName}" />
      <delete dir="${build.dir}/classes/${componentName}"/>
      <delete dir="${build.dir}/work/${componentName}"/>
  </target>
  
  <target name="copy" depends="setenv"/>
  
  <target name="compile" depends="copy">
    <echo message="Compiling test.${componentName}"/>
    <javac srcdir="${axis.home}" destdir="${build.dest}" debug="${debug}" 
fork="${javac.fork}">
      <classpath>
          <path refid="classpath"/>
      </classpath>
      <include name="${componentName}/*.java"/>
    </javac>
  </target>
  
  <target name="run">
        <antcall target="execute-Component" />
  </target>
  
  </project>
  
  
  

Reply via email to