You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by su...@apache.org on 2010/12/13 12:06:52 UTC

svn commit: r1045062 - in /synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext: ./ SynapseXpathFunctionContextProvider.java SynapseXpathVariableResolver.java XpathExtensionUtil.java

Author: supun
Date: Mon Dec 13 11:06:52 2010
New Revision: 1045062

URL: http://svn.apache.org/viewvc?rev=1045062&view=rev
Log:
applying patch for issue SYNAPSE-711, many thanks Udayanga for the contribution

Added:
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathFunctionContextProvider.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathVariableResolver.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/XpathExtensionUtil.java

Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathFunctionContextProvider.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathFunctionContextProvider.java?rev=1045062&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathFunctionContextProvider.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathFunctionContextProvider.java Mon Dec 13 11:06:52 2010
@@ -0,0 +1,57 @@
+/*
+ *  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.util.xpath.ext;
+
+import org.apache.synapse.MessageContext;
+import org.jaxen.Function;
+
+import javax.xml.namespace.QName;
+
+/**
+ * <p>This XPath Function Context provider Interface must be implemented when resolving custom
+ * XPath Function contexts .Any xpath function that can't be resolved by
+ * <code>SynapseXPathFunctionContext</code> will be delegated to this interface.
+ * Users should implement this API as well as jaxen based <code>Function</code> API .
+ *
+ * Extensions can be registered in synapse.properties under  synapse.xpath.func.extensions
+ * @see org.jaxen.Function
+ * @see org.apache.synapse.util.xpath.SynapseXPathFunctionContext
+ */
+public interface SynapseXpathFunctionContextProvider {
+
+    /**
+     * This method should implement instatntiation code for custom xpath function for the registered
+     * QNames given by #getResolvingQName().Note that this extension provider is responsible for
+     * initalizing custom xpath function and returning a fresh function instance to Synapse. Callers
+     * should be responsible for invoking the function explicitly.
+     * @see org.jaxen.Function#call(org.jaxen.Context, java.util.List)
+     *
+     * @param msgCtxt Synapse Message Context
+     *
+     * @return extension Function constructed with message
+     */
+     public Function getInitializedExtFunction(MessageContext msgCtxt);
+
+    /**
+     * Should Implement this API to return supported custom expression
+     * @return This should return the supported QName (localname + prefix + namespace URI combination ) for
+     * this extension
+     */
+     public QName getResolvingQName();
+}

Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathVariableResolver.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathVariableResolver.java?rev=1045062&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathVariableResolver.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/SynapseXpathVariableResolver.java Mon Dec 13 11:06:52 2010
@@ -0,0 +1,54 @@
+/*
+ *  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.util.xpath.ext;
+
+import org.apache.synapse.MessageContext;
+import org.jaxen.Function;
+
+import javax.xml.namespace.QName;
+
+/**
+ * <p>This XPath Variable Resolver Interface must be implemented when resolving custom XPath
+ *  Variable contexts
+ * Any xpath function that can't be resolved by <code>SynapseXPathVariableContext</code> will be
+ * delegated to this interface.
+ * Users should implement this API to resolve custom variable contexts
+ * ie:- expression="$Custom_Property_Scope:C_PROPERTY" OR expression="$CUSTOM_RESP/urn:child" , ...
+ *
+ * Extensions can be registered in synapse.properties under  synapse.xpath.var.extensions
+ * @see org.apache.synapse.util.xpath.SynapseXPathVariableContext
+ */
+public interface SynapseXpathVariableResolver {
+
+    /**
+     * This method should implement the resolving code for custom xpath variable for the registered
+     * QName given by #getResolvingQName().
+     * @param msgCtxt Synapse Message Context
+     * @return resolved object for custom xpath variable
+     */
+    public Object resolve(MessageContext msgCtxt);
+
+    /**
+     * Should Implement this API to return supported custom expression
+     * @return This should return the supported QName
+     * (localname + prefix + namespace URI combination ) for this extension
+     */
+    public QName getResolvingQName();
+
+}

Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/XpathExtensionUtil.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/XpathExtensionUtil.java?rev=1045062&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/XpathExtensionUtil.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/util/xpath/ext/XpathExtensionUtil.java Mon Dec 13 11:06:52 2010
@@ -0,0 +1,211 @@
+/*
+ *  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.util.xpath.ext;
+
+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.config.SynapsePropertiesLoader;
+import org.jaxen.Function;
+
+import javax.xml.namespace.QName;
+import java.util.*;
+
+/**
+ * Utility class to support custom xpath context extensions
+ */
+public class XpathExtensionUtil {
+    /** The Synapse extension property for variable context extensions */
+    private static final String SYNAPSE_XPATH_VARIABLE_EXTENSIONS = "synapse.xpath.var.extensions";
+
+    /** The Synapse extension property for function context extensions */
+    private static final String SYNAPSE_XPATH_FUNCTION_EXTENSIONS = "synapse.xpath.func.extensions";
+
+    private static final Log log = LogFactory.getLog(XpathExtensionUtil.class);
+
+    /**
+     * Get all registered variable context extensions. Synapse will look for synapse.properties
+     * property synapse.xpath.var.extensions
+     * @return List of Synapse Xpath Variable Context Providers
+     */
+    public static List<SynapseXpathVariableResolver> getRegisteredVariableExtensions() {
+        Properties synapseProps = SynapsePropertiesLoader.loadSynapseProperties();
+        String propValue = synapseProps.getProperty(SYNAPSE_XPATH_VARIABLE_EXTENSIONS);
+        List<SynapseXpathVariableResolver> extProviders = new
+                ArrayList<SynapseXpathVariableResolver>();
+        extractProviders(propValue, extProviders);
+        return extProviders;
+    }
+
+    /**
+     * Get all registered function context extensions. Synapse will look for synapse.properties
+     * property synapse.xpath.func.extensions
+     * @return List of Synapse Xpath Function Context Providers
+     */
+    public static List<SynapseXpathFunctionContextProvider> getRegisteredFunctionExtensions() {
+        Properties synapseProps = SynapsePropertiesLoader.loadSynapseProperties();
+        String propValue = synapseProps.getProperty(SYNAPSE_XPATH_FUNCTION_EXTENSIONS);
+        List<SynapseXpathFunctionContextProvider> extProviders = new
+                ArrayList<SynapseXpathFunctionContextProvider>();
+        extractProviders(propValue, extProviders);
+        return extProviders;
+    }
+
+    /**
+     * Populate the set of registered  Extension proiders for a given property
+     * @param propValue  either variable/function provider property name
+     * @param extProviders  a List that will be populated with the registered extensions
+     * @param <T> Variable/Function Context Provider Type
+     */
+    private static <T> void extractProviders(String propValue, List<T> extProviders) {
+        if (propValue != null) {
+            String[] observerNames = propValue.split(",");
+            for (String observer : observerNames) {
+                try {
+                    Class clazz = XpathExtensionUtil.class.getClassLoader().
+                            loadClass(observer.trim());
+                    T obj = (T) clazz.newInstance();
+                    extProviders.add(obj);
+                } catch (Exception e) {
+                    handleException("Error while initializing Synapse Xpath extension providers", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Fucntion Context extension registered for given QName/namespaceURI+prefix+localName
+     * combination
+     * @param ctxt  Synapse Message Context
+     * @param namespaceURI binding namespace in xpath expression
+     * @param prefix binding prefix string in xpath expression
+     * @param localName binding localname string in xpath expression
+     * @return jaxen Function object for corresponding extension
+     */
+    public static Function getFunctionContext(MessageContext ctxt, String namespaceURI,String prefix,
+                                           String localName) {
+        Map<QName, SynapseXpathFunctionContextProvider> extensions =
+                ctxt.getEnvironment().getXpathFunctionExtensions();
+        SynapseXpathFunctionContextProvider functionContextProvider =
+                getMatchingExtensionProvider(extensions, namespaceURI, prefix, localName);
+        if (functionContextProvider!=null) {
+            return initAndReturnXpathFunction(functionContextProvider,ctxt);
+        }
+        return null;
+    }
+
+    /**
+     * Returns an object resolved by Variable Context extension registered for given
+     * QName/namespaceURI+prefix+localName combination
+     * @param ctxt  Synapse Message Context
+     * @param namespaceURI binding namespace in xpath expression
+     * @param prefix binding prefix string in xpath expression
+     * @param localName binding localname string in xpath expression
+     * @return Object variable resolved by corresponding extension
+     */
+    public static Object resolveVariableContext(MessageContext ctxt, String namespaceURI,String prefix,
+                                         String localName) {
+        Map<QName, SynapseXpathVariableResolver> extensions =
+                ctxt.getEnvironment().getXpathVariableExtensions();
+        SynapseXpathVariableResolver variableResolver = getMatchingExtensionProvider(extensions, namespaceURI, prefix, localName);
+        if (variableResolver !=null) {
+            return resolveXpathVariable(variableResolver,ctxt);
+        }
+        return null;
+    }
+
+    /**
+     * returns the matching Extension provider for a given QName/namespaceURI+prefix+localName
+     * combination
+     * @param extensionMap registered extension Map for the corresponding extension provider
+     * @param namespaceURI binding namespace in xpath expression
+     * @param prefix binding prefix string in xpath expression
+     * @param localName binding localname string in xpath expression
+     * @param <T> Variable/Function Context Provider Type
+     * @return matching Extension provider. returns null if no extension is found for the given
+     * combination
+     */
+    private static <T> T getMatchingExtensionProvider(Map<QName,T> extensionMap ,String namespaceURI,
+                                                      String prefix,String localName){
+        QName subject;
+        if (localName != null && prefix != null) {
+            subject = new QName(namespaceURI, localName, prefix);
+        } else if (localName != null) {
+            subject = new QName(namespaceURI, localName);
+        } else {
+            //can't resolve xpath extensions - invalid combination
+            return null;
+        }
+
+        Set<QName> qNames = extensionMap.keySet();
+        for (QName qName : qNames) {
+            //check for a match for the given combination for QName registered
+            if (subject.equals(qName)) {
+                return extensionMap.get(qName);
+            }
+        }
+        //no match found
+        return null;
+
+    }
+
+    /**
+     * try to resolve an xpath variable context using the extension given
+     * @param variableExt Extension provider for variable contexts
+     * @param ctxt Synapse Message Context
+     * @return resolved property/object
+     */
+    private static Object resolveXpathVariable(SynapseXpathVariableResolver variableExt,
+                                              MessageContext ctxt) {
+        try {
+            return variableExt.resolve(ctxt);
+        } catch (Exception e) {
+            handleExceptionWarning("Error Invoking Xpath Variable Provider " +
+                                   variableExt.getClass().getName(), e);
+        }
+        return null;
+    }
+
+    /**
+     * Initializes an returns new Xpath Function
+     * @param funcExtProvider extension provider for a Function Context
+     * @param ctxt Synapse Message Context
+     * @return Xpath Function instance . returns null if error occurs
+     */
+    private static Function initAndReturnXpathFunction(SynapseXpathFunctionContextProvider funcExtProvider,
+                                                       MessageContext ctxt) {
+        try {
+            return funcExtProvider.getInitializedExtFunction(ctxt);
+        } catch (Exception e) {
+            handleExceptionWarning("Error Initializing Xpath Function Provider " +
+                                   funcExtProvider.getClass().getName(), e);
+        }
+        return null;
+    }
+
+    private static void handleException(String msg, Exception e) {
+        log.warn(msg, e);
+        throw new SynapseException(msg, e);
+    }
+
+    private static void handleExceptionWarning(String msg, Exception e) {
+        log.warn(msg, e);
+    }
+}