You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@synapse.apache.org by as...@apache.org on 2006/07/14 14:28:28 UTC

svn commit: r421891 - in /incubator/synapse/trunk/java/modules: core/src/org/apache/synapse/config/ core/src/org/apache/synapse/config/xml/ core/src/org/apache/synapse/core/axis2/ core/src/org/apache/synapse/registry/ core/src/org/apache/synapse/regist...

Author: asankha
Date: Fri Jul 14 05:28:27 2006
New Revision: 421891

URL: http://svn.apache.org/viewvc?rev=421891&view=rev
Log:
Checkin initial support for a registry
Validate mediator is updated to support the registry concept

Added:
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/DynamicProperty.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/Util.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/XMLToObjectMapper.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/RegistryFactory.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/AbstractRegistry.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/Registry.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/RegistryEntry.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/SimpleURLRegistry.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/URLRegistryEntry.java
    incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/
    incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/
    incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/SimpleURLRegistryTest.java
Modified:
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/SynapseConfiguration.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/Constants.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/XMLConfigurationBuilder.java
    incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/core/axis2/ProxyService.java
    incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/mediators/TestUtils.java
    incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediator.java
    incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediatorFactory.java
    incubator/synapse/trunk/java/modules/extensions/test/org/apache/synapse/ValidateMediatorTest.java

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/DynamicProperty.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/DynamicProperty.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/DynamicProperty.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/DynamicProperty.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,89 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.config;
+
+/**
+ * A DynamicProperty is a Synapse (global) property (defined within the 'definitions'
+ * section) of a SynapseConfiguration. However, these properties are implicitly
+ * tied to a Registry, and will be automatically refreshed after a cacheable lease
+ * expires for such a property. The cachable duration for each property is given
+ * by the registry when the RegistryEntry for a property is requested. This duration
+ * can change while the property is being used, and will be refreshed at each
+ * cache expiry. However, the resource will be loaded, iff the RegistryEntry returned
+ * after a cache expiry as a version later than the version cached. Else, the
+ * existing cache of the resource will be renewed for a further period, as stated by
+ * the new RegistryEntry lookup.
+ */
+public class DynamicProperty {
+    /** The registry key */
+    private String key;
+    /** The cached object */
+    private Object cache = null;
+    /** An XML to Object mapper - if one is available */
+    private XMLToObjectMapper mapper = null;
+    /** The version of the cached resource */
+    private long version;
+    /** The local expiry time for the cached resource */
+    private long expiryTime;
+
+    public DynamicProperty(String key) {
+        this.key = key;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public Object getCache() {
+        return cache;
+    }
+
+    public void setCache(Object cache) {
+        this.cache = cache;
+    }
+
+    public XMLToObjectMapper getMapper() {
+        return mapper;
+    }
+
+    public void setMapper(XMLToObjectMapper mapper) {
+        this.mapper = mapper;
+    }
+
+    public long getExpiryTime() {
+        return expiryTime;
+    }
+
+    public void setExpiryTime(long expiryTime) {
+        this.expiryTime = expiryTime;
+    }
+
+    public boolean isExpired() {
+        return System.currentTimeMillis() > expiryTime;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long version) {
+        this.version = version;
+    }
+}

Modified: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/SynapseConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/SynapseConfiguration.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/SynapseConfiguration.java (original)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/SynapseConfiguration.java Fri Jul 14 05:28:27 2006
@@ -17,6 +17,7 @@
 
 import org.apache.synapse.api.Mediator;
 import org.apache.synapse.core.axis2.ProxyService;
+import org.apache.synapse.registry.Registry;
 
 import java.util.*;
 
@@ -40,6 +41,9 @@
     /** Holds global (system-wide) properties that apply to the synapse instance and every message */
     private Map globalProps = new HashMap();
 
+    /** Hold referenced to the declared registries */
+    private Map registryMap = new HashMap();
+
     /** This is the "main" (or default) synapse mediator which mediates each and every message */
     private Mediator mainMediator = null;
 
@@ -157,6 +161,30 @@
      */
     public Map getGlobalProps() {
         return globalProps;
+    }
+
+    /**
+     * Add a registry into this configuration with the given name
+     * @param name a name for the registry or null for default registry
+     * @param reg the actual registry implementation
+     */
+    public void addRegistry(String name, Registry reg) {
+        if (name == null) {
+            name = "DEFAULT";
+        }
+        registryMap.put(name, reg);
+    }
+
+    /**
+     * Get the named registry, or the default if name is null
+     * @param name registry name or null - for default registry
+     * @return actual registry for the given name or the default registry
+     */
+    public Registry getRegistry(String name) {
+        if (name == null) {
+            name = "DEFAULT";
+        }
+        return (Registry) registryMap.get(name);
     }
 
 }

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/Util.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/Util.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/Util.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/Util.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,126 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.config;
+
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.synapse.SynapseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
+import org.apache.ws.commons.schema.XmlSchemaObject;
+
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+
+public class Util {
+
+    private static final Log log = LogFactory.getLog(Util.class);
+
+    /**
+     * Return a StreamSource for the given Object
+     * @param o the object
+     * @return the StreamSource
+     */
+    public static StreamSource getStreamSource(Object o) {
+
+        if (o instanceof OMNode) {
+            OMNode omNode = (OMNode) o;
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try {
+                omNode.serialize(baos);
+                return new StreamSource(new ByteArrayInputStream(baos.toByteArray()));
+            } catch (XMLStreamException e) {
+                handleException("Error converting to a StreamSource", e);
+            }
+            
+        } else {
+            handleException("Cannot convert object to a StreamSource");
+        }
+        return null;
+    }
+
+    /**
+     * Get an object from a given URL. Will first fetch the content from the
+     * URL and depending on the content-type, a suitable XMLToObjectMapper
+     * (if available) would be used to transform this content into an Object.
+     * If a suitable XMLToObjectMapper cannot be found, the content would be
+     * treated as XML and an OMNode would be returned
+     * @param url the URL to the resource
+     * @return an Object created from the given URL
+     */
+    public static Object getObject(URL url) {
+        try {
+            URLConnection urlc = url.openConnection();
+            XMLToObjectMapper xmlToObject =
+                getXmlToObjectMapper(urlc.getContentType());
+
+            try {
+                XMLStreamReader parser = XMLInputFactory.newInstance().
+                    createXMLStreamReader(urlc.getInputStream());
+                StAXOMBuilder builder = new StAXOMBuilder(parser);
+                OMElement omElem =  builder.getDocumentElement();
+
+                // detach from URL connection and keep in memory
+                omElem.build();
+
+                if (xmlToObject != null) {
+                    return xmlToObject.getObjectFromOMNode(omElem);
+                } else {
+                    return omElem;
+                }
+
+            } catch (XMLStreamException e) {
+                log.warn("Content at URL : " + url + " is non XML..");
+                return urlc.getContent();
+            }
+
+        } catch (IOException e) {
+            handleException("Error connecting to URL : " + url, e);
+        }
+        return null;
+    }
+
+    private static void handleException(String msg, Exception e) {
+        log.error(msg, e);
+        throw new SynapseException(msg, e);
+    }
+
+    private static void handleException(String msg) {
+        log.error(msg);
+        throw new SynapseException(msg);
+    }
+
+    /**
+     * Return a suitable XMLToObjectMapper for the given content type if one
+     * is available, else return null;
+     * @param contentType the content type for which a mapper is required
+     * @return a suitable XMLToObjectMapper or null if none can be found
+     */
+    public static XMLToObjectMapper getXmlToObjectMapper(String contentType) {
+        return null;
+    }
+}

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/XMLToObjectMapper.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/XMLToObjectMapper.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/XMLToObjectMapper.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/XMLToObjectMapper.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,32 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.config;
+
+import org.apache.axiom.om.OMNode;
+
+/**
+ * Defines the interface which should be implemented by a mapper that could
+ * convert a XML resource into a known Object such as WSDL, XSD, etc..
+ */
+public interface XMLToObjectMapper {
+
+    /**
+     * Create an application object from the given OMNode
+     * @param om the XML
+     * @return a suitable application object
+     */
+    public Object getObjectFromOMNode(OMNode om);
+}

Modified: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/Constants.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/Constants.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/Constants.java (original)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/Constants.java Fri Jul 14 05:28:27 2006
@@ -26,6 +26,7 @@
     public static final QName ENDPOINT_ELT      = new QName(Constants.SYNAPSE_NAMESPACE, "endpoint");
     public static final QName PROPERTY_ELT      = new QName(Constants.SYNAPSE_NAMESPACE, "set-property");
     public static final QName RULES_ELT         = new QName(Constants.SYNAPSE_NAMESPACE, "rules");
+    public static final QName REGISTRY_ELT      = new QName(Constants.SYNAPSE_NAMESPACE, "registry");
     public static final QName PROXIES_ELT       = new QName(Constants.SYNAPSE_NAMESPACE, "proxies");
     public static final QName PROXY_ELT         = new QName(Constants.SYNAPSE_NAMESPACE, "proxy");
 

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/RegistryFactory.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/RegistryFactory.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/RegistryFactory.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/RegistryFactory.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,105 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.config.xml;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMAttribute;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.registry.Registry;
+
+import javax.xml.namespace.QName;
+import java.util.Iterator;
+
+/**
+ * Create an instance of the given registry, and sets properties on it.
+ *
+ * <registry [name="string"] provider="provider.class">
+ *   <property name="string" value="string">
+ * </registry>
+ */
+public class RegistryFactory {
+
+    private static final Log log = LogFactory.getLog(RegistryFactory.class);
+
+    public static final QName PROVIDER_Q = new QName(Constants.NULL_NAMESPACE, "provider");
+    public static final QName PROPERTY_Q = new QName(Constants.NULL_NAMESPACE, "property");
+    public static final QName NAME_Q     = new QName(Constants.NULL_NAMESPACE, "name");
+    public static final QName VALUE_Q    = new QName(Constants.NULL_NAMESPACE, "value");
+
+    public static Registry createRegistry(OMElement elem) {
+
+        OMAttribute prov = elem.getAttribute(PROVIDER_Q);
+        if (prov != null) {
+            try {
+                Class provider = Class.forName(prov.getAttributeValue());
+                Registry registry = (Registry) provider.newInstance();
+                setProperties(registry, elem);
+
+                OMAttribute name = elem.getAttribute(NAME_Q);
+                if (name != null) {
+                    registry.setRegistryName(name.getAttributeValue());
+                }
+                return registry;
+
+            } catch (ClassNotFoundException e) {
+                handleException("Cannot locate registry provider class : " +
+                    prov.getAttributeValue(), e);
+            } catch (IllegalAccessException e) {
+                handleException("Error instantiating registry provider : " +
+                    prov.getAttributeValue(), e);
+            } catch (InstantiationException e) {
+                handleException("Error instantiating registry provider : " +
+                    prov.getAttributeValue(), e);
+            }
+        } else {
+            handleException("The registry 'provider' attribute is required for a registry definition");
+        }
+
+        return null;
+    }
+
+    private static void setProperties(Registry reg, OMElement elem) {
+        Iterator iter = elem.getChildrenWithName(PROPERTY_Q);
+        while (iter.hasNext()) {
+            Object o = iter.next();
+            if (o instanceof OMElement) {
+                OMElement propEle = (OMElement) o;
+                OMAttribute nAtt = propEle.getAttribute(NAME_Q);
+                OMAttribute vAtt = propEle.getAttribute(VALUE_Q);
+                if (nAtt != null && vAtt !=null) {
+                    reg.setConfigProperty(nAtt.getAttributeValue(), vAtt.getAttributeValue());
+                } else {
+                    handleException("The 'name' and 'value' attributes are required for a " +
+                        "registry property definition");
+                }
+            } else {
+                handleException("Invalid 'property' definition for registry.");
+            }
+        }
+    }
+
+    private static void handleException(String msg) {
+        log.error(msg);
+        throw new SynapseException(msg);
+    }
+
+    private static void handleException(String msg, Exception e) {
+        log.error(msg, e);
+        throw new SynapseException(msg, e);
+    }
+}

Modified: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/XMLConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/XMLConfigurationBuilder.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/XMLConfigurationBuilder.java (original)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/config/xml/XMLConfigurationBuilder.java Fri Jul 14 05:28:27 2006
@@ -20,9 +20,11 @@
 import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.synapse.SynapseException;
+import org.apache.synapse.registry.Registry;
 import org.apache.synapse.core.axis2.ProxyService;
 import org.apache.synapse.config.SynapseConfiguration;
 import org.apache.synapse.config.Endpoint;
+import org.apache.synapse.config.DynamicProperty;
 import org.apache.synapse.mediators.base.SequenceMediator;
 import org.apache.synapse.mediators.base.SynapseMediator;
 import org.apache.commons.logging.Log;
@@ -107,6 +109,19 @@
             }
         }
 
+        Iterator regs = root.getChildrenWithName(Constants.REGISTRY_ELT);
+        if (regs != null) {
+            while (regs.hasNext()) {
+                Object o = regs.next();
+                if (o instanceof OMElement) {
+                    Registry reg = RegistryFactory.createRegistry((OMElement) o);
+                    config.addRegistry(reg.getRegistryName(), reg);
+                } else {
+                    handleException("Invalid registry declaration in configuration");
+                }
+            }
+        }
+
         if (is != null) {
             try {
                 is.close();
@@ -125,10 +140,47 @@
     private void defineProperty(SynapseConfiguration config, OMElement elem) {
         OMAttribute name  = elem.getAttribute(new QName(Constants.NULL_NAMESPACE, "name"));
         OMAttribute value = elem.getAttribute(new QName(Constants.NULL_NAMESPACE, "value"));
-        if (name == null || value == null) {
-            handleException("The 'name' and 'value' attributes are required");
+        OMAttribute src   = elem.getAttribute(new QName(Constants.NULL_NAMESPACE, "src"));
+        OMAttribute key   = elem.getAttribute(new QName(Constants.NULL_NAMESPACE, "key"));
+        if (name == null) {
+            handleException("The 'name' attribute is required for a property definition");
+        } else if (
+            (value != null && src != null) ||
+            (value != null && key != null) ||
+            (src != null && key != null)) {
+            // if more than one attribute of (value|src|key) is specified
+            handleException("A property must use exactly one of 'value', " +
+                "'src' or 'key' attributes");
+
+        } else if (value == null && src == null && key == null) {
+            // if no attribute of (value|src|key) is specified, check if this is a TextNode
+            if (elem.getFirstOMChild() != null) {
+                config.addProperty(name.getAttributeValue(), elem.getFirstOMChild());
+            } else {
+                handleException("A property must use exactly one of 'value', " +
+                    "'src' or 'key' attributes");
+            }
+        }
+
+        // a simple string literal property
+        if (value != null) {
+            config.addProperty(name.getAttributeValue(), value.getAttributeValue());
+
+        // a property (XML) loaded once through the given URL as an OMNode
+        } else if (src != null) {
+            try {
+                config.addProperty(name.getAttributeValue(),
+                    org.apache.synapse.config.Util.getObject(new URL(src.getAttributeValue())));
+            } catch (MalformedURLException e) {
+                handleException("Invalid URL specified by 'src' attribute : " +
+                    src.getAttributeValue(), e);
+            }
+
+        // a DynamicProperty which refers to an XML resource on a remote registry
+        } else if (key != null) {
+            config.addProperty(name.getAttributeValue(),
+                new DynamicProperty(key.getAttributeValue()));
         }
-        config.addProperty(name.getAttributeValue(), value.getAttributeValue());
     }
 
     /**

Modified: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/core/axis2/ProxyService.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/core/axis2/ProxyService.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/core/axis2/ProxyService.java (original)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/core/axis2/ProxyService.java Fri Jul 14 05:28:27 2006
@@ -103,7 +103,7 @@
             for (int i=0; i<st.countTokens(); i++) {
                 transportList.add(st.nextToken());
             }
-            proxyService.setExposedTransports(transportList);
+            proxyService.setExposeTransports((String[])transportList.toArray());
         }
 
         // process parameters

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/AbstractRegistry.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/AbstractRegistry.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/AbstractRegistry.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/AbstractRegistry.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,155 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry;
+
+import org.apache.axiom.om.OMNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.synapse.config.XMLToObjectMapper;
+import org.apache.synapse.config.DynamicProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.net.URI;
+
+/**
+ * Implements the core Registry lookup algorithm
+ */
+public abstract class AbstractRegistry implements Registry {
+
+    private static final Log log = LogFactory.getLog(AbstractRegistry.class);
+
+    /** A local cache of Objects */
+    protected Map localCache = new HashMap();
+
+    /** The name of the registry */
+    protected String name = null;
+
+    /**
+     * Get the object for the given key from this registry
+     * @param key the key for the registry lookup
+     * @return the matching object
+     */
+    public Object getProperty(String key) {
+
+        DynamicProperty dp = null;
+
+        // check local cache for the given key
+        Object obj = localCache.get(key);
+
+        if (obj != null) {
+            // if the local cache contains an object which is not a DynamicProperty, return it
+            if (!(obj instanceof DynamicProperty)) {
+                log.debug("Returning non dynamic object from cache for key : " + key);
+                return obj;
+
+            } else {
+                log.debug("Cache contains DynamicProperty for key : " + key);
+                dp = (DynamicProperty) obj;
+            }
+
+        } else {
+            log.debug("Object not available in local registry cache for key : " + key);
+        }
+
+        OMNode omNode = null;
+        RegistryEntry re = null;
+
+        // we are dealing with a DynamicProperty. Have we seen this before and processed
+        // it at least once and have it in the localCache?
+        if (dp != null) {
+            // if we have an unexpired cached copy, return the cached object
+            if (!dp.isExpired() && dp.getCache() != null) {
+                return dp.getCache();
+
+            // if we have not cached the referenced object, fetch it and its RegistryEntry
+            } else if (dp.getCache() == null) {
+                omNode = lookup(key);
+                re = getRegistryEntry(key);
+
+            // if we have cached it before, and not the cache has expired
+            // get its *new* registry entry and compare versions and pick new cache duration
+            } else if (dp.isExpired()) {
+
+                log.debug("Cached object has expired for key : " + key);
+                re = getRegistryEntry(key);
+
+                if (re.getVersion() != Long.MIN_VALUE &&
+                    re.getVersion() == dp.getVersion()) {
+                    log.debug("Expired version number is same as current version in registry");
+
+                    // renew cache lease for another cachable duration (as returned by the
+                    // last getRegistryEntry() call
+                    dp.setExpiryTime(
+                        System.currentTimeMillis() + re.getCachableDuration());
+                    log.debug("Renew cache lease for another " + re.getCachableDuration() / 1000 + "s");
+
+                    // return cached object
+                    return dp.getCache();
+
+                } else {
+                    omNode = lookup(key);
+                }
+            }
+
+        } else {
+            log.debug("Processing DynamicProperty for the first time. key : " + key);
+            dp = new DynamicProperty(key);
+            omNode = lookup(key);
+            re = getRegistryEntry(key);
+        }
+
+        // if we get here, we have received the raw omNode from the
+        // registry and our previous copy (if we had one) has expired or is not valid
+
+        // if the type of the object is known to have a mapper, create the
+        // resultant Object using the known mapper, and cache this Object
+        // else cache the raw OMNode
+        if (re != null && re.getType() != null) {
+
+            XMLToObjectMapper mapper = getMapper(re.getType());
+            if (mapper != null) {
+                dp.setMapper(mapper);
+                dp.setCache(mapper.getObjectFromOMNode(omNode));
+
+            } else {
+                dp.setCache(omNode);
+            }
+        }
+
+        // increment cache expiry time as specified by the last getRegistryEntry() call
+        dp.setExpiryTime(
+            System.currentTimeMillis() + re.getCachableDuration());
+        dp.setVersion(re.getVersion());
+
+        // place DynamicProperty in local cache
+        localCache.put(key, dp);
+
+        return dp.getCache();
+    }
+
+    private XMLToObjectMapper getMapper(URI type) {
+        return null;
+    }
+
+    public void setRegistryName(String name) {
+        this.name = name;
+    }
+
+    public String getRegistryName() {
+        return name;
+    }
+}

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/Registry.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/Registry.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/Registry.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/Registry.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,67 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry;
+
+import org.apache.axiom.om.OMNode;
+
+/**
+ * This is the interface to a Registry from Synapse.
+ */
+public interface Registry {
+
+    /**
+     * Perform an actual lookup for for an XML resource as an OMNode for the given key
+     * @param key the key for the registry lookup
+     * @return the XML content from the registry as an OMNode
+     */
+    public OMNode lookup(String key);
+
+    /**
+     * This is the publicly used interface to the registry. It will perform
+     * the lookup on the local cache considering expiry time, and will fetch
+     * the content from the registry and cache when required.
+     * @see AbstractRegistry
+     *
+     * @param key the key for the proprty lookup
+     * @return the value from the registry or local cache
+     */
+    public Object getProperty(String key);
+
+    /**
+     * Get the registry entry for the given key
+     * @return the registry key
+     */
+    public RegistryEntry getRegistryEntry(String key);
+
+    /**
+     * Set a configuration property on the registry. Could be used to initialize a registry
+     * @param name property name
+     * @param value simple String value
+     */
+    public void setConfigProperty(String name, String value);
+
+    /**
+     * Get the name of this registry
+     * @return name of the registry
+     */
+    public String getRegistryName();
+
+    /**
+     * Set the name of this registry
+     * @param name of this registry
+     */
+    public void setRegistryName(String name);
+}

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/RegistryEntry.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/RegistryEntry.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/RegistryEntry.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/RegistryEntry.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,50 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry;
+
+import java.net.URI;
+
+/**
+ * This interface defines the core information to be returned by a Registry implementation
+ * about a resource being managed by it. Every Registry implementation *must* provide valid
+ * information for the methods marked below as 'required'
+ */
+public interface RegistryEntry {
+
+    /** The key for the resource - required */
+    public String getKey();
+
+    /** A name for the resource - optional */
+    public String getName();
+
+    /** The version of the resource - required */
+    public long getVersion();
+
+    /** The type of the resource - optional */
+    public URI getType();
+
+    /** A description for the resource - optional */
+    public String getDescription();
+
+    /** The created time for the resource - optional */
+    public long getCreated();
+
+    /** The last updated time for the resource - optional */
+    public long getLastModified();
+
+    /** The number of milliseconds this resource could be cached */
+    public long getCachableDuration();
+}

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/SimpleURLRegistry.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/SimpleURLRegistry.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/SimpleURLRegistry.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/SimpleURLRegistry.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,111 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry.url;
+
+import org.apache.synapse.registry.Registry;
+import org.apache.synapse.registry.AbstractRegistry;
+import org.apache.synapse.registry.RegistryEntry;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import java.net.*;
+import java.io.IOException;
+
+/**
+ * A Simple HTTP GET based registry which will work with a Web Server / WebDAV
+ *
+ * This saves the root server URL, and appends the a given key to construct the
+ * full URL to locate resources
+ */
+public class SimpleURLRegistry extends AbstractRegistry implements Registry {
+
+    private static final Log log = LogFactory.getLog(SimpleURLRegistry.class);
+
+    /** The root for the URLs */
+    private String root = "";
+
+    /** default cachable duration */
+    private long cachableDuration = 15000;
+
+    public OMNode lookup(String key) {
+
+        log.info("==> Repository fetch of resource with key : " + key);
+        try {
+            URL url = new URL(root + key);
+            URLConnection urlc = url.openConnection();
+
+            XMLStreamReader parser = XMLInputFactory.newInstance().
+                createXMLStreamReader(urlc.getInputStream());
+            StAXOMBuilder builder = new StAXOMBuilder(parser);
+            return builder.getDocumentElement();
+
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (XMLStreamException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public RegistryEntry getRegistryEntry(String key) {
+
+        log.debug("Perform RegistryEntry lookup for key : " + key);
+        try {
+            URL url = new URL(root + key);
+            URLConnection urlc = url.openConnection();
+
+            URLRegistryEntry wre = new URLRegistryEntry();
+            wre.setKey(key);
+            wre.setName(url.getFile());
+            wre.setType(new URI(urlc.getContentType()));
+            wre.setDescription("Resource at : " + url.toString());
+            wre.setLastModified(urlc.getLastModified());
+            wre.setVersion(urlc.getLastModified());
+            if (urlc.getExpiration() > 0) {
+                wre.setCachableDuration(
+                    urlc.getExpiration() - System.currentTimeMillis());
+            } else {
+                wre.setCachableDuration(cachableDuration);
+            }
+            return wre;
+
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public void setConfigProperty(String name, String value) {
+        if ("root".equals(name)) {
+            this.root = value;
+        } else if ("cachableDuration".equals(name)) {
+            this.cachableDuration = Long.parseLong(value);
+        }
+    }
+}

Added: incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/URLRegistryEntry.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/URLRegistryEntry.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/URLRegistryEntry.java (added)
+++ incubator/synapse/trunk/java/modules/core/src/org/apache/synapse/registry/url/URLRegistryEntry.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,112 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry.url;
+
+import org.apache.synapse.registry.RegistryEntry;
+
+import java.net.URI;
+import java.util.Date;
+
+public class URLRegistryEntry implements RegistryEntry {
+
+    private String key = null;
+    private String name = null;
+    private long version = Long.MIN_VALUE;
+    private URI type = null;
+    private String description;
+    private long created;
+    private long lastModified;
+    private long cachableDuration;
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long version) {
+        this.version = version;
+    }
+
+    public URI getType() {
+        return type;
+    }
+
+    public void setType(URI type) {
+        this.type = type;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public long getCreated() {
+        return created;
+    }
+
+    public void setCreated(long created) {
+        this.created = created;
+    }
+
+    public long getLastModified() {
+        return lastModified;
+    }
+
+    public void setLastModified(long lastModified) {
+        this.lastModified = lastModified;
+    }
+
+    public long getCachableDuration() {
+        return cachableDuration;
+    }
+
+    public void setCachableDuration(long cachableDuration) {
+        this.cachableDuration = cachableDuration;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("RegistryEntry {")
+            .append(" Key : " + key)
+            .append(" Name : " + name)
+            .append(" Ver : " + version)
+            .append(" Type : " + type)
+            .append(" Desc : " + description)
+            .append(" Created : " + new Date(created))
+            .append(" Modified : " + new Date(lastModified))
+            .append(" Cacheable for : " + (cachableDuration / 1000) + "sec")
+            .append("}");
+        return sb.toString();
+    }
+}

Modified: incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/mediators/TestUtils.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/mediators/TestUtils.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/mediators/TestUtils.java (original)
+++ incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/mediators/TestUtils.java Fri Jul 14 05:28:27 2006
@@ -17,6 +17,7 @@
 
 import org.apache.synapse.TestMessageContext;
 import org.apache.synapse.MessageContext;
+import org.apache.synapse.registry.url.SimpleURLRegistry;
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.om.OMAbstractFactory;
 import org.apache.axiom.om.OMDocument;
@@ -36,6 +37,9 @@
 
         // create a test synapse context
         TestMessageContext synCtx = new TestMessageContext();
+        SynapseConfiguration testConfig = new SynapseConfiguration();
+        testConfig.addRegistry(null, new SimpleURLRegistry());
+        synCtx.setConfiguration(testConfig);
 
         SOAPEnvelope envelope = OMAbstractFactory.getSOAP11Factory().getDefaultEnvelope();
         OMDocument omDoc = OMAbstractFactory.getSOAP11Factory().createOMDocument();

Added: incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/SimpleURLRegistryTest.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/SimpleURLRegistryTest.java?rev=421891&view=auto
==============================================================================
--- incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/SimpleURLRegistryTest.java (added)
+++ incubator/synapse/trunk/java/modules/core/test/org/apache/synapse/registry/url/SimpleURLRegistryTest.java Fri Jul 14 05:28:27 2006
@@ -0,0 +1,86 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* Licensed 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.registry.url;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+
+import org.apache.synapse.registry.Registry;
+
+public class SimpleURLRegistryTest extends TestCase {
+
+    private static final String FILE = "text.xml";
+    private static final String TEXT_1 = "<text1 />";
+    private static final String TEXT_2 = "<text2 />";
+
+    public void setUp() throws Exception {
+        writeToFile(TEXT_1);
+    }
+
+    public void testRegistry() throws Exception {
+        Registry reg = new SimpleURLRegistry();
+        reg.setConfigProperty("root", "file:./");
+        reg.setConfigProperty("cachableDuration", "1500");
+
+        // initial load of file from registry
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+
+        // sleep 1 sec
+        Thread.sleep(1000);
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+
+        // sleep another 1 sec, has expired in cache, but content hasnt changed
+        Thread.sleep(1000);
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+
+        // the renewed cache should be valid for another 1.5 secs
+        // change the file now and change next cache duration
+        writeToFile(TEXT_2);
+        reg.setConfigProperty("cachableDuration", "100");
+
+        // still cached content should be available and valid
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+
+        // now sleep 1 sec, still cache should be valid
+        Thread.sleep(1000);
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+
+        // sleep another 1 sec.. cache should expire and new content should be loaded
+        Thread.sleep(1000);
+        assertEquals(TEXT_2, reg.getProperty(FILE).toString());
+
+        // change content back to original
+        writeToFile(TEXT_1);
+
+        // sleep for .5 sec, now the new content should be loaded as new expiry time
+        // is .1 sec
+        Thread.sleep(500);
+        assertEquals(TEXT_1, reg.getProperty(FILE).toString());
+    }
+
+    public void tearDown() throws Exception {
+        new File(FILE).delete();
+    }
+
+    private void writeToFile(String content) throws Exception {
+        BufferedWriter out = new BufferedWriter(new FileWriter(new File(FILE)));
+        out.write(content);
+        out.close();
+    }
+}

Modified: incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediator.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediator.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediator.java (original)
+++ incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediator.java Fri Jul 14 05:28:27 2006
@@ -15,18 +15,17 @@
 */
 package org.apache.synapse.mediators.validate;
 
-import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.xpath.AXIOMXPath;
-import org.apache.axiom.soap.SOAP11Constants;
-import org.apache.axiom.soap.SOAP12Constants;
 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.DynamicProperty;
+import org.apache.synapse.config.Util;
 import org.apache.synapse.mediators.AbstractListMediator;
 import org.apache.synapse.mediators.MediatorProperty;
+import org.apache.synapse.registry.Registry;
 import org.jaxen.JaxenException;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -35,7 +34,6 @@
 import org.xml.sax.helpers.DefaultHandler;
 import org.xml.sax.helpers.XMLReaderFactory;
 
-import javax.xml.XMLConstants;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.sax.SAXSource;
@@ -45,32 +43,38 @@
 import javax.xml.validation.Validator;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.StringTokenizer;
+import java.io.IOException;
+import java.util.*;
 
 /**
  * Validate a message or an element against a schema
+ * <p/>
+ * This internally uses the Xerces2-j parser, which cautions a lot about thread-safety and
+ * memory leaks. Hence this initial implementation will create a single parser instance
+ * for each unique mediator instance, and re-use it to validate multiple messages - even
+ * concurrently - by synchronizing access
  */
 public class ValidateMediator extends AbstractListMediator {
 
     private static final Log log = LogFactory.getLog(ValidateMediator.class);
 
     /**
-     * Default validation schema language (http://www.w3.org/2001/XMLSchema) and validator feature ids.
+     * Default schema language (http://www.w3.org/2001/XMLSchema) and validator feature ids.
      */
     private static final String DEFAULT_SCHEMA_LANGUAGE = "http://www.w3.org/2001/XMLSchema";
 
+    /** The name of the registry on which the Schema keys could be looked up from */
+    private String registryName = null;
+
     /**
-     * A space or comma delimitered list of schemas to validate the source element against
+     * A list of DynamicProperty keys, referring to the schemas to be used for validation
      */
-    private String schemaUrl = null;
+    private List schemaKeys = new ArrayList();
 
     /**
      * An XPath expression to be evaluated against the message to find the element to be validated.
-     * If this is not specified, the validation will occur against the first child element of the SOAP body
+     * If this is not specified, the validation will occur against the first child element of the
+     * SOAP body
      */
     private AXIOMXPath source = null;
 
@@ -80,146 +84,217 @@
      */
     private Map properties = new HashMap();
 
+    /**
+     * This is the actual Validator instance used to validate messages - probably
+     * by multiple threads. Always *USE* validatorLock to synchronize access to this
+     */
+    private Validator validator = null;
 
-    public String getSchemaUrl() {
-        return schemaUrl;
-    }
-
-    public void setSchemaUrl(String schemaUrl) {
-        this.schemaUrl = schemaUrl;
-    }
+    /**
+     * Lock used to ensure thread-safe creation and use of the above Validator
+     */
+    private final Object validatorLock = new Object();
 
-    public AXIOMXPath getSource() {
-        return source;
-    }
+    /**
+     * This is the reference to the DefaultHandler instance
+     */
+    private final MyErrorHandler errorHandler = new MyErrorHandler();
 
-    public void setSource(AXIOMXPath source) {
-        this.source = source;
+    public ValidateMediator() {
+        // create the default XPath
+        try {
+            this.source = new AXIOMXPath("//*:Envelope/*:Body/child::*");
+        } catch (JaxenException e) {
+            // this should not cause a runtime exception!
+        }
     }
 
     /**
-     * Return the node to be validated. If a source XPath is not specified, this will
-     * default to the first child of the SOAP body
+     * Return the OMNode to be validated. If a source XPath is not specified, this will
+     * default to the first child of the SOAP body i.e. - //*:Envelope/*:Body/child::*
+     *
      * @param synCtx the message context
      * @return the OMNode against which validation should be performed
      */
     private OMNode getValidateSource(MessageContext synCtx) {
 
-        AXIOMXPath sourceXPath = source;
-        // do not change the source XPath if not specified, as it is shared..
-        // and will cause confusion to concurrent messages and erroneous results
-
-        if (sourceXPath == null) {
-            log.debug("validation source was not specified.. defaulting to SOAP Body");
-            try {
-                sourceXPath = new AXIOMXPath("//SOAP-ENV:Body/child::*");
-                sourceXPath.addNamespace("SOAP-ENV", synCtx.isSOAP11() ?
-                    SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI : SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
-            } catch (JaxenException e) {
-                // this should not cause a runtime exception!
-            }
-        }
-
         try {
-            Object o = sourceXPath.evaluate(synCtx.getEnvelope());
+            Object o = source.evaluate(synCtx.getEnvelope());
             if (o instanceof OMNode) {
                 return (OMNode) o;
             } else if (o instanceof List && !((List) o).isEmpty()) {
                 return (OMNode) ((List) o).get(0);  // Always fetches *only* the first
             } else {
-                String msg = "The evaluation of the XPath expression " + source + " must result in an OMNode";
-                log.error(msg);
-                throw new SynapseException(msg);
+                handleException("The evaluation of the XPath expression "
+                    + source + " must result in an OMNode");
             }
-
         } catch (JaxenException e) {
-            String msg = "Error evaluating XPath " + source + " on message";
-            log.error(msg);
-            throw new SynapseException(msg, e);
+            handleException("Error evaluating XPath " + source + " on message");
         }
+        return null;
     }
 
     public boolean mediate(MessageContext synCtx) {
 
         ByteArrayInputStream baisFromSource = null;
-        OMNode sourceNode = null;
 
         try {
             // create a byte array output stream and serialize the source node into it
             ByteArrayOutputStream baosForSource = new ByteArrayOutputStream();
-            XMLStreamWriter xsWriterForSource = XMLOutputFactory.newInstance().createXMLStreamWriter(baosForSource);
+            XMLStreamWriter xsWriterForSource =
+                XMLOutputFactory.newInstance().createXMLStreamWriter(baosForSource);
 
             // serialize the validation target and get an input stream into it
-            sourceNode = getValidateSource(synCtx);
-            sourceNode.serialize(xsWriterForSource);
+            getValidateSource(synCtx).serialize(xsWriterForSource);
             baisFromSource = new ByteArrayInputStream(baosForSource.toByteArray());
 
         } catch (Exception e) {
-            String msg = "Error accessing source element for validation : " + source;
-            log.error(msg);
-            throw new SynapseException(msg, e);
+            handleException("Error accessing source element for validation : " + source, e);
         }
 
         try {
-            // this is our custom validation handler
-            SynapseValidator handler = new SynapseValidator();
+            XMLReader reader = XMLReaderFactory.createXMLReader();
+            SAXSource saxSrc = new SAXSource(reader, new InputSource(baisFromSource));
 
-            // Create SchemaFactory and configure
-            SchemaFactory factory = SchemaFactory.newInstance(DEFAULT_SCHEMA_LANGUAGE);
-            factory.setErrorHandler(handler);
-            setXmlFeatures(factory);
-
-            // Build Schema from schemaUrl
-            Schema schema = null;
-            if (schemaUrl != null) {
-                StringTokenizer st = new StringTokenizer(schemaUrl, " ,");
-                int sourceCount = st.countTokens();
-
-                if (sourceCount == 0) {
-                    log.debug("Schemas have not been specified..");
-                    schema = factory.newSchema();
-                } else {
-                    StreamSource[] sources = new StreamSource[sourceCount];
-                    for (int j = 0; j < sourceCount; ++j) {
-                        sources[j] = new StreamSource(st.nextToken());
+            synchronized (validatorLock) {
+
+                // initialize schemas/Validator if required
+                initialize(synCtx);
+
+                // perform actual validation
+                validator.validate(saxSrc);
+
+                if (errorHandler.isValidationError()) {
+                    if (log.isDebugEnabled()) {
+                        log.debug(
+                            "Validation of element returned by XPath : " + source +
+                                " failed against the given schemas with Message : " +
+                                errorHandler.getSaxParseException().getMessage() +
+                                " Executing 'on-fail' sequence");
+                        log.debug("Failed message envelope : " + synCtx.getEnvelope());
                     }
-                    schema = factory.newSchema(sources);
+                    // super.mediate() invokes the "on-fail" sequence of mediators
+                    return super.mediate(synCtx);
                 }
-            } else {
-                log.debug("Schemas have not been specified..");
-                schema = factory.newSchema();
             }
+        } catch (SAXException e) {
+            handleException("Error validating " + source + " element" + e.getMessage(), e);
+        } catch (IOException e) {
+            handleException("Error validating " + source + " element" + e.getMessage(), e);
+        }
 
-            // Setup validator and input source
-            // Features set for the SchemaFactory get propagated to Schema and Validator (JAXP 1.4).
-            Validator validator = schema.newValidator();
-            validator.setErrorHandler(handler);
+        return true;
+    }
 
-            XMLReader reader = XMLReaderFactory.createXMLReader();
-            SAXSource source = new SAXSource(reader, new InputSource(baisFromSource));
-            validator.validate(source);
+    /**
+     * Perform actual initialization of this validate mediator instance - if required
+     */
+    private void initialize(MessageContext msgCtx) {
+
+        // flag to check if we need to initialize/re-initialize the schema Validator
+        boolean reCreate = false;
+
+        Registry reg = msgCtx.getConfiguration().getRegistry(registryName);
 
-            if (handler.isValidationError()) {
-                log.debug("Validation of element : " + sourceNode + " failed against : " + schemaUrl +
-                    " Message : " + handler.getSaxParseException().getMessage() + " Executing 'on-fail' sequence");
-                log.debug("Failed message envelope : " + synCtx.getEnvelope());
-                // super.mediate() invokes the "on-fail" sequence of mediators
-                return super.mediate(synCtx);
+        // if any of the schemas are not loaded or expired, load or re-load them
+        Iterator iter = schemaKeys.iterator();
+        while (iter.hasNext()) {
+            DynamicProperty dp = (DynamicProperty) iter.next();
+            if (dp.getCache() == null || dp.isExpired()) {
+                reg.getProperty(dp.getKey());   // load property from registry
+                reCreate = true;                // request re-initialization of Validator
             }
+        }
 
+        // do not re-initialize Validator unless required
+        if (!reCreate) {
+            return;
         }
-        catch (Exception e) {
-            String msg = "Error validating " + source + " against schema : " + schemaUrl + " : " + e.getMessage();
-            log.error(msg);
-            throw new SynapseException(msg, e);
+
+        synchronized (validatorLock) {
+
+            try {
+                // Create SchemaFactory and configure for the default schema language - XMLSchema
+                SchemaFactory factory = SchemaFactory.newInstance(DEFAULT_SCHEMA_LANGUAGE);
+                factory.setErrorHandler(errorHandler);
+
+                // set any features on/off as requested
+                iter = properties.entrySet().iterator();
+                while (iter.hasNext()) {
+                    Map.Entry entry = (Map.Entry) iter.next();
+                    String value = (String) entry.getValue();
+                    factory.setFeature(
+                        (String) entry.getKey(), value != null && "true".equals(value));
+                }
+
+                Schema schema = null;
+
+                StreamSource[] sources = new StreamSource[schemaKeys.size()];
+                iter = schemaKeys.iterator();
+                int i = 0;
+                while (iter.hasNext()) {
+                    DynamicProperty dp = (DynamicProperty) iter.next();
+                    sources[i++] = Util.getStreamSource(reg.getProperty(dp.getKey()));
+                }
+                schema = factory.newSchema(sources);
+
+                // Setup validator and input source
+                // Features set for the SchemaFactory get propagated to Schema and Validator (JAXP 1.4)
+                validator = schema.newValidator();
+                validator.setErrorHandler(errorHandler);
+
+            } catch (SAXException e) {
+                handleException("Error creating Validator", e);
+            }
         }
+    }
 
-        return true;
+    /**
+     * This class handles validation errors to be used for error reporting
+     */
+    private class MyErrorHandler extends DefaultHandler {
+
+        private boolean validationError = false;
+        private SAXParseException saxParseException = null;
+
+        public void error(SAXParseException exception) throws SAXException {
+            validationError = true;
+            saxParseException = exception;
+        }
+
+        public void fatalError(SAXParseException exception) throws SAXException {
+            validationError = true;
+            saxParseException = exception;
+        }
+
+        public void warning(SAXParseException exception) throws SAXException {
+        }
+
+        public boolean isValidationError() {
+            return validationError;
+        }
+
+        public SAXParseException getSaxParseException() {
+            return saxParseException;
+        }
+    }
+
+    private void handleException(String msg) {
+        log.error(msg);
+        throw new SynapseException(msg);
+    }
+
+    private void handleException(String msg, Exception e) {
+        log.error(msg, e);
+        throw new SynapseException(msg, e);
     }
 
+    // setters and getters
+
     /**
      * Get a mediator property. The common use case is a feature for the
      * underlying Xerces validator
+     *
      * @param key property key / feature name
      * @return property string value (usually true|false)
      */
@@ -229,7 +304,8 @@
 
     /**
      * Set a property for this mediator
-     * @param key the property key / feature name
+     *
+     * @param key   the property key / feature name
      * @param value property string value (usually true|false)
      * @see #getProperty(String)
      */
@@ -239,6 +315,7 @@
 
     /**
      * Add a list of 'MediatorProperty'ies to this mediator
+     *
      * @param list a List of MediatorProperty objects
      */
     public void addAllProperties(List list) {
@@ -255,53 +332,29 @@
         }
     }
 
-    private void handleException(String msg) {
-        log.error(msg);
-        throw new SynapseException(msg);
+    /**
+     * Set a list of DynamicProperty elements which refer to the list of schemas to be
+     * used for validation
+     *
+     * @param schemaKeys list of DynamicProperty elements
+     */
+    public void setSchemaKeys(List schemaKeys) {
+        this.schemaKeys = schemaKeys;
     }
 
     /**
-     * Set the properties set on this mediator to the underlying Xerces
-     * @param factory Schema factory
-     * @throws SAXException on error
+     * Set the given XPath as the source XPath
+     * @param source an XPath to be set as the source
      */
-    private void setXmlFeatures(SchemaFactory factory) throws SAXException {
-        Iterator iter = properties.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry entry = (Map.Entry)iter.next();
-            String value = (String)entry.getValue();
-            factory.setFeature((String)entry.getKey(), value != null && "true".equals(value));
-        }
+    public void setSource(AXIOMXPath source) {
+       this.source = source;
     }
 
     /**
-     * This class handles validation errors to be used for error reporting
+     * Set the name of the registry which should be used for schema key lookup
+     * @param registryName the name of the registry
      */
-    private class SynapseValidator extends DefaultHandler {
-
-        private boolean validationError = false;
-        private SAXParseException saxParseException = null;
-
-        public void error(SAXParseException exception) throws SAXException {
-            validationError = true;
-            saxParseException = exception;
-        }
-
-        public void fatalError(SAXParseException exception) throws SAXException {
-            validationError = true;
-            saxParseException = exception;
-        }
-
-        public void warning(SAXParseException exception) throws SAXException {
-        }
-
-        public boolean isValidationError() {
-            return validationError;
-        }
-
-        public SAXParseException getSaxParseException() {
-            return saxParseException;
-        }
+    public void setRegistryName(String registryName) {
+        this.registryName = registryName;
     }
-
 }

Modified: incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediatorFactory.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediatorFactory.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediatorFactory.java (original)
+++ incubator/synapse/trunk/java/modules/extensions/src/org/apache/synapse/mediators/validate/ValidateMediatorFactory.java Fri Jul 14 05:28:27 2006
@@ -25,18 +25,22 @@
 import org.apache.synapse.config.xml.AbstractListMediatorFactory;
 import org.apache.synapse.config.xml.Constants;
 import org.apache.synapse.config.xml.MediatorPropertyFactory;
+import org.apache.synapse.config.DynamicProperty;
 import org.apache.synapse.api.Mediator;
 import org.apache.synapse.mediators.validate.ValidateMediator;
 import org.apache.ws.commons.schema.XmlSchema;
 import org.jaxen.JaxenException;
 
 import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
 import javax.xml.namespace.QName;
 
 /**
  * Creates a validation mediator from the XML configuration
  * <p/>
- * <validate schema="url" [source="xpath"]>
+ * <validate [source="xpath"]>
+ *   <schema key="string">+
  *   <property name="<validation-feature-id>" value="true|false"/> *
  *   <on-fail>
  *     mediator+
@@ -48,9 +52,10 @@
     private static final Log log = LogFactory.getLog(ValidateMediatorFactory.class);
 
     private static final QName VALIDATE_Q = new QName(Constants.SYNAPSE_NAMESPACE, "validate");
-    private static final QName ON_FAIL_Q = new QName(Constants.SYNAPSE_NAMESPACE, "on-fail");
-    private static final QName SCHEMA_Q = new QName(Constants.NULL_NAMESPACE, "schema");
-    private static final QName SOURCE_Q = new QName(Constants.NULL_NAMESPACE, "source");
+    private static final QName ON_FAIL_Q  = new QName(Constants.SYNAPSE_NAMESPACE, "on-fail");
+    private static final QName SCHEMA_Q   = new QName(Constants.SYNAPSE_NAMESPACE, "schema");
+    private static final QName KEY_Q      = new QName(Constants.NULL_NAMESPACE, "key");
+    private static final QName SOURCE_Q   = new QName(Constants.NULL_NAMESPACE, "source");
 
     private static final String STR_SCHEMA =
         Constants.SCHEMA_PROLOG +
@@ -77,29 +82,46 @@
     public Mediator createMediator(OMElement elem) {
 
         ValidateMediator validateMediator = new ValidateMediator();
-        OMAttribute attSchema = elem.getAttribute(SCHEMA_Q);
-        OMAttribute attSource = elem.getAttribute(SOURCE_Q);
 
-        if (attSchema != null) {
-            validateMediator.setSchemaUrl(attSchema.getAttributeValue());
+        // process schema element definitions and create DynamicProperties
+        List schemaKeys = new ArrayList();
+        Iterator schemas = elem.getChildrenWithName(SCHEMA_Q);
+
+        while (schemas.hasNext()) {
+            Object o = schemas.next();
+            if (o instanceof OMElement) {
+                OMElement omElem = (OMElement) o;
+                OMAttribute keyAtt = omElem.getAttribute(KEY_Q);
+                if (keyAtt != null) {
+                    schemaKeys.add(new DynamicProperty(keyAtt.getAttributeValue()));
+                } else {
+                    handleException("A 'schema' definition must contain the registry 'key'");
+                }
+            } else {
+                handleException("Invalid 'schema' declaration for validate mediator");
+            }
+        }
+
+        if (schemaKeys.size() == 0) {
+            handleException("No schemas specified for the validate mediator");
         } else {
-            String msg = "The 'schema' attribute is required for the validate mediator configuration";
-            log.error(msg);
-            throw new SynapseException(msg);
+            validateMediator.setSchemaKeys(schemaKeys);
         }
 
+        // process source XPath attribute if present
+        OMAttribute attSource = elem.getAttribute(SOURCE_Q);
+
         if (attSource != null) {
             try {
                 AXIOMXPath xp = new AXIOMXPath(attSource.getAttributeValue());
                 validateMediator.setSource(xp);
                 Util.addNameSpaces(xp, elem, log);
             } catch (JaxenException e) {
-                String msg = "Invalid XPath expression specified for attribute 'source'";
-                log.error(msg);
-                throw new SynapseException(msg, e);
+                handleException("Invalid XPath expression specified for attribute 'source'", e);
             }
         }
 
+        // process on-fail
         OMElement onFail = null;
         Iterator iter = elem.getChildrenWithName(ON_FAIL_Q);
         if (iter.hasNext()) {
@@ -109,15 +131,25 @@
         if (onFail != null && onFail.getChildElements().hasNext()) {
             super.addChildren(onFail, validateMediator);
         } else {
-            String msg = "A non-empty <on-fail> child element is required for the <validate> mediator";
-            log.error(msg);
-            throw new SynapseException(msg);
+            handleException("A non-empty <on-fail> child element is required for " +
+                "the <validate> mediator");
         }
 
+        // process properties
         validateMediator.addAllProperties(
             MediatorPropertyFactory.getMediatorProperties(elem));
 
         return validateMediator;
+    }
+
+    private void handleException(String msg, Exception e) {
+        log.error(msg, e);
+        throw new SynapseException(msg, e);
+    }
+
+    private void handleException(String msg) {
+        log.error(msg);
+        throw new SynapseException(msg);
     }
 
     public QName getTagQName() {

Modified: incubator/synapse/trunk/java/modules/extensions/test/org/apache/synapse/ValidateMediatorTest.java
URL: http://svn.apache.org/viewvc/incubator/synapse/trunk/java/modules/extensions/test/org/apache/synapse/ValidateMediatorTest.java?rev=421891&r1=421890&r2=421891&view=diff
==============================================================================
--- incubator/synapse/trunk/java/modules/extensions/test/org/apache/synapse/ValidateMediatorTest.java (original)
+++ incubator/synapse/trunk/java/modules/extensions/test/org/apache/synapse/ValidateMediatorTest.java Fri Jul 14 05:28:27 2006
@@ -16,6 +16,8 @@
 package org.apache.synapse;
 
 import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.ArrayList;
 import javax.xml.stream.XMLStreamException;
 import junit.framework.TestCase;
 import org.apache.axiom.om.OMElement;
@@ -24,6 +26,7 @@
 import org.apache.synapse.MessageContext;
 import org.apache.synapse.TestMediateHandler;
 import org.apache.synapse.TestMediator;
+import org.apache.synapse.config.DynamicProperty;
 import org.apache.synapse.mediators.TestUtils;
 import org.apache.synapse.mediators.validate.ValidateMediator;
 import org.apache.synapse.mediators.validate.ValidateMediatorFactory;
@@ -77,8 +80,8 @@
             "</CheckPriceRequest>\n";
 
     private static final String DEFAULT_FEATURES_MEDIATOR_CONFIG = 
-            "<validate xmlns=\"http://ws.apache.org/ns/synapse\" " +
-            "       schema=\"file:synapse_repository/conf/sample/validate.xsd\">" + 
+            "<validate xmlns=\"http://ws.apache.org/ns/synapse\">" +
+            "   <schema key=\"file:synapse_repository/conf/sample/validate.xsd\"/>" +
             "   <on-fail>" +
             "       <makefault>" +
             "           <code value=\"tns:Receiver\" xmlns:tns=\"http://www.w3.org/2003/05/soap-envelope\"/>" +
@@ -88,8 +91,8 @@
             "</validate>";
 
     private static final String CUSTOM_FEATURES_MEDIATOR_CONFIG = 
-            "<validate xmlns=\"http://ws.apache.org/ns/synapse\" " +
-            "       schema=\"file:synapse_repository/conf/sample/validate.xsd\">" + 
+            "<validate xmlns=\"http://ws.apache.org/ns/synapse\">" +
+            "   <schema key=\"file:synapse_repository/conf/sample/validate.xsd\"/>" +
             "   <property name=\"" + SCHEMA_FULL_CHECKING_FEATURE_ID + "\" value=\"false\"/>" +
             "   <property name=\"" + HONOUR_ALL_SCHEMA_LOCATIONS_FEATURE_ID + "\" value=\"true\"/>" +
             "   <on-fail>" +
@@ -124,7 +127,9 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:CheckPriceRequest");
         source.addNamespace("m0", "http://www.apache-synapse.org/test");
         validate.setSource(source);
@@ -145,7 +150,10 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd ../core/test-resources/misc/validate2.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate2.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:Outer");
         source.addNamespace("m0", "http://www.apache-synapse.org/test2");
         validate.setSource(source);
@@ -166,7 +174,10 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd ../core/test-resources/misc/validate2.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate2.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:Outer");
         source.addNamespace("m0", "http://www.apache-synapse.org/test2");
         validate.setSource(source);
@@ -187,7 +198,9 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:CheckPriceRequest");
         source.addNamespace("m0", "http://www.apache-synapse.org/test");
         validate.setSource(source);
@@ -208,7 +221,9 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:CheckPriceRequest");
         source.addNamespace("m0", "http://www.apache-synapse.org/test");
         validate.setSource(source);
@@ -229,7 +244,9 @@
         ValidateMediator validate = new ValidateMediator();
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:CheckPriceRequest");
         source.addNamespace("m0", "http://www.apache-synapse.org/test");
         validate.setSource(source);
@@ -274,7 +291,9 @@
         setOnFailInvoked(false);
 
         // set the schema url, source xpath and any name spaces
-        validate.setSchemaUrl("../core/test-resources/misc/validate.xsd");
+        List keys = new ArrayList();
+        keys.add(new DynamicProperty("file:../core/test-resources/misc/validate.xsd"));
+        validate.setSchemaKeys(keys);
         AXIOMXPath source = new AXIOMXPath("//m0:CheckPriceRequest");
         source.addNamespace("m0", "http://www.apache-synapse.org/test");
         validate.setSource(source);



---------------------------------------------------------------------
To unsubscribe, e-mail: synapse-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: synapse-dev-help@ws.apache.org