Return-Path: Delivered-To: apmail-ws-axis-cvs-archive@www.apache.org Received: (qmail 58571 invoked from network); 20 Nov 2009 19:58:05 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 20 Nov 2009 19:58:05 -0000 Received: (qmail 88232 invoked by uid 500); 20 Nov 2009 19:58:04 -0000 Delivered-To: apmail-ws-axis-cvs-archive@ws.apache.org Received: (qmail 87664 invoked by uid 500); 20 Nov 2009 19:58:03 -0000 Mailing-List: contact axis-cvs-help@ws.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list axis-cvs@ws.apache.org Received: (qmail 87464 invoked by uid 500); 20 Nov 2009 19:58:03 -0000 Delivered-To: apmail-ws-axis2-cvs@ws.apache.org Received: (qmail 87434 invoked by uid 99); 20 Nov 2009 19:58:03 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Nov 2009 19:58:03 +0000 X-ASF-Spam-Status: No, hits=-1997.2 required=10.0 tests=ALL_TRUSTED,WEIRD_QUOTING X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Nov 2009 19:57:51 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1108B23888FD; Fri, 20 Nov 2009 19:57:30 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r882698 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/context/listener/ test/org/apache/axis2/jaxws/context/listener/ Date: Fri, 20 Nov 2009 19:57:29 -0000 To: axis2-cvs@ws.apache.org From: scheu@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091120195730.1108B23888FD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: scheu Date: Fri Nov 20 19:57:29 2009 New Revision: 882698 URL: http://svn.apache.org/viewvc?rev=882698&view=rev Log: AXIS2-4550 Contributor:Lori VanGulick and Bill Nagy Committer: Rich Scheuerle Fix to ParserInputStream to correct namespaces. Also a validation test. Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ContextListenerUtils.java webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ContextListenerUtils.java URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ContextListenerUtils.java?rev=882698&r1=882697&r2=882698&view=diff ============================================================================== --- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ContextListenerUtils.java (original) +++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ContextListenerUtils.java Fri Nov 20 19:57:29 2009 @@ -50,9 +50,9 @@ ProviderOMContextListener.create(mc.getAxisMessageContext().getServiceContext()); } - public static InputStream createPayloadElement(InputStream payloadContent, OMNamespace ns, String localPart, OMContainer parent){ + public static InputStream createPayloadElement(InputStream payloadContent, OMNamespace ns, String localPart, OMContainer parent, HashMap nsElementDecls, HashMap attrElementDecls){ CompositeInputStream inputStream = new CompositeInputStream(); - InputStream startTag = getStartTag(ns, localPart, parent); + InputStream startTag = getStartTag(ns, localPart, parent, nsElementDecls, attrElementDecls); InputStream endTag = getEndTag(ns, localPart); //Add Element startTag ((CompositeInputStream)inputStream).append(startTag); @@ -96,7 +96,7 @@ /* * get startElement using namespace and local part. Add all namespace prefixes from parent elements. */ - private static InputStream getStartTag(OMNamespace ns, String localPart, OMContainer parent){ + private static InputStream getStartTag(OMNamespace ns, String localPart, OMContainer parent, HashMap nsElementDecls, HashMap attrElementDecls){ if(log.isDebugEnabled()){ log.debug("Start ParsedEntityDataSource.Data.getStartTag()"); } @@ -104,17 +104,28 @@ StringBuffer startElement = new StringBuffer(); String prefix = (ns!=null)?ns.getPrefix():null; String uri = (ns!=null)?ns.getNamespaceURI():null; + + HashMap nsDecls = new HashMap(); + //Get all of the namespaces associated with Body, envelope, etc + getParentnsdeclarations(nsDecls, parent); + + nsDecls.putAll(nsElementDecls); + if(prefix!=null && prefix.length()>0){ - startElement.append("<"+prefix+":"+localPart+ " xmlns:"+prefix+"=\""+uri+"\""); - addParentNs(startElement, parent); - + startElement.append("<"+prefix+":"+localPart+ " "); + if (!nsDecls.containsKey(prefix) || !nsDecls.get(prefix).equals(uri)){ + nsDecls.put(prefix, uri); + } }else{ - startElement.append("<"+localPart+" xmlns=\""+uri+"\""); - addParentNs(startElement, parent); + startElement.append("<"+localPart + " "); } + addParentNs(startElement, parent, nsDecls); + addAttrs(startElement, attrElementDecls); + if(log.isDebugEnabled()){ - log.debug("StartElement ="+startElement); + log.debug("StartElement ="+startElement); } + if(log.isDebugEnabled()){ log.debug("End ParsedEntityDataSource.Data.getStartTag()"); } @@ -134,8 +145,9 @@ OMNamespace omn = (OMNamespace) ite.next(); String prefix = omn.getPrefix(); String nsUri = omn.getNamespaceURI(); - if (!nsDecls.containsKey(prefix)) + if (!nsDecls.containsKey(prefix)) { nsDecls.put(prefix, nsUri); + } } parent = omElement.getParent(); } @@ -143,10 +155,7 @@ /* * add all parent namespace declarations to the element */ - private static void addParentNs(StringBuffer startElement, OMContainer parent){ - HashMap nsDecls = new HashMap(); - //Get all the namespaces associated with Body, envelope etc. - getParentnsdeclarations(nsDecls, parent); + private static void addParentNs(StringBuffer startElement, OMContainer parent, HashMap nsDecls){ Iterator> iter = nsDecls.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); @@ -162,7 +171,21 @@ startElement.append(uri); startElement.append("\""); } - startElement.append(">"); } + private static void addAttrs(StringBuffer startElement, HashMap attrDecls) + { + Iterator> iter = attrDecls.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + String compoundName = entry.getKey(); + String value = entry.getValue(); + startElement.append(" "); + startElement.append(compoundName); + startElement.append("=\""); + startElement.append(value); + startElement.append("\""); + } + startElement.append(">"); + } } Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java?rev=882698&r1=882697&r2=882698&view=diff ============================================================================== --- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java (original) +++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilder.java Fri Nov 20 19:57:29 2009 @@ -19,6 +19,8 @@ package org.apache.axis2.jaxws.context.listener; import java.io.InputStream; +import java.util.HashMap; +import java.util.LinkedList; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; @@ -87,7 +89,7 @@ //Do not user custom builder if Parser does not have ability to read sub content. if(!entityReader.isParsedEntityStreamAvailable()){ if (log.isDebugEnabled()) { - log.debug("Stream not available"); + log.debug("ParsedEntityStream is not available, defaulting to normal build"); } return null; } @@ -96,10 +98,13 @@ if(parsedStream == null){ //cant read content from EntityReader, returning null. if (log.isDebugEnabled()) { - log.debug("No content available"); + log.debug("Unable to read content from the entity reader, defaulting to normal build"); } return null; } + HashMap nsElementDecls = getElementNamespaceDeclarations(reader); + HashMap attrElementDecls = getElementAttributeDeclarations(reader); + //read the payload. Lets move the parser forward. if(reader.hasNext()){ reader.next(); @@ -113,7 +118,8 @@ } } OMNamespace ns = factory.createOMNamespace(namespace, reader.getPrefix()); - InputStream payload = ContextListenerUtils.createPayloadElement(parsedStream, ns, localPart, parent); + InputStream payload = ContextListenerUtils.createPayloadElement(parsedStream, ns, localPart, parent, + nsElementDecls, attrElementDecls); ParserInputStreamDataSource ds = new ParserInputStreamDataSource(payload, encoding); OMSourcedElement om = null; @@ -182,6 +188,121 @@ } } + private HashMap getElementNamespaceDeclarations(XMLStreamReader reader) + { + HashMap nsElementDecls = new HashMap(); + int count = reader.getNamespaceCount(); + for (int i = 0; i < count; i++){ + String prefix = reader.getNamespacePrefix(i); + String namespace = reader.getNamespaceURI(i); + if (namespace != null && namespace.length() > 0){ + nsElementDecls.put(prefix == null ? "":prefix, namespace); + } + } + return nsElementDecls; + } + + private HashMap getElementAttributeDeclarations(XMLStreamReader reader) + { + HashMap attrElementDecls = new HashMap(); + int count = reader.getAttributeCount(); + + for (int i = 0; i < count; i++) { + String prefix = reader.getAttributePrefix(i); + String name = reader.getAttributeLocalName(i); + String value = convertEntityReferences(reader.getAttributeValue(i)); + String compoundName; + if (prefix != null && prefix.length() > 0){ + compoundName = prefix+":"+name; + } + else { + compoundName = name; + } + attrElementDecls.put(compoundName, value); + } + return attrElementDecls; + } + + protected String convertEntityReferences(String value) + { + if ((value == null) || (value.length() == 0)) + return value; + + int valueLen = value.length(); + + int[] positionsToChange = null; + int numChanged = 0; + + for (int i = 0; i < valueLen; i++) { + switch (value.charAt(i)) { + case '<': + case '>': + case '&': + case '\"': + case '\'': + if (positionsToChange == null) + { + positionsToChange = new int[valueLen]; + } + positionsToChange[numChanged++]=i; + break; + } + } + + if (numChanged == 0) { + if(log.isDebugEnabled()) + { + log.debug("No entity references were found in "+value); + } + return value; + } + else { + if(log.isDebugEnabled()) + { + log.debug("Found "+numChanged+" entity references in "+value); + } + + //We'll create the new builder assuming the size of the worst case + StringBuilder changedValue = new StringBuilder(valueLen+numChanged*5); + int changedPos = 0; + for (int i = 0; i < valueLen; i++) { + if (i == positionsToChange[changedPos]) { + switch (value.charAt(i)) { + case '<': + changedValue.append("<"); + changedPos++; + break; + case '>': + changedValue.append(">"); + changedPos++; + break; + case '&': + changedValue.append("&"); + changedPos++; + break; + case '\'': + changedValue.append("'"); + changedPos++; + break; + case '\"': + changedValue.append("""); + changedPos++; + break; + } + } + else { + changedValue.append(value.charAt(i)); + } + } + + if(log.isDebugEnabled()) + { + log.debug("Converted to "+changedValue.toString()); + } + + return changedValue.toString(); + } + } /* * Read content from entityReader. */ Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java?rev=882698&r1=882697&r2=882698&view=diff ============================================================================== --- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java (original) +++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/context/listener/ParserInputStreamCustomBuilderTests.java Fri Nov 20 19:57:29 2009 @@ -74,6 +74,35 @@ } } + /** + * Tests that ParsedEntityCustomBuilder.convertEntityReferences works as expected. + */ + public void testConvertEntityReferences(){ + try{ + ParserInputStreamCustomBuilder customBuilder = new ParserInputStreamCustomBuilder("UTF-8"); + // test that all expected chars are converted + String expectedString1 = "<,>,",',&"; + String convertedString = customBuilder.convertEntityReferences("<,>,\",',&"); + assertTrue("Special chars didn't get converted! " + + "Expected: \""+expectedString1+"\" but received: \""+convertedString+"\"", + convertedString.equals(expectedString1)); + // test that a string with no special chars is unchanged + String simpleString = "This is a simple string"; + convertedString = customBuilder.convertEntityReferences(simpleString); + assertTrue("Simple string was changed unexpectedly. " + + "Expected: \""+simpleString+"\" but received: \""+convertedString+"\"", + convertedString.equals(simpleString)); + + // test that the mockenvelope gets converted correctly + String expectedString2 = "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><invokeOp>Hello Provider OM</invokeOp></soapenv:Body></soapenv:Envelope>"; + convertedString = customBuilder.convertEntityReferences(mockenvelope); + assertTrue("mockenvelope was not converted as expected. " + + "Expected: \""+expectedString2+"\" but received: \""+convertedString+"\"", + convertedString.equals(expectedString2)); + }catch(Exception e){ + fail(e.getMessage()); + } + } private SOAPEnvelope getMockEnvelope() throws Exception{ SOAPEnvelope env = (SOAPEnvelope)getOMBuilder().getDocumentElement(); return env;