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;
}