1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/util/pipe/AbstractSchemaValidationTube.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,549 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.ws.util.pipe; 1.30 + 1.31 +import com.sun.istack.internal.NotNull; 1.32 +import com.sun.istack.internal.Nullable; 1.33 +import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult; 1.34 +import com.sun.xml.internal.ws.api.WSBinding; 1.35 +import com.sun.xml.internal.ws.api.message.Message; 1.36 +import com.sun.xml.internal.ws.api.message.Packet; 1.37 +import com.sun.xml.internal.ws.api.pipe.Tube; 1.38 +import com.sun.xml.internal.ws.api.pipe.TubeCloner; 1.39 +import com.sun.xml.internal.ws.api.pipe.helper.AbstractFilterTubeImpl; 1.40 +import com.sun.xml.internal.ws.api.server.DocumentAddressResolver; 1.41 +import com.sun.xml.internal.ws.api.server.SDDocument; 1.42 +import com.sun.xml.internal.ws.api.server.SDDocumentSource; 1.43 +import com.sun.xml.internal.ws.developer.SchemaValidationFeature; 1.44 +import com.sun.xml.internal.ws.developer.ValidationErrorHandler; 1.45 +import com.sun.xml.internal.ws.server.SDDocumentImpl; 1.46 +import com.sun.xml.internal.ws.util.ByteArrayBuffer; 1.47 +import com.sun.xml.internal.ws.util.xml.XmlUtil; 1.48 +import com.sun.xml.internal.ws.wsdl.SDDocumentResolver; 1.49 +import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; 1.50 +import org.w3c.dom.*; 1.51 +import org.w3c.dom.ls.LSInput; 1.52 +import org.w3c.dom.ls.LSResourceResolver; 1.53 +import org.xml.sax.SAXException; 1.54 +import org.xml.sax.helpers.NamespaceSupport; 1.55 + 1.56 +import javax.xml.XMLConstants; 1.57 +import javax.xml.namespace.QName; 1.58 +import javax.xml.transform.Source; 1.59 +import javax.xml.transform.Transformer; 1.60 +import javax.xml.transform.TransformerException; 1.61 +import javax.xml.transform.dom.DOMResult; 1.62 +import javax.xml.transform.dom.DOMSource; 1.63 +import javax.xml.transform.stream.StreamSource; 1.64 +import javax.xml.validation.SchemaFactory; 1.65 +import javax.xml.validation.Validator; 1.66 +import javax.xml.ws.WebServiceException; 1.67 +import java.io.IOException; 1.68 +import java.io.InputStream; 1.69 +import java.io.Reader; 1.70 +import java.io.StringReader; 1.71 +import java.net.MalformedURLException; 1.72 +import java.net.URI; 1.73 +import java.net.URL; 1.74 +import java.util.*; 1.75 +import java.util.logging.Level; 1.76 +import java.util.logging.Logger; 1.77 + 1.78 +/** 1.79 + * {@link Tube} that does the schema validation. 1.80 + * 1.81 + * @author Jitendra Kotamraju 1.82 + */ 1.83 +public abstract class AbstractSchemaValidationTube extends AbstractFilterTubeImpl { 1.84 + 1.85 + private static final Logger LOGGER = Logger.getLogger(AbstractSchemaValidationTube.class.getName()); 1.86 + 1.87 + protected final WSBinding binding; 1.88 + protected final SchemaValidationFeature feature; 1.89 + protected final DocumentAddressResolver resolver = new ValidationDocumentAddressResolver(); 1.90 + protected final SchemaFactory sf; 1.91 + 1.92 + public AbstractSchemaValidationTube(WSBinding binding, Tube next) { 1.93 + super(next); 1.94 + this.binding = binding; 1.95 + feature = binding.getFeature(SchemaValidationFeature.class); 1.96 + sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 1.97 + } 1.98 + 1.99 + protected AbstractSchemaValidationTube(AbstractSchemaValidationTube that, TubeCloner cloner) { 1.100 + super(that, cloner); 1.101 + this.binding = that.binding; 1.102 + this.feature = that.feature; 1.103 + this.sf = that.sf; 1.104 + } 1.105 + 1.106 + protected abstract Validator getValidator(); 1.107 + 1.108 + protected abstract boolean isNoValidation(); 1.109 + 1.110 + private static class ValidationDocumentAddressResolver implements DocumentAddressResolver { 1.111 + 1.112 + @Nullable 1.113 + public String getRelativeAddressFor(@NotNull SDDocument current, @NotNull SDDocument referenced) { 1.114 + LOGGER.fine("Current = "+current.getURL()+" resolved relative="+referenced.getURL()); 1.115 + return referenced.getURL().toExternalForm(); 1.116 + } 1.117 + } 1.118 + 1.119 + private Document createDOM(SDDocument doc) { 1.120 + // Get infoset 1.121 + ByteArrayBuffer bab = new ByteArrayBuffer(); 1.122 + try { 1.123 + doc.writeTo(null, resolver, bab); 1.124 + } catch (IOException ioe) { 1.125 + throw new WebServiceException(ioe); 1.126 + } 1.127 + 1.128 + // Convert infoset to DOM 1.129 + Transformer trans = XmlUtil.newTransformer(); 1.130 + Source source = new StreamSource(bab.newInputStream(), null); //doc.getURL().toExternalForm()); 1.131 + DOMResult result = new DOMResult(); 1.132 + try { 1.133 + trans.transform(source, result); 1.134 + } catch(TransformerException te) { 1.135 + throw new WebServiceException(te); 1.136 + } 1.137 + return (Document)result.getNode(); 1.138 + } 1.139 + 1.140 + protected class MetadataResolverImpl implements SDDocumentResolver, LSResourceResolver { 1.141 + 1.142 + // systemID --> SDDocument 1.143 + final Map<String, SDDocument> docs = new HashMap<String, SDDocument>(); 1.144 + 1.145 + // targetnamespace --> SDDocument 1.146 + final Map<String, SDDocument> nsMapping = new HashMap<String, SDDocument>(); 1.147 + 1.148 + public MetadataResolverImpl() { 1.149 + } 1.150 + 1.151 + public MetadataResolverImpl(Iterable<SDDocument> it) { 1.152 + for(SDDocument doc : it) { 1.153 + if (doc.isSchema()) { 1.154 + docs.put(doc.getURL().toExternalForm(), doc); 1.155 + nsMapping.put(((SDDocument.Schema)doc).getTargetNamespace(), doc); 1.156 + } 1.157 + } 1.158 + } 1.159 + 1.160 + void addSchema(Source schema) { 1.161 + assert schema.getSystemId() != null; 1.162 + 1.163 + String systemId = schema.getSystemId(); 1.164 + try { 1.165 + XMLStreamBufferResult xsbr = XmlUtil.identityTransform(schema, new XMLStreamBufferResult()); 1.166 + SDDocumentSource sds = SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer()); 1.167 + SDDocument sdoc = SDDocumentImpl.create(sds, new QName(""), new QName("")); 1.168 + docs.put(systemId, sdoc); 1.169 + nsMapping.put(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc); 1.170 + } catch(Exception ex) { 1.171 + LOGGER.log(Level.WARNING, "Exception in adding schemas to resolver", ex); 1.172 + } 1.173 + } 1.174 + 1.175 + void addSchemas(Collection<? extends Source> schemas) { 1.176 + for(Source src : schemas) { 1.177 + addSchema(src); 1.178 + } 1.179 + } 1.180 + 1.181 + public SDDocument resolve(String systemId) { 1.182 + SDDocument sdi = docs.get(systemId); 1.183 + if (sdi == null) { 1.184 + SDDocumentSource sds; 1.185 + try { 1.186 + sds = SDDocumentSource.create(new URL(systemId)); 1.187 + } catch(MalformedURLException e) { 1.188 + throw new WebServiceException(e); 1.189 + } 1.190 + sdi = SDDocumentImpl.create(sds, new QName(""), new QName("")); 1.191 + docs.put(systemId, sdi); 1.192 + } 1.193 + return sdi; 1.194 + } 1.195 + 1.196 + public LSInput resolveResource(String type, String namespaceURI, String publicId, final String systemId, final String baseURI) { 1.197 + LOGGER.fine("type="+type+ " namespaceURI="+namespaceURI+" publicId="+publicId+" systemId="+systemId+" baseURI="+baseURI); 1.198 + try { 1.199 + final SDDocument doc; 1.200 + if (systemId == null) { 1.201 + doc = nsMapping.get(namespaceURI); 1.202 + } else { 1.203 + URI rel = (baseURI != null) 1.204 + ? new URI(baseURI).resolve(systemId) 1.205 + : new URI(systemId); 1.206 + doc = docs.get(rel.toString()); 1.207 + } 1.208 + if (doc != null) { 1.209 + return new LSInput() { 1.210 + 1.211 + public Reader getCharacterStream() { 1.212 + return null; 1.213 + } 1.214 + 1.215 + public void setCharacterStream(Reader characterStream) { 1.216 + throw new UnsupportedOperationException(); 1.217 + } 1.218 + 1.219 + public InputStream getByteStream() { 1.220 + ByteArrayBuffer bab = new ByteArrayBuffer(); 1.221 + try { 1.222 + doc.writeTo(null, resolver, bab); 1.223 + } catch (IOException ioe) { 1.224 + throw new WebServiceException(ioe); 1.225 + } 1.226 + return bab.newInputStream(); 1.227 + } 1.228 + 1.229 + public void setByteStream(InputStream byteStream) { 1.230 + throw new UnsupportedOperationException(); 1.231 + } 1.232 + 1.233 + public String getStringData() { 1.234 + return null; 1.235 + } 1.236 + 1.237 + public void setStringData(String stringData) { 1.238 + throw new UnsupportedOperationException(); 1.239 + } 1.240 + 1.241 + public String getSystemId() { 1.242 + return doc.getURL().toExternalForm(); 1.243 + } 1.244 + 1.245 + public void setSystemId(String systemId) { 1.246 + throw new UnsupportedOperationException(); 1.247 + } 1.248 + 1.249 + public String getPublicId() { 1.250 + return null; 1.251 + } 1.252 + 1.253 + public void setPublicId(String publicId) { 1.254 + throw new UnsupportedOperationException(); 1.255 + } 1.256 + 1.257 + public String getBaseURI() { 1.258 + return doc.getURL().toExternalForm(); 1.259 + } 1.260 + 1.261 + public void setBaseURI(String baseURI) { 1.262 + throw new UnsupportedOperationException(); 1.263 + } 1.264 + 1.265 + public String getEncoding() { 1.266 + return null; 1.267 + } 1.268 + 1.269 + public void setEncoding(String encoding) { 1.270 + throw new UnsupportedOperationException(); 1.271 + } 1.272 + 1.273 + public boolean getCertifiedText() { 1.274 + return false; 1.275 + } 1.276 + 1.277 + public void setCertifiedText(boolean certifiedText) { 1.278 + throw new UnsupportedOperationException(); 1.279 + } 1.280 + }; 1.281 + } 1.282 + } catch(Exception e) { 1.283 + LOGGER.log(Level.WARNING, "Exception in LSResourceResolver impl", e); 1.284 + } 1.285 + LOGGER.fine("Don't know about systemId="+systemId+" baseURI="+baseURI); 1.286 + return null; 1.287 + } 1.288 + 1.289 + } 1.290 + 1.291 + private void updateMultiSchemaForTns(String tns, String systemId, Map<String, List<String>> schemas) { 1.292 + List<String> docIdList = schemas.get(tns); 1.293 + if (docIdList == null) { 1.294 + docIdList = new ArrayList<String>(); 1.295 + schemas.put(tns, docIdList); 1.296 + } 1.297 + docIdList.add(systemId); 1.298 + } 1.299 + 1.300 + /* 1.301 + * Using the following algorithm described in the xerces discussion thread: 1.302 + * 1.303 + * "If you're synthesizing schema documents to glue together the ones in 1.304 + * the WSDL then you may not even need to use "honour-all-schemaLocations". 1.305 + * Create a schema document for each namespace with <xs:include>s 1.306 + * (for each schema document in the WSDL with that target namespace) 1.307 + * and then combine those together with <xs:import>s for each of those 1.308 + * namespaces in a "master" schema document. 1.309 + * 1.310 + * That should work with any schema processor, not just those which 1.311 + * honour multiple imports for the same namespace." 1.312 + */ 1.313 + protected Source[] getSchemaSources(Iterable<SDDocument> docs, MetadataResolverImpl mdresolver) { 1.314 + // All schema fragments in WSDLs are put inlinedSchemas 1.315 + // systemID --> DOMSource 1.316 + Map<String, DOMSource> inlinedSchemas = new HashMap<String, DOMSource>(); 1.317 + 1.318 + // Consolidates all the schemas(inlined and external) for a tns 1.319 + // tns --> list of systemId 1.320 + Map<String, List<String>> multiSchemaForTns = new HashMap<String, List<String>>(); 1.321 + 1.322 + for(SDDocument sdoc: docs) { 1.323 + if (sdoc.isWSDL()) { 1.324 + Document dom = createDOM(sdoc); 1.325 + // Get xsd:schema node from WSDL's DOM 1.326 + addSchemaFragmentSource(dom, sdoc.getURL().toExternalForm(), inlinedSchemas); 1.327 + } else if (sdoc.isSchema()) { 1.328 + updateMultiSchemaForTns(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc.getURL().toExternalForm(), multiSchemaForTns); 1.329 + } 1.330 + } 1.331 + LOGGER.fine("WSDL inlined schema fragment documents(these are used to create a pseudo schema) = "+ inlinedSchemas.keySet()); 1.332 + for(DOMSource src: inlinedSchemas.values()) { 1.333 + String tns = getTargetNamespace(src); 1.334 + updateMultiSchemaForTns(tns, src.getSystemId(), multiSchemaForTns); 1.335 + } 1.336 + 1.337 + if (multiSchemaForTns.isEmpty()) { 1.338 + return new Source[0]; // WSDL doesn't have any schema fragments 1.339 + } else if (multiSchemaForTns.size() == 1 && multiSchemaForTns.values().iterator().next().size() == 1) { 1.340 + // It must be a inlined schema, otherwise there would be at least two schemas 1.341 + String systemId = multiSchemaForTns.values().iterator().next().get(0); 1.342 + return new Source[] {inlinedSchemas.get(systemId)}; 1.343 + } 1.344 + 1.345 + // need to resolve these inlined schema fragments 1.346 + mdresolver.addSchemas(inlinedSchemas.values()); 1.347 + 1.348 + // If there are multiple schema fragments for the same tns, create a 1.349 + // pseudo schema for that tns by using <xsd:include> of those. 1.350 + // tns --> systemId of a pseudo schema document (consolidated for that tns) 1.351 + Map<String, String> oneSchemaForTns = new HashMap<String, String>(); 1.352 + int i = 0; 1.353 + for(Map.Entry<String, List<String>> e: multiSchemaForTns.entrySet()) { 1.354 + String systemId; 1.355 + List<String> sameTnsSchemas = e.getValue(); 1.356 + if (sameTnsSchemas.size() > 1) { 1.357 + // SDDocumentSource should be changed to take String systemId 1.358 + // String pseudoSystemId = "urn:x-jax-ws-include-"+i++; 1.359 + systemId = "file:x-jax-ws-include-"+i++; 1.360 + Source src = createSameTnsPseudoSchema(e.getKey(), sameTnsSchemas, systemId); 1.361 + mdresolver.addSchema(src); 1.362 + } else { 1.363 + systemId = sameTnsSchemas.get(0); 1.364 + } 1.365 + oneSchemaForTns.put(e.getKey(), systemId); 1.366 + } 1.367 + 1.368 + // create a master pseudo schema with all the different tns 1.369 + Source pseudoSchema = createMasterPseudoSchema(oneSchemaForTns); 1.370 + return new Source[] { pseudoSchema }; 1.371 + } 1.372 + 1.373 + private @Nullable void addSchemaFragmentSource(Document doc, String systemId, Map<String, DOMSource> map) { 1.374 + Element e = doc.getDocumentElement(); 1.375 + assert e.getNamespaceURI().equals(WSDLConstants.NS_WSDL); 1.376 + assert e.getLocalName().equals("definitions"); 1.377 + 1.378 + NodeList typesList = e.getElementsByTagNameNS(WSDLConstants.NS_WSDL, "types"); 1.379 + for(int i=0; i < typesList.getLength(); i++) { 1.380 + NodeList schemaList = ((Element)typesList.item(i)).getElementsByTagNameNS(WSDLConstants.NS_XMLNS, "schema"); 1.381 + for(int j=0; j < schemaList.getLength(); j++) { 1.382 + Element elem = (Element)schemaList.item(j); 1.383 + NamespaceSupport nss = new NamespaceSupport(); 1.384 + // Doing this because transformer is not picking up inscope namespaces 1.385 + // why doesn't transformer pickup the inscope namespaces ?? 1.386 + buildNamespaceSupport(nss, elem); 1.387 + patchDOMFragment(nss, elem); 1.388 + String docId = systemId+"#schema"+j; 1.389 + map.put(docId, new DOMSource(elem, docId)); 1.390 + } 1.391 + } 1.392 + } 1.393 + 1.394 + 1.395 + /* 1.396 + * Recursively visit ancestors and build up {@link org.xml.sax.helpers.NamespaceSupport} object. 1.397 + */ 1.398 + private void buildNamespaceSupport(NamespaceSupport nss, Node node) { 1.399 + if(node==null || node.getNodeType()!=Node.ELEMENT_NODE) 1.400 + return; 1.401 + 1.402 + buildNamespaceSupport( nss, node.getParentNode() ); 1.403 + 1.404 + nss.pushContext(); 1.405 + NamedNodeMap atts = node.getAttributes(); 1.406 + for( int i=0; i<atts.getLength(); i++ ) { 1.407 + Attr a = (Attr)atts.item(i); 1.408 + if( "xmlns".equals(a.getPrefix()) ) { 1.409 + nss.declarePrefix( a.getLocalName(), a.getValue() ); 1.410 + continue; 1.411 + } 1.412 + if( "xmlns".equals(a.getName()) ) { 1.413 + nss.declarePrefix( "", a.getValue() ); 1.414 + //continue; 1.415 + } 1.416 + } 1.417 + } 1.418 + 1.419 + /** 1.420 + * Adds inscope namespaces as attributes to <xsd:schema> fragment nodes. 1.421 + * 1.422 + * @param nss namespace context info 1.423 + * @param elem that is patched with inscope namespaces 1.424 + */ 1.425 + private @Nullable void patchDOMFragment(NamespaceSupport nss, Element elem) { 1.426 + NamedNodeMap atts = elem.getAttributes(); 1.427 + for( Enumeration en = nss.getPrefixes(); en.hasMoreElements(); ) { 1.428 + String prefix = (String)en.nextElement(); 1.429 + 1.430 + for( int i=0; i<atts.getLength(); i++ ) { 1.431 + Attr a = (Attr)atts.item(i); 1.432 + if (!"xmlns".equals(a.getPrefix()) || !a.getLocalName().equals(prefix)) { 1.433 + LOGGER.fine("Patching with xmlns:"+prefix+"="+nss.getURI(prefix)); 1.434 + elem.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:"+prefix, nss.getURI(prefix)); 1.435 + } 1.436 + } 1.437 + } 1.438 + } 1.439 + 1.440 + /* 1.441 + * Creates a pseudo schema for the WSDL schema fragments that have the same 1.442 + * targetNamespace. 1.443 + * 1.444 + * <xsd:schema targetNamespace="X"> 1.445 + * <xsd:include schemaLocation="Y1"/> 1.446 + * <xsd:include schemaLocation="Y2"/> 1.447 + * </xsd:schema> 1.448 + * 1.449 + * @param tns targetNamespace of the the schema documents 1.450 + * @param docs collection of systemId for the schema documents that have the 1.451 + * same tns, the collection must have more than one document 1.452 + * @param psuedoSystemId for the created pseudo schema 1.453 + * @return Source of pseudo schema that can be used multiple times 1.454 + */ 1.455 + private @Nullable Source createSameTnsPseudoSchema(String tns, Collection<String> docs, String pseudoSystemId) { 1.456 + assert docs.size() > 1; 1.457 + 1.458 + final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'"); 1.459 + if (!tns.equals("")) { 1.460 + sb.append(" targetNamespace='").append(tns).append("'"); 1.461 + } 1.462 + sb.append(">\n"); 1.463 + for(String systemId : docs) { 1.464 + sb.append("<xsd:include schemaLocation='").append(systemId).append("'/>\n"); 1.465 + } 1.466 + sb.append("</xsd:schema>\n"); 1.467 + LOGGER.fine("Pseudo Schema for the same tns="+tns+"is "+sb); 1.468 + 1.469 + // override getReader() so that the same source can be used multiple times 1.470 + return new StreamSource(pseudoSystemId) { 1.471 + @Override 1.472 + public Reader getReader() { 1.473 + return new StringReader(sb.toString()); 1.474 + } 1.475 + }; 1.476 + } 1.477 + 1.478 + /* 1.479 + * Creates a master pseudo schema importing all WSDL schema fragments with 1.480 + * different tns+pseudo schema for same tns. 1.481 + * <xsd:schema targetNamespace="urn:x-jax-ws-master"> 1.482 + * <xsd:import schemaLocation="Y1" namespace="X1"/> 1.483 + * <xsd:import schemaLocation="Y2" namespace="X2"/> 1.484 + * </xsd:schema> 1.485 + * 1.486 + * @param pseudo a map(tns-->systemId) of schema documents 1.487 + * @return Source of pseudo schema that can be used multiple times 1.488 + */ 1.489 + private Source createMasterPseudoSchema(Map<String, String> docs) { 1.490 + final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:x-jax-ws-master'>\n"); 1.491 + for(Map.Entry<String, String> e : docs.entrySet()) { 1.492 + String systemId = e.getValue(); 1.493 + String ns = e.getKey(); 1.494 + sb.append("<xsd:import schemaLocation='").append(systemId).append("'"); 1.495 + if (!ns.equals("")) { 1.496 + sb.append(" namespace='").append(ns).append("'"); 1.497 + } 1.498 + sb.append("/>\n"); 1.499 + } 1.500 + sb.append("</xsd:schema>"); 1.501 + LOGGER.fine("Master Pseudo Schema = "+sb); 1.502 + 1.503 + // override getReader() so that the same source can be used multiple times 1.504 + return new StreamSource("file:x-jax-ws-master-doc") { 1.505 + @Override 1.506 + public Reader getReader() { 1.507 + return new StringReader(sb.toString()); 1.508 + } 1.509 + }; 1.510 + } 1.511 + 1.512 + protected void doProcess(Packet packet) throws SAXException { 1.513 + getValidator().reset(); 1.514 + Class<? extends ValidationErrorHandler> handlerClass = feature.getErrorHandler(); 1.515 + ValidationErrorHandler handler; 1.516 + try { 1.517 + handler = handlerClass.newInstance(); 1.518 + } catch(Exception e) { 1.519 + throw new WebServiceException(e); 1.520 + } 1.521 + handler.setPacket(packet); 1.522 + getValidator().setErrorHandler(handler); 1.523 + Message msg = packet.getMessage().copy(); 1.524 + Source source = msg.readPayloadAsSource(); 1.525 + try { 1.526 + // Validator javadoc allows ONLY SAX, and DOM Sources 1.527 + // But the impl seems to handle all kinds. 1.528 + getValidator().validate(source); 1.529 + } catch(IOException e) { 1.530 + throw new WebServiceException(e); 1.531 + } 1.532 + } 1.533 + 1.534 + private String getTargetNamespace(DOMSource src) { 1.535 + Element elem = (Element)src.getNode(); 1.536 + return elem.getAttribute("targetNamespace"); 1.537 + } 1.538 + 1.539 +// protected static void printSource(Source src) { 1.540 +// try { 1.541 +// ByteArrayBuffer bos = new ByteArrayBuffer(); 1.542 +// StreamResult sr = new StreamResult(bos ); 1.543 +// Transformer trans = TransformerFactory.newInstance().newTransformer(); 1.544 +// trans.transform(src, sr); 1.545 +// LOGGER.info("**** src ******"+bos.toString()); 1.546 +// bos.close(); 1.547 +// } catch(Exception e) { 1.548 +// e.printStackTrace(); 1.549 +// } 1.550 +// } 1.551 + 1.552 +}