You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2012/07/23 12:15:14 UTC

svn commit: r1364564 - in /ofbiz/trunk/framework: service/src/org/ofbiz/service/ webtools/src/org/ofbiz/webtools/artifactinfo/ webtools/src/org/ofbiz/webtools/labelmanager/

Author: jacopoc
Date: Mon Jul 23 10:15:13 2012
New Revision: 1364564

URL: http://svn.apache.org/viewvc?rev=1364564&view=rev
Log:
Refactored DispatchContext class to be thread safe thru immutability; resorted its methods to improve the readability; added some comments to better describe it.

Modified:
    ofbiz/trunk/framework/service/src/org/ofbiz/service/DispatchContext.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericDispatcher.java
    ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java
    ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelReferences.java

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/DispatchContext.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/DispatchContext.java?rev=1364564&r1=1364563&r2=1364564&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/DispatchContext.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/DispatchContext.java Mon Jul 23 10:15:13 2012
@@ -58,18 +58,43 @@ public class DispatchContext implements 
 
     private static final UtilCache<String, Map<String, ModelService>> modelServiceMapByModel = UtilCache.createUtilCache("service.ModelServiceMapByModel", 0, 0, false);
 
-    protected transient LocalDispatcher dispatcher;
-    protected transient ClassLoader loader;
-    protected final String name;
-    private String model;
-
-    /**
-     * Creates new DispatchContext
+    // these four fields represent the immutable state of a DispatchContext object
+    private final String name;
+    private final transient ClassLoader loader;
+    private final transient LocalDispatcher dispatcher;
+    private final String model;
+
+    /**
+     * Creates new DispatchContext as an immutable object.
+     * The "dispatcher" argument can be null if the "name" argument matches the name of a valid entity model reader.
+     * The thread safety of a DispatchContext object is a consequence of its immutability.
+     *
+     * @param name The immutable name of the DispatchContext
+     * @param loader The immutable class loader
+     * @param dispatcher The immutable dispatcher associated to the DispatchContext
+     *
      */
-    public DispatchContext(String name, ClassLoader loader) {
+    public DispatchContext(String name, ClassLoader loader, LocalDispatcher dispatcher) {
         this.name = name;
-        this.model = name; // this will change when a dispatcher is set to match the model name associated to the delegator's dispatcher
         this.loader = loader;
+        this.dispatcher = dispatcher;
+        String modelName = null;
+        if (this.dispatcher != null) {
+            Delegator delegator = dispatcher.getDelegator();
+            if (delegator != null) {
+                DelegatorInfo delegatorInfo = EntityConfigUtil.getDelegatorInfo(delegator.getDelegatorBaseName());
+                if (delegatorInfo != null) {
+                    modelName = delegatorInfo.entityModelReader;
+                }
+            }
+        }
+        if (modelName == null) {
+            // if a modelName is not associated to the dispatcher (e.g. dispatcher is null) then use the name
+            // of the DispatchContext as the model reader name
+            modelName = name;
+        }
+        this.model = modelName;
+        getGlobalServiceMap();
     }
 
     /**
@@ -89,6 +114,37 @@ public class DispatchContext implements 
     }
 
     /**
+     * Gets the LocalDispatcher used with this context
+     * @return LocalDispatcher that was used to create this context
+     */
+    public LocalDispatcher getDispatcher() {
+        return this.dispatcher;
+    }
+
+    /**
+     * Gets the Delegator associated with this context/dispatcher
+     * @return Delegator associated with this context
+     */
+    public Delegator getDelegator() {
+        return dispatcher.getDelegator();
+    }
+
+    /**
+     * Gets the Security object associated with this dispatcher
+     * @return Security object associated with this dispatcher
+     */
+    public Security getSecurity() {
+        return dispatcher.getSecurity();
+    }
+
+    // All the methods that follow are helper methods to retrieve service model information from cache (and manage the cache)
+    // The cache object is static but most of these methods are not because the same service definition, is used with different
+    // DispatchContext objects may result in different in/out attributes: this happens because the DispatchContext is associated to
+    // a LocalDispatcher that is associated to a Delegator that is associated to a ModelReader; different ModelReaders could load the
+    // same entity name from different files with different fields, and the service definition could automatically get the input/output
+    // attributes from an entity.
+
+    /**
      * Uses an existing map of name value pairs and extracts the keys which are used in serviceName
      * Note: This goes not guarantee the context will be 100% valid, there may be missing fields
      * @param serviceName The name of the service to obtain parameters for
@@ -100,7 +156,6 @@ public class DispatchContext implements 
     public Map<String, Object> makeValidContext(String serviceName, String mode, Map<String, ? extends Object> context) throws GenericServiceException {
         ModelService model = getModelService(serviceName);
         return makeValidContext(model, mode, context);
-
     }
 
     /**
@@ -145,19 +200,7 @@ public class DispatchContext implements 
      * @return GenericServiceModel that corresponds to the serviceName
      */
     public ModelService getModelService(String serviceName) throws GenericServiceException {
-        //long timeStart = System.currentTimeMillis();
-        ModelService retVal = getGlobalModelService(serviceName);
-
-        if (retVal == null) {
-            throw new GenericServiceException("Cannot locate service by name (" + serviceName + ")");
-        }
-        //Debug.logTiming("Got ModelService for name [" + serviceName + "] in [" + (System.currentTimeMillis() - timeStart) + "] milliseconds", module);
-        return retVal;
-    }
-
-    private ModelService getGlobalModelService(String serviceName) throws GenericServiceException {
         Map<String, ModelService> serviceMap = getGlobalServiceMap();
-
         ModelService retVal = null;
         if (serviceMap != null) {
             retVal = serviceMap.get(serviceName);
@@ -165,50 +208,25 @@ public class DispatchContext implements 
                 retVal.interfaceUpdate(this);
             }
         }
-
+        if (retVal == null) {
+            throw new GenericServiceException("Cannot locate service by name (" + serviceName + ")");
+        }
         return retVal;
     }
 
-    /**
-     * Gets the LocalDispatcher used with this context
-     * @return LocalDispatcher that was used to create this context
-     */
-    public LocalDispatcher getDispatcher() {
-        return this.dispatcher;
-    }
+    public Set<String> getAllServiceNames() {
+        Set<String> serviceNames = new TreeSet<String>();
 
-    /**
-     * Sets the LocalDispatcher used with this context
-     * @param dispatcher The LocalDispatcher to re-assign to this context
-     */
-    public synchronized void setDispatcher(LocalDispatcher dispatcher) {
-        this.dispatcher = dispatcher;
-        if (this.dispatcher != null) {
-            Delegator delegator = dispatcher.getDelegator();
-            if (delegator != null) {
-                DelegatorInfo delegatorInfo = EntityConfigUtil.getDelegatorInfo(delegator.getDelegatorBaseName());
-                if (delegatorInfo != null) {
-                    this.model = delegatorInfo.entityModelReader;
-                }
-            }
+        Map<String, ModelService> globalServices = modelServiceMapByModel.get(this.model);
+        if (globalServices != null) {
+            serviceNames.addAll(globalServices.keySet());
         }
-        getGlobalServiceMap();
-    }
-
-    /**
-     * Gets the Delegator associated with this context/dispatcher
-     * @return Delegator associated with this context
-     */
-    public Delegator getDelegator() {
-        return dispatcher.getDelegator();
+        return serviceNames;
     }
 
-    /**
-     * Gets the Security object associated with this dispatcher
-     * @return Security object associated with this dispatcher
-     */
-    public Security getSecurity() {
-        return dispatcher.getSecurity();
+    public Document getWSDL(String serviceName, String locationURI) throws GenericServiceException, WSDLException {
+        ModelService model = this.getModelService(serviceName);
+        return model.toWSDL(locationURI);
     }
 
     private Callable<Map<String, ModelService>> createServiceReaderCallable(final ResourceHandler handler) {
@@ -219,7 +237,7 @@ public class DispatchContext implements 
         };
     }
 
-    private synchronized Map<String, ModelService> getGlobalServiceMap() {
+    private Map<String, ModelService> getGlobalServiceMap() {
         Map<String, ModelService> serviceMap = modelServiceMapByModel.get(this.model);
         if (serviceMap == null) {
             serviceMap = FastMap.newInstance();
@@ -260,19 +278,4 @@ public class DispatchContext implements 
         }
         return serviceMap;
     }
-
-    public synchronized Set<String> getAllServiceNames() {
-        Set<String> serviceNames = new TreeSet<String>();
-
-        Map<String, ModelService> globalServices = modelServiceMapByModel.get(this.model);
-        if (globalServices != null) {
-            serviceNames.addAll(globalServices.keySet());
-        }
-        return serviceNames;
-    }
-
-    public Document getWSDL(String serviceName, String locationURI) throws GenericServiceException, WSDLException {
-        ModelService model = this.getModelService(serviceName);
-        return model.toWSDL(locationURI);
-    }
 }

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericDispatcher.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericDispatcher.java?rev=1364564&r1=1364563&r2=1364564&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericDispatcher.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericDispatcher.java Mon Jul 23 10:15:13 2012
@@ -85,13 +85,12 @@ public class GenericDispatcher extends G
         } catch (SecurityException e) {
             loader = this.getClass().getClassLoader();
         }
-        DispatchContext ctx = new DispatchContext(name, loader);
 
         this.name = name;
         this.dispatcher = ServiceDispatcher.getInstance(delegator);
+        DispatchContext ctx = new DispatchContext(name, loader, this);
         this.dispatcher.register(ctx);
         this.ctx = ctx;
-        this.ctx.setDispatcher(this);
         if (Debug.verboseOn()) Debug.logVerbose("[LocalDispatcher] : Created Dispatcher for: " + name, module);
     }
 

Modified: ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java?rev=1364564&r1=1364563&r2=1364564&view=diff
==============================================================================
--- ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java (original)
+++ ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java Mon Jul 23 10:15:13 2012
@@ -140,7 +140,9 @@ public class ArtifactInfoFactory {
         } else {
             modelName = "main";
         }
-        this.dispatchContext = new DispatchContext(modelName, this.getClass().getClassLoader());
+        // since we do not associate a dispatcher to this DispatchContext, it is important to set a name of an existing entity model reader:
+        // in this way it will be possible to retrieve the service models from the cache
+        this.dispatchContext = new DispatchContext(modelName, this.getClass().getClassLoader(), null);
 
         this.prepareAll();
     }

Modified: ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelReferences.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelReferences.java?rev=1364564&r1=1364563&r2=1364564&view=diff
==============================================================================
--- ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelReferences.java (original)
+++ ofbiz/trunk/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelReferences.java Mon Jul 23 10:15:13 2012
@@ -76,7 +76,9 @@ public class LabelReferences {
         } else {
             modelName = "main";
         }
-        this.dispatchContext = new DispatchContext(modelName, this.getClass().getClassLoader());
+        // since we do not associate a dispatcher to this DispatchContext, it is important to set a name of an existing entity model reader:
+        // in this way it will be possible to retrieve the service models from the cache
+        this.dispatchContext = new DispatchContext(modelName, this.getClass().getClassLoader(), null);
         Collection<LabelInfo> infoList = this.labels.values();
         for (LabelInfo labelInfo : infoList) {
             this.labelSet.add(labelInfo.getLabelKey());