You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by as...@apache.org on 2012/11/05 10:43:02 UTC

svn commit: r1405730 - in /cxf/trunk: rt/core/src/main/java/org/apache/cxf/feature/ rt/core/src/main/java/org/apache/cxf/feature/transform/ rt/core/src/test/java/org/apache/cxf/feature/ rt/core/src/test/java/org/apache/cxf/feature/transform/ systests/u...

Author: ashakirin
Date: Mon Nov  5 09:43:01 2012
New Revision: 1405730

URL: http://svn.apache.org/viewvc?rev=1405730&view=rev
Log:
Initial contribution of XSLT Feature

Added:
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java   (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java   (with props)
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java   (with props)
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml   (with props)
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl   (with props)
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java   (with props)
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java   (with props)
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java   (with props)
    cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java   (with props)
    cxf/trunk/systests/uncategorized/src/test/resources/request.xsl   (with props)
    cxf/trunk/systests/uncategorized/src/test/resources/response.xsl   (with props)

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,81 @@
+/**
+ * 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.cxf.feature.transform;
+
+
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+
+
+/**
+ * Creates an XMLStreamReader from the InputStream on the Message.
+ */
+public abstract class AbstractXSLTInterceptor extends AbstractPhaseInterceptor<Message> {
+    private static final TransformerFactory TRANSFORM_FACTORIY = TransformerFactory.newInstance();
+
+    private String contextPropertyName;
+    private final Templates xsltTemplate;
+        
+    public AbstractXSLTInterceptor(String phase, Class<?> before, Class<?> after, String xsltPath) {
+        super(phase);
+        if (before != null) {
+            addBefore(before.getName());
+        }
+        if (after != null) {
+            addAfter(after.getName());
+        }
+        
+        try {
+            InputStream xsltStream = ClassLoaderUtils.getResourceAsStream(xsltPath, this.getClass());
+            if (xsltStream == null) {
+                throw new IllegalArgumentException("Cannot load XSLT from path: " + xsltPath);
+            }
+            Source xsltSource = new StreamSource(xsltStream);
+            xsltTemplate = TRANSFORM_FACTORIY.newTemplates(xsltSource);
+        } catch (TransformerConfigurationException e) {
+            throw new IllegalArgumentException(
+                                               String.format("Cannot create XSLT template from path: %s, error: ",
+                                                             xsltPath, e.getException()), e);
+        }        
+    }
+
+    public void setContextPropertyName(String propertyName) {
+        contextPropertyName = propertyName;
+    }
+
+    protected boolean checkContextProperty(Message message) {
+        return contextPropertyName != null 
+            && !MessageUtils.getContextualBoolean(message, contextPropertyName, false);
+    }
+    
+    protected Templates getXSLTTemplate() {
+        return xsltTemplate;
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/AbstractXSLTInterceptor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties Mon Nov  5 09:43:01 2012
@@ -0,0 +1,25 @@
+#
+#
+#    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.
+#
+#
+STAX_COPY=Could not copy XML stream: {0}.
+STREAM_COPY=Could not copy stream: {0}.
+READER_COPY=Could not copy reader: {0}.
+GET_CACHED_INPUT_STREAM=Could not get cached input stream: {0}.
+XML_TRANSFORM=XSL transformation error: {0}.

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/Messages.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,64 @@
+/**
+ * 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.cxf.feature.transform;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.feature.AbstractFeature;
+import org.apache.cxf.interceptor.InterceptorProvider;
+import org.apache.cxf.interceptor.StaxInInterceptor;
+import org.apache.cxf.interceptor.StaxOutInterceptor;
+import org.apache.cxf.phase.Phase;
+
+/**
+ * This class defines a feature is used to transform message using XSLT script. 
+ * If this feature is present and inXSLTPath/outXLSTPath are initialised,
+ * client and endpoint will transform incoming and outgoing messages correspondingly. 
+ * Attention: actually the feature breaks streaming 
+ * (can be fixed in further versions when XSLT engine supports XML stream). 
+ */
+@NoJSR250Annotations
+public class XSLTFeature extends AbstractFeature {
+    private String inXSLTPath;
+    private String outXSLTPath;
+    
+    @Override
+    protected void initializeProvider(InterceptorProvider provider, Bus bus) {
+        if (inXSLTPath != null) {
+            XSLTInInterceptor in = new XSLTInInterceptor(Phase.POST_STREAM, StaxInInterceptor.class, null, inXSLTPath);
+            provider.getInInterceptors().add(in);            
+        }
+        
+        if (outXSLTPath != null) {
+            XSLTOutInterceptor out = new XSLTOutInterceptor(Phase.PRE_STREAM, StaxOutInterceptor.class, null,
+                                                            outXSLTPath);
+            provider.getOutInterceptors().add(out);            
+            provider.getOutFaultInterceptors().add(out);            
+        }
+    }
+
+    public void setInXSLTPath(String inXSLTPath) {
+        this.inXSLTPath = inXSLTPath;
+    }
+
+    public void setOutXSLTPath(String outXSLTPath) {
+        this.outXSLTPath = outXSLTPath;
+    }
+
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTFeature.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,119 @@
+/**
+ * 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.cxf.feature.transform;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.StaxUtils;
+
+
+/** Class provides XSLT transformation of incoming message.
+ * Actually it breaks streaming (can be fixed in further versions when XSLT engine supports XML stream)
+ */
+public class XSLTInInterceptor extends AbstractXSLTInterceptor {
+    private static final Logger LOG = LogUtils.getL7dLogger(XSLTInInterceptor.class);    
+
+    public XSLTInInterceptor(String phase, Class<?> before, Class<?> after, String xsltPath) {
+        super(phase, before, after, xsltPath);
+    }
+
+    @Override
+    public void handleMessage(Message message) {
+        if (checkContextProperty(message)) {
+            return;
+        }
+
+        // 1. Try to get and transform XMLStreamReader message content
+        XMLStreamReader xReader = message.getContent(XMLStreamReader.class);
+        if (xReader != null) {
+            transformXReader(message, xReader);
+        } else {
+            // 2. Try to get and transform InputStream message content
+            InputStream is = message.getContent(InputStream.class);
+            if (is != null) {
+                transformIS(message, is);
+            } else {
+                // 3. Try to get and transform Reader message content (actually used for JMS TextMessage)
+                Reader reader = message.getContent(Reader.class);
+                if (reader != null) {
+                    transformReader(message, reader);
+                }
+            }
+        }
+    }
+
+    protected void transformXReader(Message message, XMLStreamReader xReader) {
+        CachedOutputStream cachedOS = new CachedOutputStream();
+        try {
+            StaxUtils.copy(xReader, cachedOS);
+            InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), cachedOS.getInputStream());
+            XMLStreamReader transformedReader = StaxUtils.createXMLStreamReader(transformedIS);
+            message.setContent(XMLStreamReader.class, transformedReader);
+        } catch (XMLStreamException e) {
+            throw new Fault("STAX_COPY", LOG, e, e.getMessage());
+        } catch (IOException e) {
+            throw new Fault("GET_CACHED_INPUT_STREAM", LOG, e, e.getMessage());
+        } finally {
+            StaxUtils.close(xReader);
+            try {
+                cachedOS.close();
+            } catch (IOException e) {
+                LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+            }
+        }
+    }
+    
+    protected void transformIS(Message message, InputStream is) {
+        try {
+            InputStream transformedIS = XSLTUtils.transform(getXSLTTemplate(), is);
+            message.setContent(InputStream.class, transformedIS);
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+                LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+            }
+        }
+    }
+
+    protected void transformReader(Message message, Reader reader) {
+        try {
+            Reader transformedReader = XSLTUtils.transform(getXSLTTemplate(), reader);
+            message.setContent(Reader.class, transformedReader);
+        } finally {
+            try {
+                reader.close();
+            } catch (IOException e) {
+                LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+            }
+        }
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTInInterceptor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,199 @@
+/**
+ * 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.cxf.feature.transform;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Templates;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.CachedOutputStreamCallback;
+import org.apache.cxf.io.CachedWriter;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
+import org.apache.cxf.staxutils.StaxUtils;
+
+/** Class provides XSLT transformation of outgoing message.
+ * Actually it breaks streaming (can be fixed in further versions when XSLT engine supports XML stream)
+ */
+public class XSLTOutInterceptor extends AbstractXSLTInterceptor {
+    private static final Logger LOG = LogUtils.getL7dLogger(XSLTOutInterceptor.class);
+
+    public XSLTOutInterceptor(String phase, Class<?> before, Class<?> after, String xsltPath) {
+        super(phase, before, after, xsltPath);
+    }
+
+    @Override
+    public void handleMessage(Message message) {
+        if (checkContextProperty(message)) {
+            return;
+        }
+
+        // 1. Try to get and transform XMLStreamWriter message content
+        XMLStreamWriter xWriter = message.getContent(XMLStreamWriter.class);
+        if (xWriter != null) {
+            transformXWriter(message, xWriter);
+        } else {
+            // 2. Try to get and transform OutputStream message content
+            OutputStream out = message.getContent(OutputStream.class);
+            if (out != null) {
+                transformOS(message, out);
+            } else {
+                // 3. Try to get and transform Writer message content (actually used for JMS TextMessage)
+                Writer writer = message.getContent(Writer.class);
+                if (writer != null) {
+                    transformWriter(message, writer);
+                }
+            }
+        }
+    }
+
+    protected void transformXWriter(Message message, XMLStreamWriter xWriter) {
+        CachedWriter writer = new CachedWriter();
+        XMLStreamWriter delegate = StaxUtils.createXMLStreamWriter(writer);
+        XSLTStreamWriter wrapper = new XSLTStreamWriter(getXSLTTemplate(), writer, delegate, xWriter);
+        message.setContent(XMLStreamWriter.class, wrapper);
+        message.put(AbstractOutDatabindingInterceptor.DISABLE_OUTPUTSTREAM_OPTIMIZATION,
+                    Boolean.TRUE);
+    }
+
+    protected void transformOS(Message message, OutputStream out) {
+        CachedOutputStream wrapper = new CachedOutputStream();
+        CachedOutputStreamCallback callback = new XSLTCachedOutputStreamCallback(getXSLTTemplate(), out);
+        wrapper.registerCallback(callback);
+        message.setContent(OutputStream.class, wrapper);
+    }
+
+    protected void transformWriter(Message message, Writer writer) {
+        XSLTCachedWriter wrapper = new XSLTCachedWriter(getXSLTTemplate(), writer);
+        message.setContent(Writer.class, wrapper);
+    }
+
+
+    public static class XSLTStreamWriter extends DelegatingXMLStreamWriter {
+        private final Templates xsltTemplate;
+        private final CachedWriter cachedWriter;
+        private final XMLStreamWriter origXWriter;
+
+        public XSLTStreamWriter(Templates xsltTemplate, CachedWriter cachedWriter,
+                                XMLStreamWriter delegateXWriter, XMLStreamWriter origXWriter) {
+            super(delegateXWriter);
+            this.xsltTemplate = xsltTemplate;
+            this.cachedWriter = cachedWriter;
+            this.origXWriter = origXWriter;
+        }
+
+        @Override
+        public void close() {
+            Reader transformedReader = null;
+            try {
+                super.flush();
+                transformedReader = XSLTUtils.transform(xsltTemplate, cachedWriter.getReader());
+                StaxUtils.copy(new StreamSource(transformedReader), origXWriter);
+            } catch (XMLStreamException e) {
+                throw new Fault("STAX_COPY", LOG, e, e.getMessage());
+            } catch (IOException e) {
+                throw new Fault("GET_CACHED_INPUT_STREAM", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    if (transformedReader != null) {
+                        transformedReader.close();
+                    }
+                    cachedWriter.close();
+                    StaxUtils.close(origXWriter);
+                    super.close();
+                } catch (Exception e) {
+                    LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    public static class XSLTCachedOutputStreamCallback implements CachedOutputStreamCallback {
+        private final Templates xsltTemplate;
+        private final OutputStream origStream;
+
+        public XSLTCachedOutputStreamCallback(Templates xsltTemplate, OutputStream origStream) {
+            this.xsltTemplate = xsltTemplate;
+            this.origStream = origStream;
+        }
+
+        @Override
+        public void onFlush(CachedOutputStream wrapper) {            
+        }
+
+        @Override
+        public void onClose(CachedOutputStream wrapper) {
+            InputStream transformedStream = null;
+            try {
+                transformedStream = XSLTUtils.transform(xsltTemplate, wrapper.getInputStream());
+                IOUtils.copyAndCloseInput(transformedStream, origStream);
+            } catch (IOException e) {
+                throw new Fault("STREAM_COPY", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    origStream.close();
+                } catch (IOException e) {
+                    LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    public static class XSLTCachedWriter extends CachedWriter {
+        private final Templates xsltTemplate;
+        private final Writer origWriter;
+
+        public XSLTCachedWriter(Templates xsltTemplate, Writer origWriter) {
+            this.xsltTemplate = xsltTemplate;
+            this.origWriter = origWriter;
+        }
+
+        @Override
+        protected void doClose() {
+            Reader transformedReader = null;
+            try {
+                transformedReader = XSLTUtils.transform(xsltTemplate, getReader());
+                IOUtils.copyAndCloseInput(transformedReader, origWriter, IOUtils.DEFAULT_BUFFER_SIZE);
+            } catch (IOException e) {
+                throw new Fault("READER_COPY", LOG, e, e.getMessage());
+            } finally {
+                try {
+                    origWriter.close();
+                } catch (IOException e) {
+                    LOG.warning("Cannot close stream after transformation: " + e.getMessage());
+                }
+            }
+        }
+    }
+
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTOutInterceptor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,95 @@
+/**
+ * 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.cxf.feature.transform;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.logging.Logger;
+
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.CachedWriter;
+
+public final class XSLTUtils {
+    private static final Logger LOG = LogUtils.getL7dLogger(XSLTUtils.class);
+
+    private XSLTUtils() {
+
+    }
+
+    public static InputStream transform(Templates xsltTemplate, InputStream in) {
+        try {
+            StreamSource beforeSource = new StreamSource(in);
+            CachedOutputStream out = new CachedOutputStream();
+
+            Transformer trans = xsltTemplate.newTransformer();
+            trans.transform(beforeSource, new StreamResult(out));
+
+            return out.getInputStream();
+        } catch (IOException e) {
+            throw new Fault("GET_CACHED_INPUT_STREAM", LOG, e, e.getMessage());
+        } catch (TransformerException e) {
+            throw new Fault("XML_TRANSFORM", LOG, e, e.getMessage());
+        }
+    }
+
+    public static Reader transform(Templates xsltTemplate, Reader inReader) {
+        try {
+            StreamSource beforeSource = new StreamSource(inReader);
+            CachedWriter outWriter = new CachedWriter();
+
+            Transformer trans = xsltTemplate.newTransformer();
+            trans.transform(beforeSource, new StreamResult(outWriter));
+
+            return outWriter.getReader();
+        } catch (IOException e) {
+            throw new Fault("GET_CACHED_INPUT_STREAM", LOG, e, e.getMessage());
+        } catch (TransformerException e) {
+            throw new Fault("XML_TRANSFORM", LOG, e, e.getMessage());
+        }
+    }
+
+    public static Document transform(Templates xsltTemplate, Document in) {
+        try {
+            DOMSource beforeSource = new DOMSource(in);
+            
+            Document out = DOMUtils.createDocument();
+
+            Transformer trans = xsltTemplate.newTransformer();
+            trans.transform(beforeSource, new DOMResult(out));
+
+            return out;
+        } catch (TransformerException e) {
+            throw new Fault("XML_TRANSFORM", LOG, e, e.getMessage());
+        }
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/feature/transform/XSLTUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java (added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,148 @@
+/**
+ * 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.cxf.feature.transform;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import junit.framework.Assert;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.CachedWriter;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+/* Provides XSLT transformation of incoming message.
+ * Interceptor breaks streaming (can be fixed in further versions when XSLT engine supports XML stream)
+ */
+public class XSLTInterceptorsTest {
+
+    private static final String TRANSFORMATION_XSL = "transformation.xsl";
+    private static final String MESSAGE_FILE = "message.xml";
+
+    private InputStream messageIS;
+    private Message message;
+    private XSLTInInterceptor inInterceptor;
+    private XSLTOutInterceptor outInterceptor;
+
+    @Before
+    public void setUp() throws TransformerConfigurationException {
+        messageIS = ClassLoaderUtils.getResourceAsStream(MESSAGE_FILE, this.getClass());
+        if (messageIS == null) {
+            throw new IllegalArgumentException("Cannot load message from path: " + MESSAGE_FILE);
+        }
+        message = new MessageImpl();
+        inInterceptor = new XSLTInInterceptor(Phase.POST_STREAM, null, null, TRANSFORMATION_XSL);
+        outInterceptor = new XSLTOutInterceptor(Phase.PRE_STREAM, null, null, TRANSFORMATION_XSL);
+    }
+    
+    @Test
+    public void inStreamTest() throws SAXException, IOException, ParserConfigurationException {
+        message.setContent(InputStream.class, messageIS);
+        inInterceptor.handleMessage(message);
+        InputStream transformedIS = message.getContent(InputStream.class);
+        Document doc = DOMUtils.readXml(transformedIS);
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+
+    @Test
+    public void inXMLStreamTest() throws XMLStreamException {
+        XMLStreamReader xReader = StaxUtils.createXMLStreamReader(messageIS);
+        message.setContent(XMLStreamReader.class, xReader);
+        inInterceptor.handleMessage(message);
+        XMLStreamReader transformedXReader = message.getContent(XMLStreamReader.class);
+        Document doc = StaxUtils.read(transformedXReader);
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+
+    @Test
+    public void inReaderTest() throws SAXException, IOException, ParserConfigurationException {
+        Reader reader = new InputStreamReader(messageIS);
+        message.setContent(Reader.class, reader);
+        inInterceptor.handleMessage(message);
+        Reader transformedReader = message.getContent(Reader.class);
+        Document doc = DOMUtils.readXml(transformedReader);
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+
+    @Test
+    public void outStreamTest() throws SAXException, IOException, ParserConfigurationException {
+        CachedOutputStream cos = new CachedOutputStream();
+        message.setContent(OutputStream.class, cos);
+        outInterceptor.handleMessage(message);
+        OutputStream os = message.getContent(OutputStream.class);
+        IOUtils.copy(messageIS, os);
+        os.close();
+        Document doc = DOMUtils.readXml(cos.getInputStream());
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+
+    @Test
+    public void outXMLStreamTest() throws XMLStreamException, SAXException, IOException, ParserConfigurationException {
+        CachedWriter cWriter = new CachedWriter();
+        XMLStreamWriter xWriter = StaxUtils.createXMLStreamWriter(cWriter);
+        message.setContent(XMLStreamWriter.class, xWriter);
+        outInterceptor.handleMessage(message);
+        XMLStreamWriter tXWriter = message.getContent(XMLStreamWriter.class);
+        StaxUtils.copy(new StreamSource(messageIS), tXWriter);
+        tXWriter.close();
+        Document doc = DOMUtils.readXml(cWriter.getReader());
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+
+    @Test
+    public void outWriterStreamTest() throws IOException, SAXException, ParserConfigurationException {
+        CachedWriter cWriter = new CachedWriter();
+        message.setContent(Writer.class, cWriter);
+        outInterceptor.handleMessage(message);
+        Writer tWriter = message.getContent(Writer.class);
+        IOUtils.copy(new InputStreamReader(messageIS), tWriter, IOUtils.DEFAULT_BUFFER_SIZE);
+        tWriter.close();
+        Document doc = DOMUtils.readXml(cWriter.getReader());
+        Assert.assertTrue("Message was not transformed", checkTransformedXML(doc));
+    }
+    
+    private boolean checkTransformedXML(Document doc) {
+        NodeList list = doc.getDocumentElement()
+            .getElementsByTagNameNS("http://customerservice.example.com/", "getCustomersByName1");
+        return list.getLength() == 1;
+    }
+}

Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/XSLTInterceptorsTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml (added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml Mon Nov  5 09:43:01 2012
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+	<soap:Body>
+		<cus:getCustomersByName xmlns:cus="http://customerservice.example.com/">
+			<name xmlns:ns2="http://customerservice.example.com/">Smith</name>
+		</cus:getCustomersByName>
+	</soap:Body>
+</soap:Envelope>
\ No newline at end of file

Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/message.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl (added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl Mon Nov  5 09:43:01 2012
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:cus="http://customerservice.example.com/">
+	<!-- Identity Template # Copy everything -->
+	<xsl:template match="@*|node()">
+		<xsl:copy>
+			<xsl:apply-templates select="@*|node()" />
+		</xsl:copy>
+	</xsl:template>
+	<!-- Rename element -->
+	<xsl:template match="cus:getCustomersByName">
+		<xsl:element name="getCustomersByName1" namespace="http://customerservice.example.com/">
+			<xsl:apply-templates select="@*|node()"/>
+		</xsl:element>
+	</xsl:template>
+
+</xsl:stylesheet>

Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/feature/transform/transformation.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java (added)
+++ cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,29 @@
+/**
+ * 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.cxf.systest.transform.feature;
+
+import javax.jws.WebService;
+
+@WebService
+public interface Echo {
+    
+    String echo(String request);
+    
+}

Propchange: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/Echo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java (added)
+++ cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,35 @@
+/**
+ * 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.cxf.systest.transform.feature;
+
+
+@javax.jws.WebService(portName = "EchoPort", serviceName = "EchoService", 
+                      targetNamespace = "http://apache.org/echo", 
+                      endpointInterface = "org.apache.cxf.systest.transform.feature.Echo")                  
+public class EchoImpl implements Echo {
+
+    
+    /* (non-Javadoc)
+     * @see org.apache.hello_world_soap12_http.Greeter#sayHi()
+     */
+    public String echo(String request) {
+        return "Response on " + request;
+    }
+}

Propchange: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java (added)
+++ cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java Mon Nov  5 09:43:01 2012
@@ -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.cxf.systest.transform.feature;
+
+import javax.xml.ws.Endpoint;
+
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+public class EchoServer extends AbstractBusTestServerBase {
+    public static final String PORT = allocatePort(EchoServer.class);
+
+
+    protected void run()  {    
+        Object implementor = new EchoImpl();
+        String address = "http://localhost:" + PORT + "/EchoContext/EchoPort";
+        Endpoint.publish(address, implementor);
+    }
+
+
+    public static void main(String[] args) {
+        try {
+            EchoServer s = new EchoServer();
+            s.start();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        } finally {
+            System.out.println("done!");
+        }
+    }
+}

Propchange: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/EchoServer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java (added)
+++ cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java Mon Nov  5 09:43:01 2012
@@ -0,0 +1,84 @@
+/**
+ * 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.cxf.systest.transform.feature;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;
+
+import junit.framework.Assert;
+
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.feature.transform.XSLTInInterceptor;
+import org.apache.cxf.feature.transform.XSLTOutInterceptor;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.interceptor.StaxInInterceptor;
+import org.apache.cxf.interceptor.StaxOutInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TransformFeatureTest extends AbstractBusClientServerTestBase {    
+    private static final String PORT = EchoServer.PORT;
+    private static final QName PORT_NAME = new QName("http://apache.org/echo", "EchoPort");
+    private static final QName SERVICE_NAME = new QName("http://apache.org/echo", "EchoService");
+    private static final String XSLT_REQUEST_PATH = "request.xsl"; 
+    private static final String XSLT_RESPONSE_PATH = "response.xsl"; 
+    private static final String TRANSFORMED_CONSTANT = "TRANSFORMED";
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("server did not launch correctly", launchServer(EchoServer.class, true));
+    }
+
+    @Test
+    public void testClientOutTransformation() {
+        Service service = Service.create(SERVICE_NAME);
+        String endpoint = "http://localhost:" + PORT + "/EchoContext/EchoPort";
+        service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpoint);
+         
+        Echo port = service.getPort(PORT_NAME, Echo.class);
+        Client client = ClientProxy.getClient(port);
+        XSLTOutInterceptor outInterceptor = new XSLTOutInterceptor(Phase.PRE_STREAM, StaxOutInterceptor.class, null,
+                                                                   XSLT_REQUEST_PATH);
+        client.getOutInterceptors().add(outInterceptor);
+        String response = port.echo("test");
+        Assert.assertTrue("Request was not transformed", response.contains(TRANSFORMED_CONSTANT));
+    }
+
+    @Test
+    public void testClientInTransformation() {
+        Service service = Service.create(SERVICE_NAME);
+        String endpoint = "http://localhost:" + PORT + "/EchoContext/EchoPort";
+        service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpoint);
+         
+        Echo port = service.getPort(PORT_NAME, Echo.class);
+        Client client = ClientProxy.getClient(port);
+        XSLTInInterceptor inInterceptor = new XSLTInInterceptor(Phase.POST_STREAM, StaxInInterceptor.class, null,
+                                                                   XSLT_RESPONSE_PATH);
+        client.getInInterceptors().add(inInterceptor);
+        String response = port.echo("test");
+        Assert.assertTrue(response.contains(TRANSFORMED_CONSTANT));
+    }
+}
+

Propchange: cxf/trunk/systests/uncategorized/src/test/java/org/apache/cxf/systest/transform/feature/TransformFeatureTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/resources/request.xsl
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/resources/request.xsl?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/resources/request.xsl (added)
+++ cxf/trunk/systests/uncategorized/src/test/resources/request.xsl Mon Nov  5 09:43:01 2012
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cus="http://customerservice.example.com/">
+	<!-- Identity Template # Copy everything -->
+	<xsl:template match="@*|node()">
+		<xsl:copy>
+			<xsl:apply-templates select="@*|node()" />
+		</xsl:copy>
+	</xsl:template>
+
+	<xsl:template match="arg0/text()">TRANSFORMED</xsl:template>
+
+</xsl:stylesheet>

Propchange: cxf/trunk/systests/uncategorized/src/test/resources/request.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/uncategorized/src/test/resources/response.xsl
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/uncategorized/src/test/resources/response.xsl?rev=1405730&view=auto
==============================================================================
--- cxf/trunk/systests/uncategorized/src/test/resources/response.xsl (added)
+++ cxf/trunk/systests/uncategorized/src/test/resources/response.xsl Mon Nov  5 09:43:01 2012
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cus="http://customerservice.example.com/">
+	<!-- Identity Template # Copy everything -->
+	<xsl:template match="@*|node()">
+		<xsl:copy>
+			<xsl:apply-templates select="@*|node()" />
+		</xsl:copy>
+	</xsl:template>
+
+	<xsl:template match="return/text()">TRANSFORMED</xsl:template>
+
+</xsl:stylesheet>

Propchange: cxf/trunk/systests/uncategorized/src/test/resources/response.xsl
------------------------------------------------------------------------------
    svn:mime-type = text/plain