Author: scheu
Date: Fri Aug  6 12:31:05 2010
New Revision: 982938

URL: http://svn.apache.org/viewvc?rev=982938&view=rev
Log:
AXIS2-4791
Contributor:Rich Scheuerle
Axis2 changes to enable the illegal character filtering during JAX-WS 
processing.
Also added a verification test

Modified:
    
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/ResourceInjectionTests.java
    
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/resourceinjection/ResourceInjectionPortTypeImpl.java
    
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
    
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
    
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/context/utils/ContextUtils.java

Modified: 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/ResourceInjectionTests.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/ResourceInjectionTests.java?rev=982938&r1=982937&r2=982938&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/ResourceInjectionTests.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/ResourceInjectionTests.java
 Fri Aug  6 12:31:05 2010
@@ -59,6 +59,10 @@ public class ResourceInjectionTests exte
             assertTrue("The response was null", response != null);
             assertTrue("The response was not succesful: " + response, 
                        response.indexOf("SUCCESS") >= 0);
+            char[] chars = new char[] {0x15}; // 0x15 is not a valid xml 
character..and should be filtered
+            String insert = new String(chars);
+            assertTrue("Illegal characters were not filtered: " + response,
+                    response.indexOf(insert) < 0);
         
     }
    

Modified: 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/resourceinjection/ResourceInjectionPortTypeImpl.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/resourceinjection/ResourceInjectionPortTypeImpl.java?rev=982938&r1=982937&r2=982938&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/resourceinjection/ResourceInjectionPortTypeImpl.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/resourceinjection/ResourceInjectionPortTypeImpl.java
 Fri Aug  6 12:31:05 2010
@@ -19,6 +19,7 @@
 
 package org.apache.axis2.jaxws.sample.resourceinjection;
 
+import org.apache.axis2.jaxws.Constants;
 import org.apache.axis2.jaxws.TestLogger;
 import 
org.apache.axis2.jaxws.sample.resourceinjection.sei.ResourceInjectionPortType;
 
@@ -69,7 +70,18 @@ import javax.xml.ws.handler.MessageConte
             return "FAILURE: The WebServiceContext's MessageContext " +
                         "does not have the correct wsdlOperation";
         }
-        return "SUCCESS: " + wsdlOperation.getLocalPart();
+        
+        String response = "SUCCESS: " + wsdlOperation.getLocalPart();
+        
+        // Set a flag to force filtering of JAXB data.
+        // Also set a illegal characters in the response string
+        // to verify that the illegal character is removed.
+        msgContext.put(Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS, 
Boolean.TRUE);
+        char[] chars = new char[] {0x15}; // 0x15 is not a valid xml character
+        String insert = new String(chars);
+        response = insert + response + insert;
+
+        return response;
     }
 
     @PostConstruct

Modified: 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java?rev=982938&r1=982937&r2=982938&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
 Fri Aug  6 12:31:05 2010
@@ -21,12 +21,14 @@ package org.apache.axis2.datasource.jaxb
 
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.util.XMLStreamWriterRemoveIllegalChars;
 import org.apache.axiom.util.stax.XMLStreamReaderUtils;
 import org.apache.axiom.util.stax.xop.MimePartProvider;
 import org.apache.axiom.util.stax.xop.XOPEncodedStream;
 import org.apache.axiom.util.stax.xop.XOPUtils;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.context.utils.ContextUtils;
 import org.apache.axis2.jaxws.message.OccurrenceArray;
 import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
 import org.apache.axis2.jaxws.message.util.XMLStreamWriterWithOS;
@@ -368,23 +370,26 @@ public class JAXBDSContext {
      * @param am AttachmentMarshaller, optional Attachment
      */
     public void marshal(Object obj, 
-                        XMLStreamWriter writer) throws JAXBException {
-            if (log.isDebugEnabled()) {
-                log.debug("enter marshal");
-            }
+            XMLStreamWriter writer) throws JAXBException {
+        if (log.isDebugEnabled()) {
+            log.debug("enter marshal");
+        }
+        boolean installedFilter = false;
+
+        try {
             // There may be a preferred classloader that should be used
             ClassLoader cl = getClassLoader();
-            
-            
+
+
             // Very easy, use the Context to get the Marshaller.
             // Use the marshaller to write the object.
             JAXBContext jbc = getJAXBContext(cl);
             Marshaller m = JAXBUtils.getJAXBMarshaller(jbc);
             if (writer instanceof MTOMXMLStreamWriter && 
((MTOMXMLStreamWriter) writer).getOutputFormat() != null) {
                 String encoding = ((MTOMXMLStreamWriter) 
writer).getOutputFormat().getCharSetEncoding();
-                
+
                 String marshallerEncoding = (String) 
m.getProperty(Marshaller.JAXB_ENCODING);
-                
+
                 // Make sure that the marshaller respects the encoding of the 
message.
                 // This is accomplished by setting the encoding on the 
Marshaller's JAXB_ENCODING property.
                 if (encoding == null && marshallerEncoding == null) {
@@ -394,7 +399,7 @@ public class JAXBDSContext {
                 } else {
                     // Must set the encoding to an actual String to set it on 
the Marshaller
                     if (encoding == null) {
-                       encoding = "UTF-8";
+                        encoding = "UTF-8";
                     }
                     if (!encoding.equalsIgnoreCase(marshallerEncoding)) {
                         if (log.isDebugEnabled()) {
@@ -406,12 +411,12 @@ public class JAXBDSContext {
                     } else {
                         if (log.isDebugEnabled()) {
                             log.debug("The encoding and the marshaller's 
JAXB_ENCODING are both set to:" + 
-                                        marshallerEncoding);
+                                    marshallerEncoding);
                         }
                     }
                 }
             }
-            
+
             AttachmentMarshaller am = createAttachmentMarshaller(writer);
             if (am != null) {
                 if (DEBUG_ENABLED) {
@@ -420,29 +425,40 @@ public class JAXBDSContext {
                 m.setAttachmentMarshaller(am);
             }
 
+            MessageContext mc = getMessageContext();
+
+            // If requested install a filter to remove illegal characters
+            installedFilter = installFilter(mc, writer);
+
 
             // Marshal the object
             if (getProcessType() == null) {
                 marshalByElement(obj, 
-                                 m, 
-                                 writer, 
-                                 true);
-                                 //!am.isXOPPackage());
+                        m, 
+                        writer, 
+                        true);
+                //!am.isXOPPackage());
             } else {
                 marshalByType(obj,
-                              m,
-                              writer,
-                              getProcessType(),
-                              isxmlList(),
-                              getConstructionType(),
-                              true); // Attempt to optimize by writing to 
OutputStream
+                        m,
+                        writer,
+                        getProcessType(),
+                        isxmlList(),
+                        getConstructionType(),
+                        true); // Attempt to optimize by writing to 
OutputStream
             }
-            
+
             JAXBUtils.releaseJAXBMarshaller(jbc, m);
-            
+
             if (log.isDebugEnabled()) {
                 log.debug("exit marshal");
             }
+        } finally {
+            // Make sure the filter is uninstalled
+            if (installedFilter) {
+                uninstallFilter(writer);
+            }
+        }
     }
     
     
@@ -1073,4 +1089,37 @@ public class JAXBDSContext {
             throw new OMException(t);
         }
     }
+    
+
+    /**
+     * Install a JAXB filter if requested
+     * @param mc
+     * @param writer
+     * @return true if filter installed
+     */
+    private boolean installFilter(MessageContext mc, XMLStreamWriter writer) {
+        if (!(writer instanceof MTOMXMLStreamWriter)) {
+            return false;
+        }
+        if (!ContextUtils.isJAXBRemoveIllegalChars(mc)) {
+            return false;
+        }
+        
+         
+        MTOMXMLStreamWriter mtomWriter = (MTOMXMLStreamWriter) writer;
+        mtomWriter.setFilter(new XMLStreamWriterRemoveIllegalChars());
+        return true;
+    }
+    
+    /**
+     * UninstallInstall a JAXB filter if requested
+     * @param mc
+     * @param writer
+     * @return true if filter installed
+     */
+    private void uninstallFilter(XMLStreamWriter writer) {
+        MTOMXMLStreamWriter mtomWriter = (MTOMXMLStreamWriter) writer;
+        mtomWriter.removeFilter();
+    }
+
 }

Modified: 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java?rev=982938&r1=982937&r2=982938&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
 Fri Aug  6 12:31:05 2010
@@ -161,4 +161,33 @@ public interface Constants {
      * This constant will be used to store the location of JAX-WS generated 
artifacts cache.
      */
     public static final String WS_CACHE="wsCache";
+    
+    /**
+     * Context Property:
+     * Name: jaxws.jaxb.write.remove.illegal.chars
+     * Value: Boolean.TRUE or Boolean.FALSE
+     * Default: null, which is interpreted as FALSE.
+     * 
+     * Configuration Parameter
+     * Name: jaxws.jaxb.write.remove.illegal.chars
+     * Value: String or Boolean representing true or false
+     * Default: null, which is interpreted as FALSE
+     * 
+     * Description:
+     * If the value is false, the jax-ws engine will detect and remove
+     * illegal characters (characters not supported in xml) when writing
+     * a JAXB data bean associated with a jaxws web method
+     *  http://www.w3.org/TR/2008/REC-xml-20081126/#NT-Char
+     * This extra filter may degrade performance.
+     * 
+     * Customers should accept the default behavior (false), and only set the 
value to true if the
+     * character data produced by their web service is invalid and cannot be 
filtered by some
+     * other mechanism.
+     * 
+     * The engine will first examine the Context property.  If not set, the 
value of the Configuration
+     * property is used.
+     */
+    public static final String JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS = 
+        "jaxws.jaxb.write.remove.illegal.chars";
+
 }

Modified: 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/context/utils/ContextUtils.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/context/utils/ContextUtils.java?rev=982938&r1=982937&r2=982938&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/context/utils/ContextUtils.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/context/utils/ContextUtils.java
 Fri Aug  6 12:31:05 2010
@@ -20,7 +20,11 @@
 package org.apache.axis2.jaxws.context.utils;
 
 import org.apache.axiom.soap.SOAPHeader;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.OperationContext;
 import org.apache.axis2.context.ServiceContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.jaxws.Constants;
 import org.apache.axis2.jaxws.addressing.util.ReferenceParameterList;
 import org.apache.axis2.jaxws.context.WebServiceContextImpl;
 import org.apache.axis2.jaxws.core.MessageContext;
@@ -33,6 +37,7 @@ import org.apache.axis2.jaxws.i18n.Messa
 import 
org.apache.axis2.jaxws.server.endpoint.lifecycle.impl.EndpointLifecycleManagerImpl;
 import org.apache.axis2.jaxws.utility.JavaUtils;
 import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.wsdl.WSDLConstants;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.w3c.dom.Element;
@@ -279,4 +284,145 @@ public class ContextUtils {
             }
         }
     }
+    
+    /**
+     * isJAXBRemoveIllegalChars
+     * 
+     * Determine if illegal characters should be removed when JAXB beans are 
written
+     * 
+     * @see Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS 
+     * 
+     * @param mc
+     * @return true if the property is set
+     */
+    public static boolean 
isJAXBRemoveIllegalChars(org.apache.axis2.context.MessageContext mc) {
+        boolean rc = _isJAXBRemoveIllegalChars(mc);
+
+        // If not true, check the related MessageContext
+        if (!rc) {
+            if (mc != null && mc != null) {
+                rc = _isJAXBRemoveIllegalChars(getRelatedMessageContext(mc));
+            }
+        }
+        return rc;
+    }
+    
+    /**
+     * getRelatedMessageContext
+     * @param mc Axis2 MessageContext
+     * @return related MessageContext
+     */
+    private static org.apache.axis2.context.MessageContext 
+        getRelatedMessageContext(org.apache.axis2.context.MessageContext mc) {
+        if (log.isDebugEnabled()) {
+            log.debug("Enter getRelatedMessageContext for:" + mc);
+        }
+        org.apache.axis2.context.MessageContext relatedMC = null;
+        if (mc != null) {
+            OperationContext oc = mc.getOperationContext();
+            if (oc != null) {
+                try {
+                    relatedMC = 
oc.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+                    if (relatedMC == mc) {
+                        relatedMC = 
oc.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
+                    }
+                } catch (AxisFault e) {
+                    // TODO This should never occur in this scenario, swallow 
and continue
+                }
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Exit getRelatedMessageContext related messageContext 
is" + relatedMC);
+        }
+        return relatedMC;
+    }
+
+    /**
+     * _isJAXBRemoveIllegalChars
+     * 
+     * Determine if illegal characters should be removed when JAXB beans are 
written
+     * 
+     * @see Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS 
+     * 
+     * @param mc
+     * @return true if property is set
+     */
+    private static boolean _isJAXBRemoveIllegalChars(MessageContext mc) {
+        
+        boolean value = false;
+        if (mc == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("_isJAXBRemoveIllegalChars returns false due to 
missing MessageContext");
+            }
+            return false;
+        }
+        
+        // First examine the property on the jaxws MessageContext
+        Boolean property = (Boolean) mc.getProperty(
+                Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+        if (property != null) {
+            value = property.booleanValue();
+            if (log.isDebugEnabled()) {
+                log.debug("_isJAXBRemoveIllegalChars returns " + value + " per 
jaxws MessageContext property " + 
+                        Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+            }
+            return value;
+        }
+        
+        // If not found, delegate to the Axis2 MessageContext
+        if (mc.getAxisMessageContext() != null) {
+            return _isJAXBRemoveIllegalChars(mc.getAxisMessageContext());
+        }
+        return value;
+    }
+    
+    /**
+     * _isJAXBRemoveIllegalChars
+     * 
+     * Determine if illegal characters should be removed when JAXB beans are 
written
+     * 
+     * @see Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS 
+     * 
+     * @param mc
+     * @return true if property is set
+     */
+    private static boolean 
_isJAXBRemoveIllegalChars(org.apache.axis2.context.MessageContext mc) {
+        
+        boolean value = false;
+        if (mc == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("_isJAXBRemoveIllegalChars returns false due to 
missing MessageContext");
+            }
+            return false;
+        }
+        
+        // First examine the property on the axis2 MessageContext hierarchy
+        Boolean property = (Boolean) mc.getProperty(
+                Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+        if (property != null) {
+            value = property.booleanValue();
+            if (log.isDebugEnabled()) {
+                log.debug("_isJAXBRemoveIllegalChars returns " + value + " per 
axis2 MessageContext property " + 
+                        Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+            }
+            return value;
+        }
+        
+        
+        // Now look at the configuration parameter
+        Parameter p = 
mc.getParameter(Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+        if (p != null) {
+            value = JavaUtils.isTrue(p.getValue());
+            if (log.isDebugEnabled()) {
+                log.debug("isJAXBRemoveIllegalChars returns " + value + " per 
inspection of Configuration property " + 
+                        Constants.JAXWS_JAXB_WRITE_REMOVE_ILLEGAL_CHARS);
+            }
+            return value;
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("isJAXBRemoveIllegalChars returns the default: false");
+        }
+        return false;
+    }
 }


Reply via email to