You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by ge...@apache.org on 2008/08/25 12:57:29 UTC

svn commit: r688693 [2/5] - in /servicemix/utils/trunk: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/servicemix/ src/main/java/org/apache/servicemix/components/ src/main/java/org/apache/servicem...

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/StringUtils.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/StringUtils.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/StringUtils.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/StringUtils.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,286 @@
+/*
+ * 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.servicemix.components.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class StringUtils {
+
+    static final String[] EMPTY_STRING_ARRAY = new String[0];
+    static final String EMPTY = "";
+
+    private StringUtils() {
+    }
+
+    /**
+     * <p>Checks if a String is whitespace, empty ("") or null.</p>
+     *
+     * <pre>
+     * StringUtils.isBlank(null)      = true
+     * StringUtils.isBlank("")        = true
+     * StringUtils.isBlank(" ")       = true
+     * StringUtils.isBlank("bob")     = false
+     * StringUtils.isBlank("  bob  ") = false
+     * </pre>
+     *
+     * @param str  the String to check, may be null
+     * @return <code>true</code> if the String is null, empty or whitespace
+     * @since 2.0
+     */
+    public static boolean isBlank(String str) {
+        if (str == null) {
+            return true;
+        }
+        int strLen = str.length();
+        if (strLen == 0) {
+            return true;
+        }
+        for (int i = 0; i < strLen; i++) {
+            if (!Character.isWhitespace(str.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Performs the logic for the <code>split</code> and
+     * <code>splitPreserveAllTokens</code> methods that return a maximum array
+     * length.
+     *
+     * @param str  the String to parse, may be <code>null</code>
+     * @param separatorChars the separate character
+     * @param max  the maximum number of elements to include in the
+     *  array. A zero or negative value implies no limit.
+     * @param preserveAllTokens if <code>true</code>, adjacent separators are
+     * treated as empty token separators; if <code>false</code>, adjacent
+     * separators are treated as one separator.
+     * @return an array of parsed Strings, <code>null</code> if null String input
+     */
+    static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
+        // Performance tuned for 2.0 (JDK1.4)
+        // Direct code is quicker than StringTokenizer.
+        // Also, StringTokenizer uses isSpace() not isWhitespace()
+
+        if (str == null) {
+            return null;
+        }
+        int len = str.length();
+        if (len == 0) {
+            return EMPTY_STRING_ARRAY;
+        }
+        List list = new ArrayList();
+        int sizePlus1 = 1;
+        int i = 0;
+        int start = 0;
+        boolean match = false;
+        boolean lastMatch = false;
+        if (separatorChars == null) {
+            // Null separator means use whitespace
+            while (i < len) {
+                if (Character.isWhitespace(str.charAt(i))) {
+                    if (match || preserveAllTokens) {
+                        lastMatch = true;
+                        if (sizePlus1++ == max) {
+                            i = len;
+                            lastMatch = false;
+                        }
+                        list.add(str.substring(start, i));
+                        match = false;
+                    }
+                    start = ++i;
+                    continue;
+                }
+                lastMatch = false;
+                match = true;
+                i++;
+            }
+        } else if (separatorChars.length() == 1) {
+            // Optimise 1 character case
+            char sep = separatorChars.charAt(0);
+            while (i < len) {
+                if (str.charAt(i) == sep) {
+                    if (match || preserveAllTokens) {
+                        lastMatch = true;
+                        if (sizePlus1++ == max) {
+                            i = len;
+                            lastMatch = false;
+                        }
+                        list.add(str.substring(start, i));
+                        match = false;
+                    }
+                    start = ++i;
+                    continue;
+                }
+                lastMatch = false;
+                match = true;
+                i++;
+            }
+        } else {
+            // standard case
+            while (i < len) {
+                if (separatorChars.indexOf(str.charAt(i)) >= 0) {
+                    if (match || preserveAllTokens) {
+                        lastMatch = true;
+                        if (sizePlus1++ == max) {
+                            i = len;
+                            lastMatch = false;
+                        }
+                        list.add(str.substring(start, i));
+                        match = false;
+                    }
+                    start = ++i;
+                    continue;
+                }
+                lastMatch = false;
+                match = true;
+                i++;
+            }
+        }
+        if (match || (preserveAllTokens && lastMatch)) {
+            list.add(str.substring(start, i));
+        }
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the start and end of a String.
+     * This is similar to {@link String#trim()} but allows the characters
+     * to be stripped to be controlled.</p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is <code>null</code>, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.
+     *
+     * <pre>
+     * StringUtils.strip(null, *)          = null
+     * StringUtils.strip("", *)            = ""
+     * StringUtils.strip("abc", null)      = "abc"
+     * StringUtils.strip("  abc", null)    = "abc"
+     * StringUtils.strip("abc  ", null)    = "abc"
+     * StringUtils.strip(" abc ", null)    = "abc"
+     * StringUtils.strip("  abcyx", "xyz") = "  abc"
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped String, <code>null</code> if null String input
+     */
+    public static String strip(String str, String stripChars) {
+        if (str == null || str.length() == 0) {
+            return str;
+        }
+        str = stripStart(str, stripChars);
+        return stripEnd(str, stripChars);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the start of a String.</p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is <code>null</code>, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripStart(null, *)          = null
+     * StringUtils.stripStart("", *)            = ""
+     * StringUtils.stripStart("abc", "")        = "abc"
+     * StringUtils.stripStart("abc", null)      = "abc"
+     * StringUtils.stripStart("  abc", null)    = "abc"
+     * StringUtils.stripStart("abc  ", null)    = "abc  "
+     * StringUtils.stripStart(" abc ", null)    = "abc "
+     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped String, <code>null</code> if null String input
+     */
+    public static String stripStart(String str, String stripChars) {
+        if (str == null) {
+            return null;
+        }
+        int strLen = str.length();
+        if (strLen == 0) {
+            return str;
+        }
+        int start = 0;
+        if (stripChars == null) {
+            while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
+                start++;
+            }
+        } else if (stripChars.length() == 0) {
+            return str;
+        } else {
+            while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {
+                start++;
+            }
+        }
+        return str.substring(start);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the end of a String.</p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is <code>null</code>, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripEnd(null, *)          = null
+     * StringUtils.stripEnd("", *)            = ""
+     * StringUtils.stripEnd("abc", "")        = "abc"
+     * StringUtils.stripEnd("abc", null)      = "abc"
+     * StringUtils.stripEnd("  abc", null)    = "  abc"
+     * StringUtils.stripEnd("abc  ", null)    = "abc"
+     * StringUtils.stripEnd(" abc ", null)    = " abc"
+     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped String, <code>null</code> if null String input
+     */
+    public static String stripEnd(String str, String stripChars) {
+        if (str == null) {
+            return null;
+        }
+        int end = str.length();
+        if (end == 0) {
+            return str;
+        }
+        if (stripChars == null) {
+            while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
+                end--;
+            }
+        } else if (stripChars.length() == 0) {
+            return str;
+        } else {
+            while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
+                end--;
+            }
+        }
+        return str.substring(0, end);
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/TextStripConverter.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/TextStripConverter.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/TextStripConverter.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/TextStripConverter.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.servicemix.components.util;
+
+/**
+ * Column converter for SimpleFlatFileMarshaler that strips off leading and
+ * trailing whitespaces from flat file columns
+ * 
+ * @author Mayrbaeurl
+ * @since 3.2
+ */
+public class TextStripConverter implements ContentConverter {
+
+    // Implementation methods
+    // -------------------------------------------------------------------------
+    public String convertToXml(String contents) {
+        return StringUtils.strip(contents, null);
+    }
+
+    public String convertToFlatFileContent(String contents) {
+        return contents;
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/VariableFixedLengthColumnExtractor.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/VariableFixedLengthColumnExtractor.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/VariableFixedLengthColumnExtractor.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/VariableFixedLengthColumnExtractor.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,143 @@
+/*
+ * 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.servicemix.components.util;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Column extractor for SimpleFlatFileMarshaler that can extract columns from
+ * fixed-length flat files that have a variable count of columns based on a
+ * discriminator column value
+ * 
+ * @author Mayrbaeurl
+ * @since 3.2
+ */
+public class VariableFixedLengthColumnExtractor implements ColumnExtractor {
+
+    /**
+     * Index of the discriminator column in the fixed length flat file
+     */
+    private int discriminatorIndex;
+
+    /**
+     * Index of the last column that every line of the flat file contains
+     */
+    private int lastFixedContentIndex;
+
+    /**
+     * Max count of columns
+     */
+    private int maximumColumnCount;
+
+    /**
+     * Fixed columns lengths
+     */
+    private int[] fixedColumnLengths;
+
+    /**
+     * Column lengths for discriminator values. Key is discriminator value.
+     * Value is int[] for column lengths
+     */
+    private Map variableColumnLengths;
+
+    // Implementation methods
+    // -------------------------------------------------------------------------
+    public String[] extractColumns(String lineText) {
+        String[] result = new String[maximumColumnCount];
+        int curIndex = 0;
+        for (int i = 0; i <= lastFixedContentIndex; i++) {
+            try {
+                result[i] = lineText.substring(curIndex, curIndex + this.fixedColumnLengths[i]);
+                curIndex += this.fixedColumnLengths[i];
+            } catch (StringIndexOutOfBoundsException e) {
+                return result;
+            }
+        }
+        if (result.length > this.discriminatorIndex) {
+            String discriminatorValue = result[this.discriminatorIndex];
+            if (!StringUtils.isBlank(discriminatorValue) && (this.variableColumnLengths != null)
+                            && (this.variableColumnLengths.containsKey(discriminatorValue))) {
+                int[] variableLengths = (int[]) this.variableColumnLengths.get(discriminatorValue);
+
+                int variableIndex = 0;
+                for (int i = lastFixedContentIndex + 1; i < maximumColumnCount; i++, variableIndex++) {
+                    try {
+                        if (variableLengths[variableIndex] != -1) {
+                            result[i] = lineText.substring(curIndex, curIndex + variableLengths[variableIndex]);
+
+                            curIndex += variableLengths[variableIndex];
+                        }
+                    } catch (StringIndexOutOfBoundsException e) {
+                        break;
+                    }
+                }
+            }
+        } else {
+            throw new IllegalStateException("Discriminator Column could not be read");
+        }
+        return result;
+    }
+
+    // Properties
+    // -------------------------------------------------------------------------
+    public final void setFixedColumnLengths(int[] fixedColumnLengths) {
+        this.fixedColumnLengths = fixedColumnLengths;
+    }
+
+    public final void setStringFixedColumnLengths(String[] lengths) {
+        this.fixedColumnLengths = new int[lengths.length];
+        for (int i = 0; i < lengths.length; i++) {
+            this.fixedColumnLengths[i] = Integer.parseInt(lengths[i]);
+        }
+    }
+
+    public final void setMaximumColumnCount(int maximumColumnCount) {
+        this.maximumColumnCount = maximumColumnCount;
+    }
+
+    public final void setDiscriminatorIndex(int discriminatorIndex) {
+        this.discriminatorIndex = discriminatorIndex;
+    }
+
+    public final void setLastFixedContentIndex(int lastFixedContentIndex) {
+        this.lastFixedContentIndex = lastFixedContentIndex;
+    }
+
+    public final void setVariableColumnLengths(Map variableColumnLengths) {
+        this.variableColumnLengths = variableColumnLengths;
+    }
+
+    public final void setStringEncodedVariableColumnLengths(String columnLengths) {
+        this.variableColumnLengths = null;
+        String[] entries = StringUtils.splitWorker(columnLengths, ";", -1, false);
+        if ((entries != null) && (entries.length > 0)) {
+            this.variableColumnLengths = new LinkedHashMap();
+            for (int i = 0; i < entries.length; i++) {
+                String[] colLengths = StringUtils.splitWorker(entries[i], ",", -1, true);
+                if ((colLengths != null) && (colLengths.length > 1)) {
+                    int[] lengths = new int[colLengths.length - 1];
+                    for (int j = 1; j < colLengths.length; j++) {
+                        lengths[j - 1] = Integer.parseInt(colLengths[j]);
+                    }
+                    this.variableColumnLengths.put(colLengths[0], lengths);
+                }
+            }
+        }
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/XmlEscapingConverter.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/XmlEscapingConverter.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/XmlEscapingConverter.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/components/util/XmlEscapingConverter.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,32 @@
+/*
+ * 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.servicemix.components.util;
+
+/**
+ *
+ * @author Andrew Skiba <sk...@gmail.com>
+ */
+public class XmlEscapingConverter implements ContentConverter {
+
+    public String convertToXml(String contents) {
+        return contents.replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("&", "&amp;");
+    }
+
+    public String convertToFlatFileContent(String contents) {
+        return contents.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ConstantExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ConstantExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ConstantExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ConstantExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+
+/**
+ * Represents a constant expression
+ * 
+ * @version $Revision: 426415 $
+ */
+public class ConstantExpression implements Expression {
+    private Object value;
+
+    public ConstantExpression(Object value) {
+        this.value = value;
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        return value;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/Expression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/Expression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/Expression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/Expression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+ 
+/**
+ * An expression strategy for extracting or calculating some value from a message.
+ *
+ * @version $Revision: 564374 $
+ */
+public interface Expression {
+
+    /**
+     * Evaluates the expression on the given exchange and message.
+     *
+     * @param exchange the message exchange
+     * @param message the message, typically an inbound message
+     * @return the value of the expression
+     */
+    Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException;
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionEditor.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionEditor.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionEditor.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionEditor.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,28 @@
+/*
+ * 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.servicemix.expression;
+
+import java.beans.PropertyEditorSupport;
+
+public class ExpressionEditor extends PropertyEditorSupport {
+
+    @Override
+    public void setAsText(String text) throws IllegalArgumentException {
+        setValue(new ConstantExpression(text));
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionHelper.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionHelper.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionHelper.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/ExpressionHelper.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,53 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+
+/**
+ * A helper class for working with expressions.
+ * 
+ * @version $Revision: 564374 $
+ */
+public final class ExpressionHelper {
+    
+    private ExpressionHelper() {
+    }
+
+    /**
+     * Evaluates the given expression as a string value.
+     * 
+     * @param expression the expression to evaluate
+     * @param exchange the current exchange
+     * @param message the current message
+     * @param defaultValue the default value to use if the expression is null or the value of the expression is null
+     * @return the value of the expression as a string if it is not null or the defaultValue
+     * @throws MessagingException if the expression failed to be evaluated
+     */
+    public static String asString(Expression expression, MessageExchange exchange, 
+                                  NormalizedMessage message, String defaultValue) throws MessagingException {
+        if (expression != null) {
+            Object answer = expression.evaluate(exchange, message);
+            if (answer != null) {
+                return answer.toString();
+            }
+        }
+        return defaultValue;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPBooleanXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPBooleanXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPBooleanXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPBooleanXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Evaluates an XPath expression and coerces the result into a String.
+ * 
+ * @org.apache.xbean.XBean element="xpathBoolean"
+ * 
+ * @version $Revision: 359151 $
+ */
+public class JAXPBooleanXPathExpression extends JAXPXPathExpression {
+
+    public JAXPBooleanXPathExpression() {
+    }
+
+    public JAXPBooleanXPathExpression(String xpath) throws Exception {
+        super(xpath);
+    }
+
+    public Object evaluateXPath(Object object) throws XPathExpressionException {
+        return getXPathExpression().evaluate(object, XPathConstants.BOOLEAN);
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        return evaluate(exchange, message, XPathConstants.BOOLEAN);
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPNodeSetXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPNodeSetXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPNodeSetXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPNodeSetXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,46 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Evaluates an XPath expression and coerces the result into a String.
+ * 
+ * @version $Revision: 359151 $
+ */
+public class JAXPNodeSetXPathExpression extends JAXPXPathExpression {
+
+    public JAXPNodeSetXPathExpression() {
+    }
+
+    public JAXPNodeSetXPathExpression(String xpath) throws Exception {
+        super(xpath);
+    }
+
+    public Object evaluateXPath(Object object) throws XPathExpressionException {
+        return getXPathExpression().evaluate(object, XPathConstants.NODESET);
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        return evaluate(exchange, message, XPathConstants.NODESET);
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPStringXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPStringXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPStringXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPStringXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Evaluates an XPath expression and coerces the result into a String.
+ * 
+ * @org.apache.xbean.XBean element="xpathString"
+ * 
+ * @version $Revision: 654786 $
+ */
+public class JAXPStringXPathExpression extends JAXPXPathExpression {
+
+    public JAXPStringXPathExpression() {
+    }
+
+    public JAXPStringXPathExpression(String xpath) {
+        super(xpath);
+    }
+
+    public Object evaluateXPath(Object object) throws XPathExpressionException {
+        return getXPathExpression().evaluate(object, XPathConstants.STRING);
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        return evaluate(exchange, message, XPathConstants.STRING);
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,275 @@
+/*
+ * 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.servicemix.expression;
+
+import java.io.IOException;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+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.XPathFunctionResolver;
+
+import org.xml.sax.SAXException;
+
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.springframework.beans.factory.InitializingBean;
+
+/**
+ * Evalutes an XPath expression on the given message using JAXP
+ * 
+ * @org.apache.xbean.XBean element="xpath"
+ * 
+ * @version $Revision: 654087 $
+ */
+public class JAXPXPathExpression implements Expression, InitializingBean {
+    
+    private String xpath;
+
+    private boolean useMessageContent = true;
+
+    private SourceTransformer transformer = new SourceTransformer();
+
+    private MessageVariableResolver variableResolver = new MessageVariableResolver();
+
+    private XPathExpression xPathExpression;
+
+    private XPathFunctionResolver functionResolver;
+
+    private NamespaceContext namespaceContext;
+
+    private XPathFactory factory;
+
+    public JAXPXPathExpression() {
+    }
+
+    /**
+     * A helper constructor to make a fully created expression.
+     */
+    public JAXPXPathExpression(String xpath) {
+        this.xpath = xpath;
+    }
+
+    /**
+     * Compiles the xpath expression.
+     */
+    public void afterPropertiesSet() throws XPathExpressionException {
+        if (xPathExpression == null) {
+            if (xpath == null) {
+                throw new IllegalArgumentException("You must specify the xpath property");
+            }
+
+            if (factory == null) {
+                factory = XPathFactory.newInstance();
+            }
+            XPath xpathObject = factory.newXPath();
+            xpathObject.setXPathVariableResolver(variableResolver);
+            if (functionResolver != null) {
+                xpathObject.setXPathFunctionResolver(functionResolver);
+            }
+            if (namespaceContext != null) {
+                xpathObject.setNamespaceContext(namespaceContext);
+            }
+            xPathExpression = xpathObject.compile(xpath);
+        }
+    }
+
+    /**
+     * Evaluates the XPath expression and returns the string values for the XML items described
+     * by that expression.
+     *
+     * Before evaluating the xpath expression, it will be compiled by calling
+     * the {@link #afterPropertiesSet()} method.
+     *
+     * @param exchange MessageExchange to use on MessageVariableResolver
+     * @param message  NormalizedMessage to use on MessageVariableResolver
+     *
+     * @return Object  Contains the string values for the XML items described by the provided XPath
+     *                 expression
+     */
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        return evaluate(exchange, message, XPathConstants.STRING);
+    }
+
+    /**
+     * Evaluates the XPath expression and the XML items described by that expression. The type is
+     * determined by the returnType parameter.  
+     *
+     * Before evaluating the xpath expression, it will be compiled by calling
+     * the {@link #afterPropertiesSet()} method.
+     *
+     * @param exchange    MessageExchange to use on MessageVariableResolver
+     * @param message     NormalizedMessage to use on MessageVariableResolver
+     * @param returnType  QName as defined by javax.xml.xpath.XPathConstants that describes the
+     *                    desired type of the object to be retuned
+     *
+     * @return Object    Contains the XML items described by the provided XPath expression. The type is
+     *                   determined by the returnType parameter.
+     */
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message, QName returnType) throws MessagingException {
+        try {
+            afterPropertiesSet();
+            Object object = getXMLNode(exchange, message);
+            synchronized (this) {
+                variableResolver.setExchange(exchange);
+                variableResolver.setMessage(message);
+                return evaluateXPath(object, returnType);
+            }
+        } catch (TransformerException e) {
+            throw new MessagingException(e);
+        } catch (XPathExpressionException e) {
+            throw new MessagingException(e);
+        } catch (ParserConfigurationException e) {
+            throw new MessagingException(e);
+        } catch (IOException e) {
+            throw new MessagingException(e);
+        } catch (SAXException e) {
+            throw new MessagingException(e);
+        }
+    }
+
+    // Properties
+    // -------------------------------------------------------------------------
+    public String getXPath() {
+        return xpath;
+    }
+
+    public void setXPath(String xp) {
+        this.xpath = xp;
+    }
+
+    public boolean isUseMessageContent() {
+        return useMessageContent;
+    }
+
+    /**
+     * Specifies whether or not the XPath expression uses the message content.
+     * 
+     * By default, this property is <code>true</code>, but you can set it to
+     * <code>false</code> to avoid that the message content is converted to
+     * {@link StringSource}
+     * 
+     * @param useMessageContent
+     *            specify <code>false</code> if this expression does not
+     *            access the message content
+     */
+    public void setUseMessageContent(boolean useMessageContent) {
+        this.useMessageContent = useMessageContent;
+    }
+
+    public SourceTransformer getTransformer() {
+        return transformer;
+    }
+
+    public void setTransformer(SourceTransformer transformer) {
+        this.transformer = transformer;
+    }
+
+    public MessageVariableResolver getVariableResolver() {
+        return variableResolver;
+    }
+
+    public void setVariableResolver(MessageVariableResolver variableResolver) {
+        this.variableResolver = variableResolver;
+    }
+
+    public XPathFactory getFactory() {
+        return factory;
+    }
+
+    public void setFactory(XPathFactory factory) {
+        this.factory = factory;
+    }
+
+    public XPathFunctionResolver getFunctionResolver() {
+        return functionResolver;
+    }
+
+    public void setFunctionResolver(XPathFunctionResolver functionResolver) {
+        this.functionResolver = functionResolver;
+    }
+
+    public NamespaceContext getNamespaceContext() {
+        return namespaceContext;
+    }
+
+    public void setNamespaceContext(NamespaceContext namespaceContext) {
+        this.namespaceContext = namespaceContext;
+    }
+
+    // Implementation methods
+    // -------------------------------------------------------------------------
+    protected Object evaluateXPath(Object object) throws XPathExpressionException {
+        return xPathExpression.evaluate(object);
+    }
+
+    protected Object evaluateXPath(Object object, QName returnType) throws XPathExpressionException {
+        return xPathExpression.evaluate(object, returnType);
+    }
+
+    protected XPathExpression getXPathExpression() {
+        return xPathExpression;
+    }
+
+    protected Object getXMLNode(MessageExchange exchange, NormalizedMessage message) throws TransformerException, MessagingException,
+                    ParserConfigurationException, IOException, SAXException {
+        // ensure re-readability of the content if the expression also needs to
+        // access the content
+        if (useMessageContent) {
+            enableContentRereadability(message);
+        }
+        return transformer.toDOMNode(message);
+    }
+
+    /**
+     * Convert the given {@link NormalizedMessage} instance's content to a re-readable {@link javax.xml.transform.Source} This allows the
+     * content to be read more than once (e.g. for XPath evaluation or auditing).
+     *
+     * @param message
+     *            the {@link NormalizedMessage} to convert the content for
+     * @throws MessagingException
+     */
+    public void enableContentRereadability(NormalizedMessage message) throws MessagingException {
+        if (message.getContent() instanceof StreamSource) {
+            try {
+                String content = transformer.contentToString(message);
+                if (content != null) {
+                    message.setContent(new StringSource(content));
+                }
+            } catch (TransformerException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (ParserConfigurationException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (IOException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (SAXException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            }
+        }
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathXStreamExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathXStreamExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathXStreamExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JAXPXPathXStreamExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,91 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.xpath.XPathConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.xml.DomReader;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.impl.Log4JLogger;
+
+
+/**
+ *
+ * @author Andrew Skiba <sk...@gmail.com>
+ */
+public class JAXPXPathXStreamExpression extends JAXPXPathExpression {
+
+    protected Log logger = new Log4JLogger(JAXPXPathXStreamExpression.class.getName());
+    private XStream xStream;
+
+    public JAXPXPathXStreamExpression() {
+        super();
+    }
+
+    /**
+     * A helper constructor to make a fully created expression.
+     * @param xpath 
+     */
+    public JAXPXPathXStreamExpression(String xpath) {
+        super(xpath);
+    }
+
+
+    @Override
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        Object node = super.evaluate(exchange, message, XPathConstants.NODE);
+        HierarchicalStreamReader streamReader;
+        if (node instanceof Document) {
+            streamReader = new DomReader((Document) node);
+        } else if (node instanceof Element) {
+            streamReader = new DomReader((Element) node);
+        } else {
+            throw new IllegalArgumentException("DOMResult contains neither Document nor Element: " + node.getClass().getName());
+        }
+        return getXStream().unmarshal(streamReader);
+    }
+
+    public XStream getXStream() {
+        if (xStream == null) {
+            xStream = createXStream();
+        }
+        return xStream;
+    }
+
+    public void setXStream(XStream xStream) {
+        this.xStream = xStream;
+    }
+
+    //FIXME: copied as-is from XStreamMarshaler
+    private XStream createXStream() {
+        XStream answer = new XStream();
+        try {
+            answer.alias("invoke", Class.forName("org.logicblaze.lingo.LingoInvocation"));
+        } catch (ClassNotFoundException e) {
+            // Ignore
+        }
+        return answer;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenStringXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenStringXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenStringXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenStringXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,39 @@
+/*
+ * 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.servicemix.expression;
+
+import org.jaxen.JaxenException;
+
+/**
+ * An {@link Expression} which evaluates an XPath expression using  <a href="http://jaxen.org/"/>Jaxen</a> and
+ * returns the String value.
+ *
+ * @version $Revision: 450003 $
+ */
+public class JaxenStringXPathExpression extends JaxenXPathExpression {
+
+    public JaxenStringXPathExpression() {
+    }
+    
+    public JaxenStringXPathExpression(String xpath) throws Exception {
+        super(xpath);
+    }
+
+    protected Object evaluateXPath(Object object) throws JaxenException {
+        return getXpathObject().stringValueOf(object);
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenVariableContext.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenVariableContext.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenVariableContext.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenVariableContext.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,111 @@
+/*
+ * 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.servicemix.expression;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.NormalizedMessage;
+
+import org.jaxen.UnresolvableException;
+import org.jaxen.VariableContext;
+
+/**
+ * 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: 564374 $
+ */
+public class JaxenVariableContext implements VariableContext {
+    public static final String MESSAGE_NAMESPACE = "http://servicemix.org/xml/variables/message";
+
+    public static final String EXCHANGE_NAMESPACE = "http://servicemix.org/xml/variables/exchange";
+
+    public static final String SYSTEM_PROPERTIES_NAMESPACE = "http://servicemix.org/xml/variables/system-properties";
+
+    public static final String ENVIRONMENT_VARIABLES_NAMESPACE = "http://servicemix.org/xml/variables/environment-variables";
+
+    private MessageExchange exchange;
+
+    private NormalizedMessage message;
+
+    private Map variables;
+
+    public MessageExchange getExchange() {
+        return exchange;
+    }
+
+    public void setExchange(MessageExchange exchange) {
+        this.exchange = exchange;
+    }
+
+    public NormalizedMessage getMessage() {
+        return message;
+    }
+
+    public void setMessage(NormalizedMessage message) {
+        this.message = message;
+    }
+
+    public Map getVariables() {
+        return variables;
+    }
+
+    /**
+     * Allows other variables to be added to the variable scope
+     *
+     * @param variables
+     */
+    public void setVariables(Map variables) {
+        this.variables = variables;
+    }
+
+    public Object getVariableValue(String uri, String prefix, String localPart) throws UnresolvableException {
+        Object answer = null;
+
+        if (uri == null || uri.length() == 0) {
+            answer = message.getProperty(localPart);
+            if (answer == null) {
+                answer = exchange.getProperty(localPart);
+            }
+        } else if (uri.equals(MESSAGE_NAMESPACE)) {
+            answer = message.getProperty(localPart);
+        } else if (uri.equals(EXCHANGE_NAMESPACE)) {
+            answer = message.getProperty(localPart);
+        } else if (uri.equals(SYSTEM_PROPERTIES_NAMESPACE)) {
+            answer = System.getProperty(localPart);
+        } else if (uri.equals(ENVIRONMENT_VARIABLES_NAMESPACE)) {
+            answer = System.getProperty(System.getProperty(localPart));
+        }
+        return answer;
+    }
+
+    /**
+     * Allows a variable to be specified
+     *
+     * @param localPart
+     * @param value
+     */
+    public void setVariableValue(String localPart, Object value) {
+        if (variables == null) {
+            variables = new HashMap();
+        }
+        variables.put(localPart, value);
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/JaxenXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,279 @@
+/*
+ * 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.servicemix.expression;
+
+import java.io.IOException;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.SAXException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.jaxen.FunctionContext;
+import org.jaxen.JaxenException;
+import org.jaxen.NamespaceContext;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.springframework.beans.factory.InitializingBean;
+
+/**
+ * Evalutes an XPath expression on the given message using <a
+ * href="http://jaxen.org/"/>Jaxen</a>
+ * 
+ * @version $Revision: 564900 $
+ */
+public class JaxenXPathExpression implements Expression, InitializingBean {
+    
+    private static final transient Log LOG = LogFactory.getLog(JaxenXPathExpression.class);
+
+    private String xpath;
+
+    private boolean useMessageContent = true;
+
+    private SourceTransformer transformer = new SourceTransformer();
+
+    private JaxenVariableContext variableContext = new JaxenVariableContext();
+
+    private XPath xpathObject;
+
+    private NamespaceContext namespaceContext;
+
+    private FunctionContext functionContext;
+
+    public JaxenXPathExpression() {
+    }
+
+    /**
+     * A helper constructor to make a fully created expression. This constructor
+     * will call the {@link #afterPropertiesSet()} method to ensure this POJO is
+     * properly constructed.
+     */
+    public JaxenXPathExpression(String xpath) throws Exception {
+        this.xpath = xpath;
+        init();
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        init();
+    }
+
+    private void init() throws JaxenException {
+        if (xpathObject == null) {
+            if (xpath == null) {
+                throw new IllegalArgumentException("You must specify the xpath property");
+            }
+            xpathObject = createXPath(xpath);
+            xpathObject.setVariableContext(variableContext);
+            if (namespaceContext != null) {
+                xpathObject.setNamespaceContext(namespaceContext);
+            }
+            if (functionContext != null) {
+                xpathObject.setFunctionContext(functionContext);
+            }
+        }
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        try {
+            Object object = getXMLNode(exchange, message);
+            if (object == null) {
+                return null;
+            }
+            synchronized (this) {
+                variableContext.setExchange(exchange);
+                variableContext.setMessage(message);
+                return evaluateXPath(object);
+            }
+        } catch (TransformerException e) {
+            throw new MessagingException(e);
+        } catch (JaxenException e) {
+            throw new MessagingException(e);
+        } catch (ParserConfigurationException e) {
+            throw new MessagingException(e);
+        } catch (IOException e) {
+            throw new MessagingException(e);
+        } catch (SAXException e) {
+            throw new MessagingException(e);
+        }
+    }
+
+    public boolean matches(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        try {
+            Object object = getXMLNode(exchange, message);
+            if (object == null) {
+                return false;
+            }
+            synchronized (this) {
+                variableContext.setExchange(exchange);
+                variableContext.setMessage(message);
+                return evaluateXPathAsBoolean(object);
+            }
+        } catch (TransformerException e) {
+            throw new MessagingException(e);
+        } catch (JaxenException e) {
+            throw new MessagingException(e);
+        } catch (ParserConfigurationException e) {
+            throw new MessagingException(e);
+        } catch (IOException e) {
+            throw new MessagingException(e);
+        } catch (SAXException e) {
+            throw new MessagingException(e);
+        }
+    }
+
+    // Properties
+    // -------------------------------------------------------------------------
+    public XPath getXpathObject() {
+        return xpathObject;
+    }
+
+    public void setXpathObject(XPath xpathObject) {
+        this.xpathObject = xpathObject;
+    }
+
+    public String getXpath() {
+        return xpath;
+    }
+
+    public void setXpath(String xpath) {
+        this.xpath = xpath;
+    }
+
+    public boolean isUseMessageContent() {
+        return useMessageContent;
+    }
+
+    /**
+     * Specifies whether or not the XPath expression uses the message content.
+     * 
+     * By default, this property is <code>true</code>, but you can set it to
+     * <code>false</code> to avoid that the message content is converted to
+     * {@link StringSource}
+     * 
+     * @param useMessageContent
+     *            specify <code>false</code> if this expression does not
+     *            access the message content
+     */
+    public void setUseMessageContent(boolean useMessageContent) {
+        this.useMessageContent = useMessageContent;
+    }
+
+    public SourceTransformer getTransformer() {
+        return transformer;
+    }
+
+    public void setTransformer(SourceTransformer transformer) {
+        this.transformer = transformer;
+    }
+
+    public JaxenVariableContext getVariableContext() {
+        return variableContext;
+    }
+
+    public void setVariableContext(JaxenVariableContext variableContext) {
+        this.variableContext = variableContext;
+    }
+
+    public NamespaceContext getNamespaceContext() {
+        return namespaceContext;
+    }
+
+    public void setNamespaceContext(NamespaceContext namespaceContext) {
+        this.namespaceContext = namespaceContext;
+    }
+
+    public FunctionContext getFunctionContext() {
+        return functionContext;
+    }
+
+    public void setFunctionContext(FunctionContext functionContext) {
+        this.functionContext = functionContext;
+    }
+
+    // Implementation methods
+    // -------------------------------------------------------------------------
+    protected final XPath createXPath(String xp) throws JaxenException {
+        return new DOMXPath(xp);
+    }
+
+    protected Object evaluateXPath(Object object) throws JaxenException {
+        return xpathObject.evaluate(object);
+    }
+
+    protected boolean evaluateXPathAsBoolean(Object object) throws JaxenException {
+        return xpathObject.booleanValueOf(object);
+    }
+
+    protected Object getXMLNode(MessageExchange exchange, NormalizedMessage message) throws TransformerException, MessagingException,
+                    ParserConfigurationException, IOException, SAXException {
+        Node node = null;
+        // ensure re-readability of the content if the expression also needs to
+        // access the content
+        if (useMessageContent) {
+            enableContentRereadability(message);
+        }
+        if (message != null) {
+            node = transformer.toDOMNode(message);
+        } else {
+            LOG.warn("Null message for exchange: " + exchange);
+        }
+        if (node == null) {
+            // lets make an empty document to avoid Jaxen throwing a
+            // NullPointerException
+            node = transformer.createDocument();
+        }
+        return node;
+    }
+
+    /**
+     * Convert the given {@link NormalizedMessage} instance's content to a re-readable {@link javax.xml.transform.Source} This allows the
+     * content to be read more than once (e.g. for XPath evaluation or auditing).
+     *
+     * @param message
+     *            the {@link NormalizedMessage} to convert the content for
+     * @throws MessagingException
+     */
+    public void enableContentRereadability(NormalizedMessage message) throws MessagingException {
+        if (message.getContent() instanceof StreamSource) {
+            try {
+                String content = transformer.contentToString(message);
+                if (content != null) {
+                    message.setContent(new StringSource(content));
+                }
+            } catch (TransformerException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (ParserConfigurationException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (IOException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            } catch (SAXException e) {
+                throw new MessagingException("Unable to convert message content into StringSource", e);
+            }
+        }
+    }
+
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/MessageVariableResolver.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/MessageVariableResolver.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/MessageVariableResolver.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/MessageVariableResolver.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,72 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+
+/**
+ * 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: 564374 $
+ */
+public class MessageVariableResolver implements XPathVariableResolver {
+    public static final String SYSTEM_PROPERTIES_NAMESPACE = "http://servicemix.org/xml/variables/system-properties";
+    public static final String ENVIRONMENT_VARIABLES = "http://servicemix.org/xml/variables/environment-variables";
+
+    private MessageExchange exchange;
+    private NormalizedMessage message;
+
+    public MessageExchange getExchange() {
+        return exchange;
+    }
+
+    public void setExchange(MessageExchange exchange) {
+        this.exchange = exchange;
+    }
+
+    public NormalizedMessage getMessage() {
+        return message;
+    }
+
+    public void setMessage(NormalizedMessage message) {
+        this.message = message;
+    }
+
+    public Object resolveVariable(QName name) {
+        // should we use other namespaces maybe?
+        String uri = name.getNamespaceURI();
+        String localPart = name.getLocalPart();
+
+        Object answer = null;
+
+        if (uri == null || uri.length() == 0) {
+            answer = message.getProperty(localPart);
+            if (answer == null) {
+                answer = exchange.getProperty(localPart);
+            }
+        } else if (uri.equals(SYSTEM_PROPERTIES_NAMESPACE)) {
+            answer = System.getProperty(localPart);
+        } else if (uri.equals(ENVIRONMENT_VARIABLES)) {
+            answer = System.getProperty(System.getProperty(localPart));
+        }
+        return answer;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/PropertyExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/PropertyExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/PropertyExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/PropertyExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,82 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+
+/**
+ * A simple expression which returns the value of a property on the message.
+ *
+ * @version $Revision: 451186 $
+ */
+public class PropertyExpression implements Expression {
+    private String property;
+    private Object defaultValue;
+    
+    public PropertyExpression() {
+    }
+
+    public PropertyExpression(String property) {
+        this.property = property;
+    }
+
+    public PropertyExpression(String property, Object defaultValue) {
+        this.property = property;
+        this.defaultValue = defaultValue;
+    }
+
+    /**
+     * @return the defaultValue
+     */
+    public Object getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * @param defaultValue the defaultValue to set
+     */
+    public void setDefaultValue(Object defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    /**
+     * @return the property
+     */
+    public String getProperty() {
+        return property;
+    }
+
+    /**
+     * @param property the property to set
+     */
+    public void setProperty(String property) {
+        this.property = property;
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        Object answer = message.getProperty(property);
+        if (answer == null) {
+            answer = exchange.getProperty(property);
+            if (answer == null) {
+                answer = defaultValue;
+            }
+        }
+        return answer;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansStringXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansStringXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansStringXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansStringXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.expression;
+
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+
+/**
+ * An {@link Expression} which evaluates an XPath expression using <a href="http://xmlbeans.apache.org/">XMLBeans</a> and
+ * returns the String value.
+ *
+ * @version $Revision: 564374 $
+ */
+public class XMLBeansStringXPathExpression extends XMLBeansXPathExpression {
+    public XMLBeansStringXPathExpression(String xpath) {
+        super(xpath);
+    }
+
+    protected Object evaluateXPath(XmlObject object, String xpath, XmlOptions options) {
+        XmlObject[] xmlObjects = object.selectPath(xpath);
+        if (xmlObjects == null || xmlObjects.length == 0) {
+            return "";
+        } else if (xmlObjects.length == 1) {
+            return asString(xmlObjects[0]);
+        } else {
+            StringBuffer buffer = new StringBuffer();
+            for (int i = 0; i < xmlObjects.length; i++) {
+                XmlObject xmlObject = xmlObjects[i];
+                buffer.append(asString(xmlObject));
+            }
+            return buffer.toString();
+        }
+    }
+
+    protected String asString(XmlObject xmlObject) {
+        XmlCursor cursor = xmlObject.newCursor();
+        return cursor.getTextValue();
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansXPathExpression.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansXPathExpression.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansXPathExpression.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/XMLBeansXPathExpression.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,69 @@
+/*
+ * 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.servicemix.expression;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.sax.SAXResult;
+
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.XmlSaxHandler;
+
+/**
+ * An {@link Expression} which evaluates an XPath expression using <a href="http://xmlbeans.apache.org/">XMLBeans</a>
+ *
+ * @version $Revision: 564374 $
+ */
+public class XMLBeansXPathExpression implements Expression {
+    
+    private String xpath;
+
+    private XmlOptions options = new XmlOptions();
+
+    private SourceTransformer transformer = new SourceTransformer();
+
+    public XMLBeansXPathExpression(String xp) {
+        this.xpath = xp;
+    }
+
+    public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {
+        try {
+            XmlSaxHandler handler = XmlObject.Factory.newXmlSaxHandler();
+            SAXResult result = new SAXResult(handler.getContentHandler());
+            transformer.toResult(message.getContent(), result);
+            XmlObject object = handler.getObject();
+            return evaluateXPath(object, xpath, options);
+        } catch (TransformerException e) {
+            throw new MessagingException(e);
+        } catch (XmlException e) {
+            throw new MessagingException(e);
+        }
+    }
+
+    protected Object evaluateXPath(XmlObject object, String xp, XmlOptions opts) {
+        XmlObject[] xmlObjects = object.selectPath(xp, opts);
+        if (xmlObjects.length == 1) {
+            return xmlObjects[0];
+        }
+        return xmlObjects;
+    }
+}

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/package.html
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/package.html?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/package.html (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/expression/package.html Mon Aug 25 03:57:27 2008
@@ -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>
+
+A pluggable expression library.
+
+</body>
+</html>

Added: servicemix/utils/trunk/src/main/java/org/apache/servicemix/jbi/jaxp/BytesSource.java
URL: http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/jbi/jaxp/BytesSource.java?rev=688693&view=auto
==============================================================================
--- servicemix/utils/trunk/src/main/java/org/apache/servicemix/jbi/jaxp/BytesSource.java (added)
+++ servicemix/utils/trunk/src/main/java/org/apache/servicemix/jbi/jaxp/BytesSource.java Mon Aug 25 03:57:27 2008
@@ -0,0 +1,60 @@
+/*
+ * 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.servicemix.jbi.jaxp;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.xml.transform.stream.StreamSource;
+
+/**
+ * A helper class which provides a JAXP {@link javax.xml.transform.Source} from a byte[]
+ * which can be read as many times as required.
+ *
+ * @version $Revision: 564607 $
+ */
+public class BytesSource extends StreamSource {
+    private byte[] data;
+
+    public BytesSource(byte[] data) {
+        this.data = data;
+    }
+
+    public BytesSource(byte[] data, String systemId) {
+        this.data = data;
+        setSystemId(systemId);
+    }
+
+    public InputStream getInputStream() {
+        return new ByteArrayInputStream(data);
+    }
+
+    public Reader getReader() {
+        return new InputStreamReader(getInputStream());
+    }
+
+    public byte[] getData() {
+        return data;
+    }
+
+    public String toString() {
+        return "BytesSource[" + new String(data) + "]";
+    }
+
+}