You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by js...@apache.org on 2007/05/01 15:14:41 UTC

svn commit: r534059 - /activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/

Author: jstrachan
Date: Tue May  1 06:14:40 2007
New Revision: 534059

URL: http://svn.apache.org/viewvc?view=rev&rev=534059
Log:
Added an XSLT processor and refactored the XPath and XSLT code into an xml package

Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html   (with props)

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java Tue May  1 06:14:40 2007
@@ -0,0 +1,98 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPathFactory;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An implementation of {@link NamespaceContext} which uses a simple Map where
+ * the keys are the prefixes and the values are the URIs
+ *
+ * @version $Revision: $
+ */
+public class DefaultNamespaceContext implements NamespaceContext {
+
+    private final Map map;
+    private final NamespaceContext parent;
+
+    public DefaultNamespaceContext() {
+        this(XPathFactory.newInstance());
+    }
+
+    public DefaultNamespaceContext(XPathFactory factory) {
+        this.parent = factory.newXPath().getNamespaceContext();
+        this.map = new HashMap();
+    }
+
+    public DefaultNamespaceContext(NamespaceContext parent, Map map) {
+        this.parent = parent;
+        this.map = map;
+    }
+
+    /**
+     * A helper method to make it easy to create newly populated instances
+     */
+    public DefaultNamespaceContext add(String prefix, String uri) {
+        map.put(prefix, uri);
+        return this;
+    }
+
+    public String getNamespaceURI(String prefix) {
+        String answer = (String) map.get(prefix);
+        if (answer == null && parent != null) {
+            return parent.getNamespaceURI(prefix);
+        }
+        return answer;
+    }
+
+    public String getPrefix(String namespaceURI) {
+        for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            if (namespaceURI.equals(entry.getValue())) {
+                return (String) entry.getKey();
+            }
+        }
+        if (parent != null) {
+            return parent.getPrefix(namespaceURI);
+        }
+        return null;
+    }
+
+    public Iterator getPrefixes(String namespaceURI) {
+        Set set = new HashSet();
+        for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            if (namespaceURI.equals(entry.getValue())) {
+                set.add(entry.getKey());
+            }
+        }
+        if (parent != null) {
+            Iterator iter = parent.getPrefixes(namespaceURI);
+            while (iter.hasNext()) {
+                set.add(iter.next());
+            }
+        }
+        return set.iterator();
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DefaultNamespaceContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java Tue May  1 06:14:40 2007
@@ -0,0 +1,40 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Message;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.dom.DOMResult;
+
+/**
+ * Uses DOM to handle results of the transformation
+ * 
+ * @version $Revision: 1.1 $
+ */
+public class DomResultHandler implements ResultHandler {
+    private DOMResult result = new DOMResult();
+
+    public Result getResult() {
+        return result;
+    }
+
+    public void setBody(Message in) {
+        in.setBody(result.getNode());
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/DomResultHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java Tue May  1 06:14:40 2007
@@ -0,0 +1,40 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.RuntimeExpressionException;
+
+import javax.xml.xpath.XPathException;
+
+/**
+ * An exception thrown if am XPath expression could not be parsed or evaluated
+ *
+ * @version $Revision: 521180 $
+ */
+public class InvalidXPathExpression extends RuntimeExpressionException {
+    private final String xpath;
+
+    public InvalidXPathExpression(String xpath, XPathException e) {
+        super("Invalid xpath: " + xpath + ". Reason: " + e, e);
+        this.xpath = xpath;
+    }
+
+    public String getXpath() {
+        return xpath;
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/InvalidXPathExpression.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java Tue May  1 06:14:40 2007
@@ -0,0 +1,101 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A variable resolver for XPath expressions which support properties on the messge, exchange as well
+ * as making system properties and environment properties available.
+ *
+ * @version $Revision: 521692 $
+ */
+public class MessageVariableResolver implements XPathVariableResolver {
+    public static final String SYSTEM_PROPERTIES_NAMESPACE = "http://camel.apache.org/xml/variables/system-properties";
+    public static final String ENVIRONMENT_VARIABLES = "http://camel.apache.org/xml/variables/environment-variables";
+    public static final String EXCHANGE_PROPERTY = "http://camel.apache.org/xml/variables/exchange-property";
+    public static final String IN_HEADER = "http://camel.apache.org/xml/variables/in-header";
+    public static final String OUT_HEADER = "http://camel.apache.org/xml/variables/out-header";
+
+    private static final transient Log log = LogFactory.getLog(MessageVariableResolver.class);
+
+    private Exchange exchange;
+    private Map<String, Object> variables = new HashMap<String, Object>();
+
+    public Exchange getExchange() {
+        return exchange;
+    }
+
+    public void setExchange(Exchange exchange) {
+        this.exchange = exchange;
+    }
+
+    public Object resolveVariable(QName name) {
+        String uri = name.getNamespaceURI();
+        String localPart = name.getLocalPart();
+        Object answer = null;
+
+        if (uri == null || uri.length() == 0) {
+            answer = variables.get(localPart);
+            if (answer == null) {
+                Message message = exchange.getIn();
+                if (message != null) {
+                    answer = message.getHeader(localPart);
+                }
+                if (answer == null) {
+                    answer = exchange.getProperty(localPart);
+                }
+            }
+        }
+        else if (uri.equals(SYSTEM_PROPERTIES_NAMESPACE)) {
+            try {
+                answer = System.getProperty(localPart);
+            }
+            catch (Exception e) {
+                log.debug("Security exception evaluating system property: " + localPart + ". Reason: " + e, e);
+            }
+        }
+        else if (uri.equals(ENVIRONMENT_VARIABLES)) {
+            answer = System.getenv().get(localPart);
+        }
+        else if (uri.equals(EXCHANGE_PROPERTY)) {
+            answer = exchange.getProperty(localPart);
+        }
+        else if (uri.equals(IN_HEADER)) {
+            answer = exchange.getIn().getHeader(localPart);
+        }
+        else if (uri.equals(OUT_HEADER)) {
+            answer = exchange.getOut().getHeader(localPart);
+        }
+
+        // TODO support exposing CamelContext properties/resources via XPath?
+        return answer;
+    }
+
+    public void addVariable(String localPart, Object value) {
+        variables.put(localPart, value);
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/MessageVariableResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java Tue May  1 06:14:40 2007
@@ -0,0 +1,33 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Message;
+
+import javax.xml.transform.Result;
+
+/**
+ * A strategy for handling XSLT results
+ *
+ * @version $Revision: 1.1 $
+ */
+public interface ResultHandler {
+    Result getResult();
+
+    void setBody(Message in);
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/ResultHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java Tue May  1 06:14:40 2007
@@ -0,0 +1,42 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Message;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Processes the XSLT result as a byte[]
+ *
+ * @version $Revision: 1.1 $
+ */
+public class StreamResultHandler implements ResultHandler {
+    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+    StreamResult result = new StreamResult(buffer);
+
+    public Result getResult() {
+        return result;
+    }
+
+    public void setBody(Message in) {
+        in.setBody(buffer.toByteArray());
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StreamResultHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java Tue May  1 06:14:40 2007
@@ -0,0 +1,42 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Message;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.Result;
+import java.io.StringWriter;
+
+/**
+ * Processes the XSLT result as a String
+ *
+ * @version $Revision: 1.1 $
+ */
+public class StringResultHandler implements ResultHandler {
+    StringWriter buffer = new StringWriter();
+    StreamResult result = new StreamResult(buffer);
+
+    public Result getResult() {
+        return result;
+    }
+
+    public void setBody(Message in) {
+        in.setBody(buffer.toString());
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/StringResultHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java Tue May  1 06:14:40 2007
@@ -0,0 +1,316 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import static org.apache.camel.converter.ObjectConverter.toBoolean;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeExpressionException;
+import org.apache.camel.Message;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunctionResolver;
+import java.io.StringReader;
+
+/**
+ * Creates an XPath expression builder
+ *
+ * @version $Revision: 531854 $
+ */
+public class XPathBuilder<E extends Exchange> implements Expression<E>, Predicate<E> {
+    private final String text;
+    private XPathFactory xpathFactory;
+    private Class documentType = Document.class;
+    private QName resultType = null;
+    private String objectModelUri = null;
+    private DefaultNamespaceContext namespaceContext;
+    private XPathFunctionResolver functionResolver;
+    private XPathExpression expression;
+    private MessageVariableResolver variableResolver = new MessageVariableResolver();
+
+    public static XPathBuilder xpath(String text) {
+        return new XPathBuilder(text);
+    }
+
+    public XPathBuilder(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return "XPath: " + text;
+    }
+
+    public boolean matches(E exchange) {
+        Object booleanResult = evaluateAs(exchange, XPathConstants.BOOLEAN);
+        return toBoolean(booleanResult);
+    }
+
+    public void assertMatches(String text, E exchange) throws AssertionError {
+        Object booleanResult = evaluateAs(exchange, XPathConstants.BOOLEAN);
+        if (!toBoolean(booleanResult)) {
+            throw new AssertionError(this + " failed on " + exchange + " as returned <" + booleanResult + ">");
+        }
+    }
+
+    public Object evaluate(E exchange) {
+        return evaluateAs(exchange, resultType);
+    }
+
+
+    // Builder methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Sets the expression result type to boolean
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> booleanResult() {
+        resultType = XPathConstants.BOOLEAN;
+        return this;
+    }
+
+    /**
+     * Sets the expression result type to boolean
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> nodeResult() {
+        resultType = XPathConstants.NODE;
+        return this;
+    }
+
+    /**
+     * Sets the expression result type to boolean
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> nodeSetResult() {
+        resultType = XPathConstants.NODESET;
+        return this;
+    }
+
+    /**
+     * Sets the expression result type to boolean
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> numberResult() {
+        resultType = XPathConstants.NUMBER;
+        return this;
+    }
+
+    /**
+     * Sets the expression result type to boolean
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> stringResult() {
+        resultType = XPathConstants.STRING;
+        return this;
+    }
+
+    /**
+     * Sets the object model URI to use
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> objectModel(String uri) {
+        this.objectModelUri = uri;
+        return this;
+    }
+
+    /**
+     * Sets the {@link XPathFunctionResolver} instance to use on these XPath expressions
+     *
+     * @return the current builder
+     */
+    public XPathBuilder<E> functionResolver(XPathFunctionResolver functionResolver) {
+        this.functionResolver = functionResolver;
+        return this;
+    }
+
+    /**
+     * Registers the namespace prefix and URI with the builder so that the prefix can be used in XPath expressions
+     *
+     * @param prefix is the namespace prefix that can be used in the XPath expressions
+     * @param uri is the namespace URI to which the prefix refers
+     * @return the current builder
+     */
+    public XPathBuilder<E> namespace(String prefix, String uri) {
+        getNamespaceContext().add(prefix, uri);
+        return this;
+    }
+
+    /**
+     * Registers a variable (in the global namespace) which can be referred to from XPath expressions
+     */
+    public XPathBuilder<E> variable(String name, Object value) {
+        variableResolver.addVariable(name, value);
+        return this;
+    }
+
+
+    // Properties
+    //-------------------------------------------------------------------------
+    public XPathFactory getXPathFactory() throws XPathFactoryConfigurationException {
+        if (xpathFactory == null) {
+            if (objectModelUri != null) {
+                xpathFactory = XPathFactory.newInstance(objectModelUri);
+            }
+            xpathFactory = XPathFactory.newInstance();
+        }
+        return xpathFactory;
+    }
+
+    public void setXPathFactory(XPathFactory xpathFactory) {
+        this.xpathFactory = xpathFactory;
+    }
+
+    public Class getDocumentType() {
+        return documentType;
+    }
+
+    public void setDocumentType(Class documentType) {
+        this.documentType = documentType;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public QName getResultType() {
+        return resultType;
+    }
+
+    public DefaultNamespaceContext getNamespaceContext() {
+        if (namespaceContext == null) {
+            try {
+                namespaceContext = new DefaultNamespaceContext(getXPathFactory());
+            }
+            catch (XPathFactoryConfigurationException e) {
+                throw new RuntimeExpressionException(e);
+            }
+        }
+        return namespaceContext;
+    }
+
+    public void setNamespaceContext(DefaultNamespaceContext namespaceContext) {
+        this.namespaceContext = namespaceContext;
+    }
+
+    public XPathFunctionResolver getFunctionResolver() {
+        return functionResolver;
+    }
+
+    public void setFunctionResolver(XPathFunctionResolver functionResolver) {
+        this.functionResolver = functionResolver;
+    }
+
+    public XPathExpression getExpression() throws XPathFactoryConfigurationException, XPathExpressionException {
+        if (expression == null) {
+            expression = createXPathExpression();
+        }
+        return expression;
+    }
+
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+
+    /**
+     * Evaluates the expression as the given result type
+     */
+    protected synchronized Object evaluateAs(E exchange, QName resultType) {
+        variableResolver.setExchange(exchange);
+        try {
+            Object document = getDocument(exchange);
+            if (resultType != null) {
+                if (document instanceof InputSource) {
+                    InputSource inputSource = (InputSource) document;
+                    return getExpression().evaluate(inputSource, resultType);
+                }
+                else {
+                    return getExpression().evaluate(document, resultType);
+                }
+            }
+            else {
+                if (document instanceof InputSource) {
+                    InputSource inputSource = (InputSource) document;
+                    return getExpression().evaluate(inputSource);
+                }
+                else {
+                    return getExpression().evaluate(document);
+                }
+            }
+        }
+        catch (XPathExpressionException e) {
+            throw new InvalidXPathExpression(getText(), e);
+        }
+        catch (XPathFactoryConfigurationException e) {
+            throw new InvalidXPathExpression(getText(), e);
+        }
+    }
+
+    protected XPathExpression createXPathExpression() throws XPathExpressionException, XPathFactoryConfigurationException {
+        XPath xPath = getXPathFactory().newXPath();
+
+        // lets now clear any factory references to avoid keeping them around
+        xpathFactory = null;
+
+        xPath.setNamespaceContext(getNamespaceContext());
+        xPath.setXPathVariableResolver(variableResolver);
+        if (functionResolver != null) {
+            xPath.setXPathFunctionResolver(functionResolver);
+        }
+        return xPath.compile(text);
+    }
+
+    /**
+     * Strategy method to extract the document from the exchange
+     */
+    protected Object getDocument(E exchange) {
+        Message in = exchange.getIn();
+        Class type = getDocumentType();
+        Object answer = null;
+        if (type != null) {
+            answer = in.getBody(type);
+        }
+        if (answer == null) {
+            answer = in.getBody();
+        }
+
+        // lets try coerce some common types into something JAXP can deal with
+        if (answer instanceof String) {
+            answer = new InputSource(new StringReader(answer.toString()));
+        }
+        return answer;
+    }
+
+
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java Tue May  1 06:14:40 2007
@@ -0,0 +1,230 @@
+/**
+ *
+ * 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.camel.builder.xml;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.ExpectedBodyTypeException;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeTransformException;
+import org.apache.camel.converter.jaxp.XmlConverter;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.stream.StreamSource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.io.File;
+
+/**
+ * Creates a <a href="http://activemq.apache.org/camel/processor.html">Processor</a>
+ * which performs an XSLT transformation of the IN message body
+ *
+ * @version $Revision: 531854 $
+ */
+public class XsltBuilder<E extends Exchange> implements Processor<E> {
+    private Map<String, Object> parameters = new HashMap<String, Object>();
+    private XmlConverter converter = new XmlConverter();
+    private Transformer transformer;
+    private ResultHandler resultHandler = new DomResultHandler();
+    private boolean failOnNullBody = true;
+
+    public XsltBuilder() {
+    }
+
+    public XsltBuilder(Transformer transformer) {
+        this.transformer = transformer;
+    }
+
+    @Override
+    public String toString() {
+        return "XSLT[" + transformer + "]";
+    }
+
+    public synchronized void process(E exchange) {
+        Transformer transformer = getTransformer();
+        if (transformer == null) {
+            throw new IllegalArgumentException("No transformer configured!");
+        }
+        configureTransformer(transformer, exchange);
+        Source source = getSource(exchange);
+        Result result = resultHandler.getResult();
+        transform(transformer, source, result);
+        resultHandler.setBody(exchange.getIn());
+    }
+
+    // Builder methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Creates an XSLT processor using the given transformer instance
+     */
+    public static <E extends Exchange> XsltBuilder<E> xslt(Transformer transformer) {
+        return new XsltBuilder<E>(transformer);
+    }
+
+    /**
+     * Creates an XSLT processor using the given XSLT source
+     */
+    public static <E extends Exchange> XsltBuilder<E> xslt(Source xslt) throws TransformerConfigurationException {
+        XsltBuilder<E> answer = new XsltBuilder<E>();
+        answer.setTransformerSource(xslt);
+        return answer;
+    }
+
+    /**
+     * Creates an XSLT processor using the given XSLT source
+     */
+    public static <E extends Exchange> XsltBuilder<E> xslt(File xslt) throws TransformerConfigurationException {
+        return xslt(new StreamSource(xslt));
+    }
+
+    /**
+     * Sets the output as being a byte[]
+     */
+    public XsltBuilder<E> outputBytes() {
+        setResultHandler(new StreamResultHandler());
+        return this;
+    }
+
+    /**
+     * Sets the output as being a String
+     */
+    public XsltBuilder<E> outputString() {
+        setResultHandler(new StringResultHandler());
+        return this;
+    }
+
+    /**
+     * Sets the output as being a DOM
+     */
+    public XsltBuilder<E> outputDOM() {
+        setResultHandler(new DomResultHandler());
+        return this;
+    }
+
+    public XsltBuilder<E> parameter(String name, Object value) {
+        parameters.put(name, value);
+        return this;
+    }
+
+
+    // Properties
+    //-------------------------------------------------------------------------
+
+    public Map<String, Object> getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(Map<String, Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    public Transformer getTransformer() {
+        return transformer;
+    }
+
+    public void setTransformer(Transformer transformer) {
+        this.transformer = transformer;
+    }
+
+    public boolean isFailOnNullBody() {
+        return failOnNullBody;
+    }
+
+    public void setFailOnNullBody(boolean failOnNullBody) {
+        this.failOnNullBody = failOnNullBody;
+    }
+
+    public ResultHandler getResultHandler() {
+        return resultHandler;
+    }
+
+    public void setResultHandler(ResultHandler resultHandler) {
+        this.resultHandler = resultHandler;
+    }
+
+    public void setTransformerSource(Source source) throws TransformerConfigurationException {
+        setTransformer(converter.getTransformerFactory().newTransformer(source));
+    }
+
+
+    // Implementation methods
+    // -------------------------------------------------------------------------
+
+    /**
+     * Converts the inbound body to a {@link Source}
+     */
+    protected Source getSource(E exchange) {
+        Message in = exchange.getIn();
+        Source source = in.getBody(Source.class);
+        if (source == null) {
+            if (isFailOnNullBody()) {
+                throw new ExpectedBodyTypeException(exchange, Source.class);
+            }
+            else {
+                try {
+                    source = converter.toSource(converter.createDocument());
+                }
+                catch (ParserConfigurationException e) {
+                    throw new RuntimeTransformException(e);
+                }
+            }
+        }
+        return source;
+    }
+
+    /**
+     * Performs the transformation, wrapping any thrown exceptions
+     */
+    protected void transform(Transformer transformer, Source source, Result result) {
+        try {
+            transformer.transform(source, result);
+        }
+        catch (TransformerException e) {
+            throw new RuntimeTransformException(e);
+        }
+    }
+
+    /**
+     * Configures the transformerwith exchange specific parameters
+     */
+    protected void configureTransformer(Transformer transformer, Exchange exchange) {
+        transformer.clearParameters();
+
+        addParameters(transformer, exchange.getProperties());
+        addParameters(transformer, exchange.getIn().getHeaders());
+        addParameters(transformer, getParameters());
+
+        transformer.setParameter("exchange", exchange);
+        transformer.setParameter("in", exchange.getIn());
+        transformer.setParameter("out", exchange.getOut());
+    }
+
+    protected void addParameters(Transformer transformer, Map<String, Object> map) {
+        Set<Map.Entry<String, Object>> propertyEntries = map.entrySet();
+        for (Map.Entry<String, Object> entry : propertyEntries) {
+            transformer.setParameter(entry.getKey(), entry.getValue());
+        }
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html?view=auto&rev=534059
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html Tue May  1 06:14:40 2007
@@ -0,0 +1,27 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+Support for XPath based <a href="http://activemq.apache.org/camel/expression.html">Expressions</a>
+and <a href="http://activemq.apache.org/camel/predicate.html">Predicates</a> as well as
+<a href="http://activemq.apache.org/camel/xslt.html">an XSLT processor</a>
+
+</body>
+</html>

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/package.html
------------------------------------------------------------------------------
    svn:eol-style = native