You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by sc...@apache.org on 2008/09/16 00:44:49 UTC

svn commit: r695676 - in /tuscany/branches/sca-java-1.3.2/modules: databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/ databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/

Author: scottkurz
Date: Mon Sep 15 15:44:48 2008
New Revision: 695676

URL: http://svn.apache.org/viewvc?rev=695676&view=rev
Log:
Commit changes for TUSCANY-2590.

Modified:
    tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/JAXBDataSource.java
    tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/OMElement2JAXB.java
    tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
    tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java

Modified: tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/JAXBDataSource.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/JAXBDataSource.java?rev=695676&r1=695675&r2=695676&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/JAXBDataSource.java (original)
+++ tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/JAXBDataSource.java Mon Sep 15 15:44:48 2008
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.    
  */
-
 package org.apache.tuscany.sca.databinding.jaxb.axiom;
 
 import java.io.OutputStream;
@@ -37,6 +36,7 @@
 import org.apache.axiom.om.OMDataSource;
 import org.apache.axiom.om.OMOutputFormat;
 import org.apache.axiom.om.util.StAXUtils;
+import org.apache.tuscany.sca.databinding.jaxb.JAXBContextHelper;
 
 /**
  *
@@ -55,11 +55,14 @@
     private Marshaller getMarshaller() throws JAXBException {
         if (marshaller == null) {
             // For thread safety, not sure we can cache the marshaller
-            // marshaller = JAXBContextHelper.getMarshaller(context); 
-            marshaller = context.createMarshaller();
+            marshaller = JAXBContextHelper.getMarshaller(context); 
         }
         return marshaller;
     }
+    
+    private void releaseMarshaller(Marshaller marshaller) {
+        JAXBContextHelper.releaseJAXBMarshaller(context, marshaller);
+    }
 
     public XMLStreamReader getReader() throws XMLStreamException {
         // FIXME: [rfeng] This is a quick and dirty implementation
@@ -75,11 +78,12 @@
             // marshaller.setProperty(Marshaller.JAXB_ENCODING, format.getCharSetEncoding());
             AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                 public Object run() throws Exception {
-                    Marshaller marshaller = getMarshaller();
-                    // Set the FRAGEMENT property to avoid duplicate XML declaration
-                    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
-                    marshaller.marshal(element, xmlWriter);
-                    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
+                    try {
+                        Marshaller marshaller = getMarshaller();
+                        marshaller.marshal(element, xmlWriter);                  
+                    } finally {
+                        releaseMarshaller(marshaller);
+                    } 
                     return null;
                 }
             });
@@ -93,8 +97,12 @@
             // marshaller.setProperty(Marshaller.JAXB_ENCODING, format.getCharSetEncoding());
             AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                 public Object run() throws Exception {
-                    Marshaller marshaller = getMarshaller();
-                    marshaller.marshal(element, output);
+                    try {
+                        Marshaller marshaller = getMarshaller();
+                        marshaller.marshal(element, output);
+                    } finally {
+                        releaseMarshaller(marshaller);
+                    }
                     return null;
                 }
             });
@@ -107,8 +115,12 @@
         try {
             AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                 public Object run() throws Exception {
-                    Marshaller marshaller = getMarshaller();
-                    marshaller.marshal(element, writer);
+                    try {
+                        Marshaller marshaller = getMarshaller();
+                        marshaller.marshal(element, writer);
+                    } finally {
+                        releaseMarshaller(marshaller);
+                    }
                     return null;
                 }
             });

Modified: tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/OMElement2JAXB.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/OMElement2JAXB.java?rev=695676&r1=695675&r2=695676&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/OMElement2JAXB.java (original)
+++ tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb-axiom/src/main/java/org/apache/tuscany/sca/databinding/jaxb/axiom/OMElement2JAXB.java Mon Sep 15 15:44:48 2008
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.    
  */
-
 package org.apache.tuscany.sca.databinding.jaxb.axiom;
 
 import java.security.AccessController;
@@ -51,15 +50,21 @@
         try {
             return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                 public Object run() throws JAXBException, XMLStreamException {
+                    Unmarshaller unmarshaller = null;
+                    XMLStreamReader reader = null;
+                    Object result = null;
                     // Marshalling directly to the output stream is faster than marshalling through the
                     // XMLStreamWriter. 
                     // Take advantage of this optimization if there is an output stream.
                     JAXBContext jaxbContext = JAXBContextHelper.createJAXBContext(context, false);
-                    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-                    XMLStreamReader reader = source.getXMLStreamReaderWithoutCaching();
-                    Object result =
-                        unmarshaller.unmarshal(reader, JAXBContextHelper.getJavaType(context.getTargetDataType()));
-                    reader.close();
+                    try {
+                        unmarshaller = JAXBContextHelper.getUnmarshaller(jaxbContext);
+                        reader = source.getXMLStreamReaderWithoutCaching();
+                        result = unmarshaller.unmarshal(reader, JAXBContextHelper.getJavaType(context.getTargetDataType()));
+                    } finally {
+                        reader.close();
+                        JAXBContextHelper.releaseJAXBUnmarshaller(jaxbContext, unmarshaller);
+                    }
                     return JAXBContextHelper.createReturnValue(jaxbContext, context.getTargetDataType(), result);
                 }
             });

Modified: tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java?rev=695676&r1=695675&r2=695676&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java (original)
+++ tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java Mon Sep 15 15:44:48 2008
@@ -16,21 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.    
  */
-
 package org.apache.tuscany.sca.databinding.jaxb;
 
 import java.awt.Image;
+import java.lang.ref.SoftReference;
 import java.net.URI;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.activation.DataHandler;
 import javax.xml.bind.JAXBContext;
@@ -86,8 +91,8 @@
     */
 
     protected LRUCache<Object, JAXBContext> cache;
-    protected LRUCache<JAXBContext, Unmarshaller> upool;
-    protected LRUCache<JAXBContext, Marshaller> mpool;
+    protected Pool<JAXBContext, Marshaller>  mpool;
+    protected Pool<JAXBContext, Unmarshaller> upool;
     
     // protected JAXBContext commonContext;
     protected JAXBContext defaultContext;
@@ -98,8 +103,8 @@
 
     public JAXBContextCache(int contextSize, int marshallerSize, int unmarshallerSize) {
         cache = new LRUCache<Object, JAXBContext>(contextSize);
-        upool = new LRUCache<JAXBContext, Unmarshaller>(unmarshallerSize);
-        mpool = new LRUCache<JAXBContext, Marshaller>(marshallerSize);
+        mpool = new Pool<JAXBContext, Marshaller>();
+        upool = new Pool<JAXBContext, Unmarshaller>();
         defaultContext = getDefaultJAXBContext();
     }
     
@@ -180,27 +185,38 @@
     }
 
     public Marshaller getMarshaller(JAXBContext context) throws JAXBException {
-        synchronized (mpool) {
-            Marshaller marshaller = mpool.get(context);
-            if (marshaller == null) {
-                marshaller = context.createMarshaller();
-                mpool.put(context, marshaller);
-            }
-            return marshaller;
-        }
+        Marshaller marshaller = mpool.get(context);
+        if (marshaller == null) {
+            marshaller = context.createMarshaller();
+        }
+        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
+        return marshaller;
     }
 
+    public void releaseJAXBMarshaller(JAXBContext context, Marshaller marshaller) {   
+        if (marshaller != null) {
+            marshaller.setAttachmentMarshaller(null);
+            mpool.put(context, marshaller);
+            // No point unsetting marshaller's JAXB_FRAGMENT property, since we'll just reset it when
+            // doing the next get.
+        }
+    }
+    
     public Unmarshaller getUnmarshaller(JAXBContext context) throws JAXBException {
-        synchronized (upool) {
-            Unmarshaller unmarshaller = upool.get(context);
-            if (unmarshaller == null) {
-                unmarshaller = context.createUnmarshaller();
-                upool.put(context, unmarshaller);
-            }
-            return unmarshaller;
+        Unmarshaller unmarshaller = upool.get(context);
+        if (unmarshaller == null) {
+            unmarshaller = context.createUnmarshaller();
         }
+        return unmarshaller;
     }
 
+    public void releaseJAXBUnmarshaller(JAXBContext context, Unmarshaller unmarshaller) {   
+        if (unmarshaller != null) {
+            unmarshaller.setAttachmentUnmarshaller(null);
+            upool.put(context, unmarshaller);
+        }
+    }
+    
     public LRUCache<Object, JAXBContext> getCache() {
         return cache;
     }
@@ -282,12 +298,123 @@
         synchronized (cache) {
             cache.clear();
         }
+        /*
         synchronized (upool) {
             upool.clear();
         }
         synchronized (upool) {
             upool.clear();
         }
+        */
     }
 
+    //
+    // This inner class is copied in its entirety from the Axis2 utility class,
+    // org.apache.axis2.jaxws.message.databinding.JAXBUtils.   We could look into extending but it's such a basic data structure
+    // without other dependencies so we might be better off copying it and avoiding a new
+    // Axis2 dependency here.
+    //
+    
+    /**
+     * Pool a list of items for a specific key
+     *
+     * @param <K> Key
+     * @param <V> Pooled object
+     */
+    private static class Pool<K,V> {
+        private SoftReference<Map<K,List<V>>> softMap = 
+            new SoftReference<Map<K,List<V>>>(
+                    new ConcurrentHashMap<K, List<V>>());
+
+        // The maps are freed up when a LOAD FACTOR is hit
+        private static int MAX_LIST_FACTOR = 50;
+        private static int MAX_LOAD_FACTOR = 32;  // Maximum number of JAXBContext to store
+        
+        /**
+         * @param key
+         * @return removed item from pool or null.
+         */
+        public V get(K key) {
+            List<V> values = getValues(key);
+            synchronized (values) {
+                if (values.size()>0) {
+                    V v = values.remove(values.size()-1);
+                    return v;
+                    
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Add item back to pool
+         * @param key
+         * @param value
+         */
+        public void put(K key, V value) {
+            adjustSize();
+            List<V> values = getValues(key);
+            synchronized (values) {
+                if (values.size() < MAX_LIST_FACTOR) {
+                    values.add(value);
+                }
+            }
+        }
+
+        /**
+         * Get or create a list of the values for the key
+         * @param key
+         * @return list of values.
+         */
+        private List<V> getValues(K key) {
+            Map<K,List<V>> map = softMap.get();
+            List<V> values = null;
+            if (map != null) {
+                values = map.get(key);
+                if(values !=null) {
+                    return values;
+                }
+            }
+            synchronized (this) {
+                if (map != null) {
+                    values = map.get(key);
+                }
+                if (values == null) {
+                    if (map == null) {
+                        map = new ConcurrentHashMap<K, List<V>>();
+                        softMap = 
+                            new SoftReference<Map<K,List<V>>>(map);
+                    }
+                    values = new ArrayList<V>();
+                    map.put(key, values);
+
+                }
+                return values;
+            }
+        }
+        
+        /**
+         * AdjustSize
+         * When the number of keys exceeds the maximum load, half
+         * of the entries are deleted.
+         * 
+         * The assumption is that the JAXBContexts, UnMarshallers, Marshallers, etc. require
+         * a large footprint.
+         */
+        private void adjustSize() {
+            Map<K,List<V>> map = softMap.get();
+            if (map != null && map.size() > MAX_LOAD_FACTOR) {
+                // Remove every other Entry in the map.
+                Iterator it = map.entrySet().iterator();
+                boolean removeIt = false;
+                while (it.hasNext()) {
+                    it.next();
+                    if (removeIt) {
+                        it.remove();
+                    }
+                    removeIt = !removeIt;
+                }
+            }
+        }
+    }
 }

Modified: tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
URL: http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java?rev=695676&r1=695675&r2=695676&view=diff
==============================================================================
--- tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java (original)
+++ tuscany/branches/sca-java-1.3.2/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java Mon Sep 15 15:44:48 2008
@@ -112,10 +112,18 @@
         return cache.getUnmarshaller(context);
     }
 
+    public static void releaseJAXBUnmarshaller(JAXBContext context, Unmarshaller unmarshaller) {
+        cache.releaseJAXBUnmarshaller(context, unmarshaller);
+    }
+    
     public static Marshaller getMarshaller(JAXBContext context) throws JAXBException {
         return cache.getMarshaller(context);
     }
 
+    public static void releaseJAXBMarshaller(JAXBContext context, Marshaller marshaller) {
+        cache.releaseJAXBMarshaller(context, marshaller);
+    }
+    
     @SuppressWarnings("unchecked")
     public static Object createJAXBElement(JAXBContext context, DataType dataType, Object value) {
         Class<?> type = dataType == null ? value.getClass() : dataType.getPhysical();