You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2011/10/20 16:17:12 UTC

svn commit: r1186823 - /uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java

Author: schor
Date: Thu Oct 20 14:17:12 2011
New Revision: 1186823

URL: http://svn.apache.org/viewvc?rev=1186823&view=rev
Log:
[UIMA-2270] [UIMA-239] fix Introspection caching causing poor performance in IBM Java.  Prepare for enabling XML comment preservation in XML parsing.

Modified:
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java?rev=1186823&r1=1186822&r2=1186823&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/metadata/impl/MetaDataObject_impl.java Thu Oct 20 14:17:12 2011
@@ -33,6 +33,8 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -48,6 +50,7 @@ import org.apache.uima.util.NameClassPai
 import org.apache.uima.util.XMLParser;
 import org.apache.uima.util.XMLSerializer;
 import org.apache.uima.util.XMLizable;
+import org.w3c.dom.Comment;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -83,10 +86,12 @@ public abstract class MetaDataObject_imp
 
   private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();
 
-  private transient PropertyDescriptor[] mPropertyDescriptors = null;
+  // Class level cache (static) for introspection - 30x speedup in CDE for large descriptor
+  private static transient Map<Class<? extends MetaDataObject_impl>, PropertyDescriptor[]> mPropertyDescriptorsMap = 
+    Collections.synchronizedMap(new IdentityHashMap<Class<? extends MetaDataObject_impl>, PropertyDescriptor[]>());  
 
   private transient URL mSourceUrl;
-
+  
   /**
    * Creates a new <code>MetaDataObject_impl</code> with null attribute values
    */
@@ -98,6 +103,8 @@ public abstract class MetaDataObject_imp
    * and the Classes of the attributes' values. For primitive types, the wrapper classes will be
    * returned (e.g. <code>java.lang.Integer</code> instead of int).
    * 
+   * Several subclasses override this, to add additional items to the list.
+   * 
    * @see org.apache.uima.resource.MetaDataObject#listAttributes()
    */
   public List<NameClassPair> listAttributes() {
@@ -146,7 +153,7 @@ public abstract class MetaDataObject_imp
   }
 
   /**
-   * Gets the Class of the given attribue's value. For primitive types, the wrapper classes will be
+   * Gets the Class of the given attribute's value. For primitive types, the wrapper classes will be
    * returned (e.g. <code>java.lang.Integer</code> instead of int).
    * 
    * @param aName
@@ -157,12 +164,11 @@ public abstract class MetaDataObject_imp
    */
   public Class getAttributeClass(String aName) {
     try {
+      // note: listAttributes() is overridden in some subclasses to add additional items
       List<NameClassPair> attrList = listAttributes();
-      Iterator<NameClassPair> it = attrList.iterator();
-      while (it.hasNext()) {
-        NameClassPair ncp = it.next();
+      for (NameClassPair ncp : attrList) {
         if (ncp.getName().equals(aName)) {
-          return Class.forName(ncp.getClassName());
+          return Class.forName(ncp.getClassName()); 
         }
       }
       return null;
@@ -915,6 +921,9 @@ public abstract class MetaDataObject_imp
             readUnknownPropertyValueFromXMLElement(curElem, aParser, aOptions, foundProperties);
           }
         }
+      } else if (curNode instanceof Comment) {
+        Comment curElem = (Comment) curNode;
+        String comment = curElem.getData();
       }
     }
   }
@@ -1259,17 +1268,21 @@ public abstract class MetaDataObject_imp
    * initialization time by preventing the introspector from searching for nonexistent BeanInfo
    * classes for all the MetaDataObjects.
    * 
+   * Caching needed, this method is called for every access to a field, and introspection doesn't cache
+   * (from observation... although the javadocs say otherwise (as of Java6 10/2011 - both IBM and Sun)
+   * 
    * @return the <code>PropertyDescriptors</code> for all properties introduced by subclasses of
    *         <code>MetaDataObject_impl</code>.
    * 
    * @throw IntrospectionException if introspection fails
    */
-  protected PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException {
-    if (mPropertyDescriptors == null) {
-      mPropertyDescriptors = Introspector.getBeanInfo(this.getClass(),
-              Introspector.IGNORE_ALL_BEANINFO).getPropertyDescriptors();
+  protected PropertyDescriptor[] getPropertyDescriptors() throws IntrospectionException { 
+    PropertyDescriptor[] pd = mPropertyDescriptorsMap.get(this.getClass());
+    if (null == pd) {
+      pd = Introspector.getBeanInfo(this.getClass(), Introspector.IGNORE_ALL_BEANINFO).getPropertyDescriptors();
+      mPropertyDescriptorsMap.put(this.getClass(), pd);
     }
-    return mPropertyDescriptors;
+    return pd;
   }
 
 }