Author: supun
Date: Wed Jan 19 16:39:42 2011
New Revision: 1060856

URL: http://svn.apache.org/viewvc?rev=1060856&view=rev
Log:
adding dynamic key support for registry entries

Added:
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/Key.java
Modified:
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/MediatorProperty.java
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
    
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java

Added: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/Key.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/Key.java?rev=1060856&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/Key.java
 (added)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/Key.java
 Wed Jan 19 16:39:42 2011
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.synapse.mediators;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.MessageContext;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.util.xpath.SynapseXPath;
+
+/**
+ * Represents a Key
+ * Handling both static and dynamic(Xpath) keys.
+ * User can give Xpath expression as a key and derive
+ * real key based on message context
+ */
+public class Key {
+    private static final Log log = LogFactory.getLog(Key.class);
+    /**
+     * The static key value or generated key value for dynamic key
+     */
+    private String keyValue = null;
+    /**
+     * the dynamic key
+     */
+    private SynapseXPath expression = null;
+
+    /**
+     * Create a key instance using a static key
+     *
+     * @param staticKey static key
+     */
+    public Key(String staticKey) {
+        this.keyValue = staticKey;
+    }
+
+    /**
+     * Create a key instance using a dynamic key (Xpath Expression)
+     *
+     * @param expression SynapseXpath for dynamic key
+     */
+    public Key(SynapseXPath expression) {
+        this.expression = expression;
+    }
+
+    /**
+     * Retrieving static key
+     *
+     * @return static key
+     */
+    public String getKeyValue() {
+        return keyValue;
+    }
+
+    /**
+     * Retrieving dynamic key
+     *
+     * @return SynapseXpath
+     */
+    public SynapseXPath getExpression() {
+        return expression;
+    }
+
+    /**
+     * Evaluating key based on message context
+     * used when key is a xpath expression
+     *
+     * @param synCtx message context
+     * @return string value of evaluated key
+     */
+    public String evaluateKey(MessageContext synCtx) {
+        if (keyValue != null) {
+            //if static kry: return static key
+            return keyValue;
+        } else if (expression != null) {
+            //if dynamic key: set key value and return key value
+            keyValue = expression.stringValueOf(synCtx);
+            return keyValue;
+        } else {
+            handleException("Can not evaluate the key: " +
+                            "key should be static or dynamic key");
+            return null;
+        }
+
+    }
+
+    /**
+     * Handle exceptions
+     *
+     * @param msg error message
+     */
+    private void handleException(String msg) {
+        log.error(msg);
+        throw new SynapseException(msg);
+    }
+}
+
+

Modified: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/MediatorProperty.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/MediatorProperty.java?rev=1060856&r1=1060855&r2=1060856&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/MediatorProperty.java
 (original)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/MediatorProperty.java
 Wed Jan 19 16:39:42 2011
@@ -35,7 +35,6 @@ import java.util.Map;
  * against the current message into literal String values.
  */
 public class MediatorProperty {
-
     // TODO: these constants are related to a specific configuration language
     //       and should be moved to a class in the related package
     public static final QName PROPERTY_Q  = new 
QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "property");
@@ -52,6 +51,10 @@ public class MediatorProperty {
 
     public MediatorProperty() {}
 
+    /**
+     *
+     * @param synCtx
+     */
     public void evaluate(MessageContext synCtx) {
         String result;
         if (value != null) {

Modified: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java?rev=1060856&r1=1060855&r2=1060856&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
 (original)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/elementary/Target.java
 Wed Jan 19 16:39:42 2011
@@ -63,9 +63,8 @@ public class Target {
 
     public static final String ACTION_ADD_CHILD = "child";
 
-    public static final String ACTION_ADD_SIBLING = "sibiling";
+    public static final String ACTION_ADD_SIBLING = "sibling";
 
-    //private boolean replace = true;
     private String action = ACTION_REPLACE;
 
     public void insert(MessageContext synContext,

Modified: 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java?rev=1060856&r1=1060855&r2=1060856&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
 (original)
+++ 
synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/transform/XSLTMediator.java
 Wed Jan 19 16:39:42 2011
@@ -30,15 +30,9 @@ import org.apache.synapse.config.Entry;
 import org.apache.synapse.config.SynapseConfigUtils;
 import org.apache.synapse.core.SynapseEnvironment;
 import org.apache.synapse.mediators.AbstractMediator;
+import org.apache.synapse.mediators.Key;
 import org.apache.synapse.mediators.MediatorProperty;
-import org.apache.synapse.util.jaxp.DOOMResultBuilderFactory;
-import org.apache.synapse.util.jaxp.DOOMSourceBuilderFactory;
-import org.apache.synapse.util.jaxp.ResultBuilder;
-import org.apache.synapse.util.jaxp.ResultBuilderFactory;
-import org.apache.synapse.util.jaxp.SourceBuilder;
-import org.apache.synapse.util.jaxp.SourceBuilderFactory;
-import org.apache.synapse.util.jaxp.StreamResultBuilderFactory;
-import org.apache.synapse.util.jaxp.StreamSourceBuilderFactory;
+import org.apache.synapse.util.jaxp.*;
 import org.apache.synapse.util.resolver.CustomJAXPURIResolver;
 import org.apache.synapse.util.resolver.ResourceMap;
 import org.apache.synapse.util.xpath.SourceXPathSupport;
@@ -46,9 +40,7 @@ import org.apache.synapse.util.xpath.Syn
 
 import javax.xml.transform.*;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 
 /**
  * The XSLT mediator performs an XSLT transformation requested, using
@@ -115,9 +107,10 @@ public class XSLTMediator extends Abstra
         
"http://synapse.apache.org/ns/2010/04/configuration/transform/attribute/rbf";;
     
     /**
-     * The resource key/name which refers to the XSLT to be used for the 
transformation
+     * The resource key which refers to the XSLT to be used for the 
transformation
+     * supports both static and dynamic(xpath) keys
      */
-    private String xsltKey = null;
+    private Key xsltKey = null;
 
     /**
      * The (optional) XPath expression which yields the source element for a 
transformation
@@ -151,11 +144,11 @@ public class XSLTMediator extends Abstra
     private ResourceMap resourceMap;
 
     /**
+     * Cache multiple templates
+     * Unique string used as a key for each template
      * The Template instance used to create a Transformer object. This is  
thread-safe
-     *
-     * @see javax.xml.transform.Templates
      */
-    private Templates cachedTemplates = null;
+    private Map<String, Templates> cachedTemplatesMap = new Hashtable<String, 
Templates>();
 
     /**
      * The TransformerFactory instance which use to create Templates. This is 
not thread-safe.
@@ -219,6 +212,12 @@ public class XSLTMediator extends Abstra
         boolean isSoapEnvelope = (sourceNode == synCtx.getEnvelope());
         boolean isSoapBody = (sourceNode == synCtx.getEnvelope().getBody());
 
+        // Derive actual key from message context
+        String generatedXsltKey = xsltKey.evaluateKey(synCtx);
+
+        // get templates from generatedXsltKey
+        Templates cachedTemplates = null;
+
         if (synLog.isTraceTraceEnabled()) {
             synLog.traceTrace("Transformation source : " + 
sourceNode.toString());
         }
@@ -229,14 +228,25 @@ public class XSLTMediator extends Abstra
             synchronized (transformerLock) {
                 // only first thread should create the template
                 if (isCreationOrRecreationRequired(synCtx)) {
-                    createTemplate(synCtx, synLog);
+                    cachedTemplates = createTemplate(synCtx, synLog);
                 }
             }
         }
+        else{
+            //If already cached template then load it from cachedTemplatesMap
+            synchronized (transformerLock){
+                cachedTemplates = cachedTemplatesMap.get(generatedXsltKey);
+            }
+        }
 
         try {
             // perform transformation
-            Transformer transformer = cachedTemplates.newTransformer();
+            Transformer transformer = null;
+            try {
+                transformer = cachedTemplates.newTransformer();
+            } catch (NullPointerException ex) {
+                handleException("Unable to create Transformer using cached 
template", ex, synCtx);
+            }
             if (!properties.isEmpty()) {
                 // set the parameters which will pass to the Transformation
                 applyProperties(transformer, synCtx, synLog);
@@ -337,38 +347,56 @@ public class XSLTMediator extends Abstra
      * Create a XSLT template object and assign it to the cachedTemplates 
variable
      * @param synCtx current message
      * @param synLog logger to use
+     * @return cached template
      */
-    private void createTemplate(MessageContext synCtx, SynapseLog synLog) {
+    private Templates createTemplate(MessageContext synCtx, SynapseLog synLog) 
{
+        // Assign created template
+        Templates cachedTemplates = null;
+
         // Set an error listener (SYNAPSE-307).
         transFact.setErrorListener(new ErrorListenerImpl(synLog, "stylesheet 
parsing"));
         // Allow xsl:import and xsl:include resolution
         transFact.setURIResolver(new CustomJAXPURIResolver(resourceMap,
                 synCtx.getConfiguration()));
+        // Derive actual key from message context
+        String generatedXsltKey = xsltKey.evaluateKey(synCtx);
+
         try {
             cachedTemplates = transFact.newTemplates(
-                    
SynapseConfigUtils.getStreamSource(synCtx.getEntry(xsltKey)));
+                    
SynapseConfigUtils.getStreamSource(synCtx.getEntry(generatedXsltKey)));
             if (cachedTemplates == null) {
+                // if cached template creation failed
                 handleException("Error compiling the XSLT with key : " + 
xsltKey, synCtx);
+            } else {
+                // if cached template is created then put it in to 
cachedTemplatesMap
+                cachedTemplatesMap.put(generatedXsltKey, cachedTemplates);
             }
         } catch (Exception e) {
             handleException("Error creating XSLT transformer using : " + 
xsltKey, e, synCtx);
         }
+        return cachedTemplates;
     }
 
     /**
      * Utility method to determine weather it is needed to create a XSLT 
template
+     *
      * @param synCtx current message
      * @return true if it is needed to create a new XSLT template
      */
     private boolean isCreationOrRecreationRequired(MessageContext synCtx) {
 
-        // if there are no cachedTemplates we need to create a one
-        if (cachedTemplates == null) {
+        // Derive actual key from message context
+        String generatedXsltKey = xsltKey.evaluateKey(synCtx);
+
+        // if there are no cachedTemplates inside cachedTemplatesMap or
+        // if the template related to this generated key is not cached
+        // then it need to be cached
+        if (cachedTemplatesMap.isEmpty() || 
!cachedTemplatesMap.containsKey(generatedXsltKey)) {
             // this is a creation case
             return true;
         } else {
             // build transformer - if necessary
-            Entry dp = synCtx.getConfiguration().getEntryDefinition(xsltKey);
+            Entry dp = 
synCtx.getConfiguration().getEntryDefinition(generatedXsltKey);
             // if the xsltKey refers to a dynamic resource, and if it has been 
expired
             // it is a recreation case
             return dp != null && dp.isDynamic() && (!dp.isCached() || 
dp.isExpired());
@@ -383,11 +411,11 @@ public class XSLTMediator extends Abstra
         this.source.setXPath(source);
     }
 
-    public String getXsltKey() {
+    public Key getXsltKey() {
         return xsltKey;
     }
 
-    public void setXsltKey(String xsltKey) {
+    public void setXsltKey(Key xsltKey) {
         this.xsltKey = xsltKey;
     }
 


Reply via email to