author | mkos |
Fri, 30 Oct 2015 10:34:46 +0100 | |
changeset 33547 | e4c76ac38b12 |
parent 29839 | 6d5d546e953b |
child 45678 | 65fdff10664d |
permissions | -rw-r--r-- |
12009 | 1 |
/* |
33547
e4c76ac38b12
8139743: Update JAX-WS RI integration to latest version (2.3.0-SNAPSHOT)
mkos
parents:
29839
diff
changeset
|
2 |
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
12009 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package com.sun.xml.internal.ws.util.pipe; |
|
27 |
||
28 |
import com.sun.istack.internal.NotNull; |
|
29 |
import com.sun.istack.internal.Nullable; |
|
30 |
import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult; |
|
31 |
import com.sun.xml.internal.ws.api.WSBinding; |
|
32 |
import com.sun.xml.internal.ws.api.message.Message; |
|
33 |
import com.sun.xml.internal.ws.api.message.Packet; |
|
34 |
import com.sun.xml.internal.ws.api.pipe.Tube; |
|
35 |
import com.sun.xml.internal.ws.api.pipe.TubeCloner; |
|
36 |
import com.sun.xml.internal.ws.api.pipe.helper.AbstractFilterTubeImpl; |
|
37 |
import com.sun.xml.internal.ws.api.server.DocumentAddressResolver; |
|
38 |
import com.sun.xml.internal.ws.api.server.SDDocument; |
|
39 |
import com.sun.xml.internal.ws.api.server.SDDocumentSource; |
|
40 |
import com.sun.xml.internal.ws.developer.SchemaValidationFeature; |
|
41 |
import com.sun.xml.internal.ws.developer.ValidationErrorHandler; |
|
42 |
import com.sun.xml.internal.ws.server.SDDocumentImpl; |
|
43 |
import com.sun.xml.internal.ws.util.ByteArrayBuffer; |
|
44 |
import com.sun.xml.internal.ws.util.xml.XmlUtil; |
|
45 |
import com.sun.xml.internal.ws.wsdl.SDDocumentResolver; |
|
46 |
import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; |
|
47 |
import org.w3c.dom.*; |
|
48 |
import org.w3c.dom.ls.LSInput; |
|
49 |
import org.w3c.dom.ls.LSResourceResolver; |
|
50 |
import org.xml.sax.SAXException; |
|
51 |
import org.xml.sax.helpers.NamespaceSupport; |
|
52 |
||
53 |
import javax.xml.XMLConstants; |
|
54 |
import javax.xml.namespace.QName; |
|
55 |
import javax.xml.transform.Source; |
|
56 |
import javax.xml.transform.Transformer; |
|
57 |
import javax.xml.transform.TransformerException; |
|
58 |
import javax.xml.transform.dom.DOMResult; |
|
59 |
import javax.xml.transform.dom.DOMSource; |
|
60 |
import javax.xml.transform.stream.StreamSource; |
|
61 |
import javax.xml.validation.SchemaFactory; |
|
62 |
import javax.xml.validation.Validator; |
|
63 |
import javax.xml.ws.WebServiceException; |
|
64 |
import java.io.IOException; |
|
65 |
import java.io.InputStream; |
|
66 |
import java.io.Reader; |
|
67 |
import java.io.StringReader; |
|
68 |
import java.net.MalformedURLException; |
|
69 |
import java.net.URI; |
|
70 |
import java.net.URL; |
|
71 |
import java.util.*; |
|
72 |
import java.util.logging.Level; |
|
73 |
import java.util.logging.Logger; |
|
74 |
||
20590
b3b34e4344ce
8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
mkos
parents:
19645
diff
changeset
|
75 |
import static com.sun.xml.internal.ws.util.xml.XmlUtil.allowExternalAccess; |
19645
36f707905f2b
8022885: Update JAX-WS RI integration to 2.2.9-b14140
mkos
parents:
16791
diff
changeset
|
76 |
|
12009 | 77 |
/** |
78 |
* {@link Tube} that does the schema validation. |
|
79 |
* |
|
80 |
* @author Jitendra Kotamraju |
|
81 |
*/ |
|
82 |
public abstract class AbstractSchemaValidationTube extends AbstractFilterTubeImpl { |
|
83 |
||
84 |
private static final Logger LOGGER = Logger.getLogger(AbstractSchemaValidationTube.class.getName()); |
|
85 |
||
86 |
protected final WSBinding binding; |
|
87 |
protected final SchemaValidationFeature feature; |
|
88 |
protected final DocumentAddressResolver resolver = new ValidationDocumentAddressResolver(); |
|
89 |
protected final SchemaFactory sf; |
|
90 |
||
91 |
public AbstractSchemaValidationTube(WSBinding binding, Tube next) { |
|
92 |
super(next); |
|
93 |
this.binding = binding; |
|
94 |
feature = binding.getFeature(SchemaValidationFeature.class); |
|
29839
6d5d546e953b
8076549: Update JAX-WS RI integration to latest version (2.2.11-b150402.1412)
aefimov
parents:
27837
diff
changeset
|
95 |
sf = allowExternalAccess(SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), "all", false); |
12009 | 96 |
} |
97 |
||
98 |
protected AbstractSchemaValidationTube(AbstractSchemaValidationTube that, TubeCloner cloner) { |
|
99 |
super(that, cloner); |
|
100 |
this.binding = that.binding; |
|
101 |
this.feature = that.feature; |
|
102 |
this.sf = that.sf; |
|
103 |
} |
|
104 |
||
105 |
protected abstract Validator getValidator(); |
|
106 |
||
107 |
protected abstract boolean isNoValidation(); |
|
108 |
||
109 |
private static class ValidationDocumentAddressResolver implements DocumentAddressResolver { |
|
110 |
||
111 |
@Nullable |
|
16791 | 112 |
@Override |
12009 | 113 |
public String getRelativeAddressFor(@NotNull SDDocument current, @NotNull SDDocument referenced) { |
16791 | 114 |
LOGGER.log(Level.FINE, "Current = {0} resolved relative={1}", new Object[]{current.getURL(), referenced.getURL()}); |
12009 | 115 |
return referenced.getURL().toExternalForm(); |
116 |
} |
|
117 |
} |
|
118 |
||
119 |
private Document createDOM(SDDocument doc) { |
|
120 |
// Get infoset |
|
121 |
ByteArrayBuffer bab = new ByteArrayBuffer(); |
|
122 |
try { |
|
123 |
doc.writeTo(null, resolver, bab); |
|
124 |
} catch (IOException ioe) { |
|
125 |
throw new WebServiceException(ioe); |
|
126 |
} |
|
127 |
||
128 |
// Convert infoset to DOM |
|
129 |
Transformer trans = XmlUtil.newTransformer(); |
|
130 |
Source source = new StreamSource(bab.newInputStream(), null); //doc.getURL().toExternalForm()); |
|
131 |
DOMResult result = new DOMResult(); |
|
132 |
try { |
|
133 |
trans.transform(source, result); |
|
134 |
} catch(TransformerException te) { |
|
135 |
throw new WebServiceException(te); |
|
136 |
} |
|
137 |
return (Document)result.getNode(); |
|
138 |
} |
|
139 |
||
140 |
protected class MetadataResolverImpl implements SDDocumentResolver, LSResourceResolver { |
|
141 |
||
142 |
// systemID --> SDDocument |
|
143 |
final Map<String, SDDocument> docs = new HashMap<String, SDDocument>(); |
|
144 |
||
145 |
// targetnamespace --> SDDocument |
|
146 |
final Map<String, SDDocument> nsMapping = new HashMap<String, SDDocument>(); |
|
147 |
||
148 |
public MetadataResolverImpl() { |
|
149 |
} |
|
150 |
||
151 |
public MetadataResolverImpl(Iterable<SDDocument> it) { |
|
152 |
for(SDDocument doc : it) { |
|
153 |
if (doc.isSchema()) { |
|
154 |
docs.put(doc.getURL().toExternalForm(), doc); |
|
155 |
nsMapping.put(((SDDocument.Schema)doc).getTargetNamespace(), doc); |
|
156 |
} |
|
157 |
} |
|
158 |
} |
|
159 |
||
160 |
void addSchema(Source schema) { |
|
161 |
assert schema.getSystemId() != null; |
|
162 |
||
163 |
String systemId = schema.getSystemId(); |
|
164 |
try { |
|
165 |
XMLStreamBufferResult xsbr = XmlUtil.identityTransform(schema, new XMLStreamBufferResult()); |
|
166 |
SDDocumentSource sds = SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer()); |
|
167 |
SDDocument sdoc = SDDocumentImpl.create(sds, new QName(""), new QName("")); |
|
168 |
docs.put(systemId, sdoc); |
|
169 |
nsMapping.put(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc); |
|
170 |
} catch(Exception ex) { |
|
171 |
LOGGER.log(Level.WARNING, "Exception in adding schemas to resolver", ex); |
|
172 |
} |
|
173 |
} |
|
174 |
||
175 |
void addSchemas(Collection<? extends Source> schemas) { |
|
176 |
for(Source src : schemas) { |
|
177 |
addSchema(src); |
|
178 |
} |
|
179 |
} |
|
180 |
||
16791 | 181 |
@Override |
12009 | 182 |
public SDDocument resolve(String systemId) { |
183 |
SDDocument sdi = docs.get(systemId); |
|
184 |
if (sdi == null) { |
|
185 |
SDDocumentSource sds; |
|
186 |
try { |
|
187 |
sds = SDDocumentSource.create(new URL(systemId)); |
|
188 |
} catch(MalformedURLException e) { |
|
189 |
throw new WebServiceException(e); |
|
190 |
} |
|
191 |
sdi = SDDocumentImpl.create(sds, new QName(""), new QName("")); |
|
192 |
docs.put(systemId, sdi); |
|
193 |
} |
|
194 |
return sdi; |
|
195 |
} |
|
196 |
||
16791 | 197 |
@Override |
12009 | 198 |
public LSInput resolveResource(String type, String namespaceURI, String publicId, final String systemId, final String baseURI) { |
16791 | 199 |
if (LOGGER.isLoggable(Level.FINE)) { |
200 |
LOGGER.log(Level.FINE, "type={0} namespaceURI={1} publicId={2} systemId={3} baseURI={4}", new Object[]{type, namespaceURI, publicId, systemId, baseURI}); |
|
201 |
} |
|
12009 | 202 |
try { |
203 |
final SDDocument doc; |
|
204 |
if (systemId == null) { |
|
205 |
doc = nsMapping.get(namespaceURI); |
|
206 |
} else { |
|
207 |
URI rel = (baseURI != null) |
|
208 |
? new URI(baseURI).resolve(systemId) |
|
209 |
: new URI(systemId); |
|
210 |
doc = docs.get(rel.toString()); |
|
211 |
} |
|
212 |
if (doc != null) { |
|
213 |
return new LSInput() { |
|
214 |
||
16791 | 215 |
@Override |
12009 | 216 |
public Reader getCharacterStream() { |
217 |
return null; |
|
218 |
} |
|
219 |
||
16791 | 220 |
@Override |
12009 | 221 |
public void setCharacterStream(Reader characterStream) { |
222 |
throw new UnsupportedOperationException(); |
|
223 |
} |
|
224 |
||
16791 | 225 |
@Override |
12009 | 226 |
public InputStream getByteStream() { |
227 |
ByteArrayBuffer bab = new ByteArrayBuffer(); |
|
228 |
try { |
|
229 |
doc.writeTo(null, resolver, bab); |
|
230 |
} catch (IOException ioe) { |
|
231 |
throw new WebServiceException(ioe); |
|
232 |
} |
|
233 |
return bab.newInputStream(); |
|
234 |
} |
|
235 |
||
16791 | 236 |
@Override |
12009 | 237 |
public void setByteStream(InputStream byteStream) { |
238 |
throw new UnsupportedOperationException(); |
|
239 |
} |
|
240 |
||
16791 | 241 |
@Override |
12009 | 242 |
public String getStringData() { |
243 |
return null; |
|
244 |
} |
|
245 |
||
16791 | 246 |
@Override |
12009 | 247 |
public void setStringData(String stringData) { |
248 |
throw new UnsupportedOperationException(); |
|
249 |
} |
|
250 |
||
16791 | 251 |
@Override |
12009 | 252 |
public String getSystemId() { |
253 |
return doc.getURL().toExternalForm(); |
|
254 |
} |
|
255 |
||
16791 | 256 |
@Override |
12009 | 257 |
public void setSystemId(String systemId) { |
258 |
throw new UnsupportedOperationException(); |
|
259 |
} |
|
260 |
||
16791 | 261 |
@Override |
12009 | 262 |
public String getPublicId() { |
263 |
return null; |
|
264 |
} |
|
265 |
||
16791 | 266 |
@Override |
12009 | 267 |
public void setPublicId(String publicId) { |
268 |
throw new UnsupportedOperationException(); |
|
269 |
} |
|
270 |
||
16791 | 271 |
@Override |
12009 | 272 |
public String getBaseURI() { |
273 |
return doc.getURL().toExternalForm(); |
|
274 |
} |
|
275 |
||
16791 | 276 |
@Override |
12009 | 277 |
public void setBaseURI(String baseURI) { |
278 |
throw new UnsupportedOperationException(); |
|
279 |
} |
|
280 |
||
16791 | 281 |
@Override |
12009 | 282 |
public String getEncoding() { |
283 |
return null; |
|
284 |
} |
|
285 |
||
16791 | 286 |
@Override |
12009 | 287 |
public void setEncoding(String encoding) { |
288 |
throw new UnsupportedOperationException(); |
|
289 |
} |
|
290 |
||
16791 | 291 |
@Override |
12009 | 292 |
public boolean getCertifiedText() { |
293 |
return false; |
|
294 |
} |
|
295 |
||
16791 | 296 |
@Override |
12009 | 297 |
public void setCertifiedText(boolean certifiedText) { |
298 |
throw new UnsupportedOperationException(); |
|
299 |
} |
|
300 |
}; |
|
301 |
} |
|
302 |
} catch(Exception e) { |
|
303 |
LOGGER.log(Level.WARNING, "Exception in LSResourceResolver impl", e); |
|
304 |
} |
|
16791 | 305 |
if (LOGGER.isLoggable(Level.FINE)) { |
306 |
LOGGER.log(Level.FINE, "Don''t know about systemId={0} baseURI={1}", new Object[]{systemId, baseURI}); |
|
307 |
} |
|
12009 | 308 |
return null; |
309 |
} |
|
310 |
||
311 |
} |
|
312 |
||
313 |
private void updateMultiSchemaForTns(String tns, String systemId, Map<String, List<String>> schemas) { |
|
314 |
List<String> docIdList = schemas.get(tns); |
|
315 |
if (docIdList == null) { |
|
316 |
docIdList = new ArrayList<String>(); |
|
317 |
schemas.put(tns, docIdList); |
|
318 |
} |
|
319 |
docIdList.add(systemId); |
|
320 |
} |
|
321 |
||
322 |
/* |
|
323 |
* Using the following algorithm described in the xerces discussion thread: |
|
324 |
* |
|
325 |
* "If you're synthesizing schema documents to glue together the ones in |
|
326 |
* the WSDL then you may not even need to use "honour-all-schemaLocations". |
|
327 |
* Create a schema document for each namespace with <xs:include>s |
|
328 |
* (for each schema document in the WSDL with that target namespace) |
|
329 |
* and then combine those together with <xs:import>s for each of those |
|
330 |
* namespaces in a "master" schema document. |
|
331 |
* |
|
332 |
* That should work with any schema processor, not just those which |
|
333 |
* honour multiple imports for the same namespace." |
|
334 |
*/ |
|
335 |
protected Source[] getSchemaSources(Iterable<SDDocument> docs, MetadataResolverImpl mdresolver) { |
|
336 |
// All schema fragments in WSDLs are put inlinedSchemas |
|
337 |
// systemID --> DOMSource |
|
338 |
Map<String, DOMSource> inlinedSchemas = new HashMap<String, DOMSource>(); |
|
339 |
||
340 |
// Consolidates all the schemas(inlined and external) for a tns |
|
341 |
// tns --> list of systemId |
|
342 |
Map<String, List<String>> multiSchemaForTns = new HashMap<String, List<String>>(); |
|
343 |
||
344 |
for(SDDocument sdoc: docs) { |
|
345 |
if (sdoc.isWSDL()) { |
|
346 |
Document dom = createDOM(sdoc); |
|
347 |
// Get xsd:schema node from WSDL's DOM |
|
348 |
addSchemaFragmentSource(dom, sdoc.getURL().toExternalForm(), inlinedSchemas); |
|
349 |
} else if (sdoc.isSchema()) { |
|
350 |
updateMultiSchemaForTns(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc.getURL().toExternalForm(), multiSchemaForTns); |
|
351 |
} |
|
352 |
} |
|
16791 | 353 |
if (LOGGER.isLoggable(Level.FINE)) { |
354 |
LOGGER.log(Level.FINE, "WSDL inlined schema fragment documents(these are used to create a pseudo schema) = {0}", inlinedSchemas.keySet()); |
|
355 |
} |
|
12009 | 356 |
for(DOMSource src: inlinedSchemas.values()) { |
357 |
String tns = getTargetNamespace(src); |
|
358 |
updateMultiSchemaForTns(tns, src.getSystemId(), multiSchemaForTns); |
|
359 |
} |
|
360 |
||
361 |
if (multiSchemaForTns.isEmpty()) { |
|
362 |
return new Source[0]; // WSDL doesn't have any schema fragments |
|
363 |
} else if (multiSchemaForTns.size() == 1 && multiSchemaForTns.values().iterator().next().size() == 1) { |
|
364 |
// It must be a inlined schema, otherwise there would be at least two schemas |
|
365 |
String systemId = multiSchemaForTns.values().iterator().next().get(0); |
|
366 |
return new Source[] {inlinedSchemas.get(systemId)}; |
|
367 |
} |
|
368 |
||
369 |
// need to resolve these inlined schema fragments |
|
370 |
mdresolver.addSchemas(inlinedSchemas.values()); |
|
371 |
||
372 |
// If there are multiple schema fragments for the same tns, create a |
|
373 |
// pseudo schema for that tns by using <xsd:include> of those. |
|
374 |
// tns --> systemId of a pseudo schema document (consolidated for that tns) |
|
375 |
Map<String, String> oneSchemaForTns = new HashMap<String, String>(); |
|
376 |
int i = 0; |
|
377 |
for(Map.Entry<String, List<String>> e: multiSchemaForTns.entrySet()) { |
|
378 |
String systemId; |
|
379 |
List<String> sameTnsSchemas = e.getValue(); |
|
380 |
if (sameTnsSchemas.size() > 1) { |
|
381 |
// SDDocumentSource should be changed to take String systemId |
|
382 |
// String pseudoSystemId = "urn:x-jax-ws-include-"+i++; |
|
383 |
systemId = "file:x-jax-ws-include-"+i++; |
|
384 |
Source src = createSameTnsPseudoSchema(e.getKey(), sameTnsSchemas, systemId); |
|
385 |
mdresolver.addSchema(src); |
|
386 |
} else { |
|
387 |
systemId = sameTnsSchemas.get(0); |
|
388 |
} |
|
389 |
oneSchemaForTns.put(e.getKey(), systemId); |
|
390 |
} |
|
391 |
||
392 |
// create a master pseudo schema with all the different tns |
|
393 |
Source pseudoSchema = createMasterPseudoSchema(oneSchemaForTns); |
|
394 |
return new Source[] { pseudoSchema }; |
|
395 |
} |
|
396 |
||
397 |
private @Nullable void addSchemaFragmentSource(Document doc, String systemId, Map<String, DOMSource> map) { |
|
398 |
Element e = doc.getDocumentElement(); |
|
399 |
assert e.getNamespaceURI().equals(WSDLConstants.NS_WSDL); |
|
400 |
assert e.getLocalName().equals("definitions"); |
|
401 |
||
402 |
NodeList typesList = e.getElementsByTagNameNS(WSDLConstants.NS_WSDL, "types"); |
|
403 |
for(int i=0; i < typesList.getLength(); i++) { |
|
404 |
NodeList schemaList = ((Element)typesList.item(i)).getElementsByTagNameNS(WSDLConstants.NS_XMLNS, "schema"); |
|
405 |
for(int j=0; j < schemaList.getLength(); j++) { |
|
406 |
Element elem = (Element)schemaList.item(j); |
|
407 |
NamespaceSupport nss = new NamespaceSupport(); |
|
408 |
// Doing this because transformer is not picking up inscope namespaces |
|
409 |
// why doesn't transformer pickup the inscope namespaces ?? |
|
410 |
buildNamespaceSupport(nss, elem); |
|
411 |
patchDOMFragment(nss, elem); |
|
412 |
String docId = systemId+"#schema"+j; |
|
413 |
map.put(docId, new DOMSource(elem, docId)); |
|
414 |
} |
|
415 |
} |
|
416 |
} |
|
417 |
||
418 |
||
419 |
/* |
|
420 |
* Recursively visit ancestors and build up {@link org.xml.sax.helpers.NamespaceSupport} object. |
|
421 |
*/ |
|
422 |
private void buildNamespaceSupport(NamespaceSupport nss, Node node) { |
|
16791 | 423 |
if (node==null || node.getNodeType()!=Node.ELEMENT_NODE) { |
12009 | 424 |
return; |
16791 | 425 |
} |
12009 | 426 |
|
427 |
buildNamespaceSupport( nss, node.getParentNode() ); |
|
428 |
||
429 |
nss.pushContext(); |
|
430 |
NamedNodeMap atts = node.getAttributes(); |
|
431 |
for( int i=0; i<atts.getLength(); i++ ) { |
|
432 |
Attr a = (Attr)atts.item(i); |
|
433 |
if( "xmlns".equals(a.getPrefix()) ) { |
|
434 |
nss.declarePrefix( a.getLocalName(), a.getValue() ); |
|
435 |
continue; |
|
436 |
} |
|
437 |
if( "xmlns".equals(a.getName()) ) { |
|
438 |
nss.declarePrefix( "", a.getValue() ); |
|
439 |
//continue; |
|
440 |
} |
|
441 |
} |
|
442 |
} |
|
443 |
||
444 |
/** |
|
445 |
* Adds inscope namespaces as attributes to <xsd:schema> fragment nodes. |
|
446 |
* |
|
447 |
* @param nss namespace context info |
|
448 |
* @param elem that is patched with inscope namespaces |
|
449 |
*/ |
|
450 |
private @Nullable void patchDOMFragment(NamespaceSupport nss, Element elem) { |
|
451 |
NamedNodeMap atts = elem.getAttributes(); |
|
452 |
for( Enumeration en = nss.getPrefixes(); en.hasMoreElements(); ) { |
|
453 |
String prefix = (String)en.nextElement(); |
|
454 |
||
455 |
for( int i=0; i<atts.getLength(); i++ ) { |
|
456 |
Attr a = (Attr)atts.item(i); |
|
457 |
if (!"xmlns".equals(a.getPrefix()) || !a.getLocalName().equals(prefix)) { |
|
16791 | 458 |
if (LOGGER.isLoggable(Level.FINE)) { |
459 |
LOGGER.log(Level.FINE, "Patching with xmlns:{0}={1}", new Object[]{prefix, nss.getURI(prefix)}); |
|
460 |
} |
|
12009 | 461 |
elem.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:"+prefix, nss.getURI(prefix)); |
462 |
} |
|
463 |
} |
|
464 |
} |
|
465 |
} |
|
466 |
||
467 |
/* |
|
468 |
* Creates a pseudo schema for the WSDL schema fragments that have the same |
|
469 |
* targetNamespace. |
|
470 |
* |
|
471 |
* <xsd:schema targetNamespace="X"> |
|
472 |
* <xsd:include schemaLocation="Y1"/> |
|
473 |
* <xsd:include schemaLocation="Y2"/> |
|
474 |
* </xsd:schema> |
|
475 |
* |
|
476 |
* @param tns targetNamespace of the the schema documents |
|
477 |
* @param docs collection of systemId for the schema documents that have the |
|
478 |
* same tns, the collection must have more than one document |
|
479 |
* @param psuedoSystemId for the created pseudo schema |
|
480 |
* @return Source of pseudo schema that can be used multiple times |
|
481 |
*/ |
|
482 |
private @Nullable Source createSameTnsPseudoSchema(String tns, Collection<String> docs, String pseudoSystemId) { |
|
483 |
assert docs.size() > 1; |
|
484 |
||
485 |
final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'"); |
|
27837
86d4f46e622a
8065870: Update JAX-WS RI integration to latest version (2.2.11-b141124.1933)
mkos
parents:
25871
diff
changeset
|
486 |
if (!"".equals(tns)) { |
12009 | 487 |
sb.append(" targetNamespace='").append(tns).append("'"); |
488 |
} |
|
489 |
sb.append(">\n"); |
|
490 |
for(String systemId : docs) { |
|
491 |
sb.append("<xsd:include schemaLocation='").append(systemId).append("'/>\n"); |
|
492 |
} |
|
493 |
sb.append("</xsd:schema>\n"); |
|
16791 | 494 |
if (LOGGER.isLoggable(Level.FINE)) { |
495 |
LOGGER.log(Level.FINE, "Pseudo Schema for the same tns={0}is {1}", new Object[]{tns, sb}); |
|
496 |
} |
|
12009 | 497 |
|
498 |
// override getReader() so that the same source can be used multiple times |
|
499 |
return new StreamSource(pseudoSystemId) { |
|
500 |
@Override |
|
501 |
public Reader getReader() { |
|
502 |
return new StringReader(sb.toString()); |
|
503 |
} |
|
504 |
}; |
|
505 |
} |
|
506 |
||
507 |
/* |
|
508 |
* Creates a master pseudo schema importing all WSDL schema fragments with |
|
509 |
* different tns+pseudo schema for same tns. |
|
510 |
* <xsd:schema targetNamespace="urn:x-jax-ws-master"> |
|
511 |
* <xsd:import schemaLocation="Y1" namespace="X1"/> |
|
512 |
* <xsd:import schemaLocation="Y2" namespace="X2"/> |
|
513 |
* </xsd:schema> |
|
514 |
* |
|
515 |
* @param pseudo a map(tns-->systemId) of schema documents |
|
516 |
* @return Source of pseudo schema that can be used multiple times |
|
517 |
*/ |
|
518 |
private Source createMasterPseudoSchema(Map<String, String> docs) { |
|
519 |
final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:x-jax-ws-master'>\n"); |
|
520 |
for(Map.Entry<String, String> e : docs.entrySet()) { |
|
521 |
String systemId = e.getValue(); |
|
522 |
String ns = e.getKey(); |
|
523 |
sb.append("<xsd:import schemaLocation='").append(systemId).append("'"); |
|
33547
e4c76ac38b12
8139743: Update JAX-WS RI integration to latest version (2.3.0-SNAPSHOT)
mkos
parents:
29839
diff
changeset
|
524 |
if (ns != null && !("".equals(ns))) { |
12009 | 525 |
sb.append(" namespace='").append(ns).append("'"); |
526 |
} |
|
527 |
sb.append("/>\n"); |
|
528 |
} |
|
529 |
sb.append("</xsd:schema>"); |
|
16791 | 530 |
if (LOGGER.isLoggable(Level.FINE)) { |
531 |
LOGGER.log(Level.FINE, "Master Pseudo Schema = {0}", sb); |
|
532 |
} |
|
12009 | 533 |
|
534 |
// override getReader() so that the same source can be used multiple times |
|
535 |
return new StreamSource("file:x-jax-ws-master-doc") { |
|
536 |
@Override |
|
537 |
public Reader getReader() { |
|
538 |
return new StringReader(sb.toString()); |
|
539 |
} |
|
540 |
}; |
|
541 |
} |
|
542 |
||
543 |
protected void doProcess(Packet packet) throws SAXException { |
|
544 |
getValidator().reset(); |
|
545 |
Class<? extends ValidationErrorHandler> handlerClass = feature.getErrorHandler(); |
|
546 |
ValidationErrorHandler handler; |
|
547 |
try { |
|
548 |
handler = handlerClass.newInstance(); |
|
549 |
} catch(Exception e) { |
|
550 |
throw new WebServiceException(e); |
|
551 |
} |
|
552 |
handler.setPacket(packet); |
|
553 |
getValidator().setErrorHandler(handler); |
|
554 |
Message msg = packet.getMessage().copy(); |
|
555 |
Source source = msg.readPayloadAsSource(); |
|
556 |
try { |
|
557 |
// Validator javadoc allows ONLY SAX, and DOM Sources |
|
558 |
// But the impl seems to handle all kinds. |
|
559 |
getValidator().validate(source); |
|
560 |
} catch(IOException e) { |
|
561 |
throw new WebServiceException(e); |
|
562 |
} |
|
563 |
} |
|
564 |
||
565 |
private String getTargetNamespace(DOMSource src) { |
|
566 |
Element elem = (Element)src.getNode(); |
|
567 |
return elem.getAttribute("targetNamespace"); |
|
568 |
} |
|
569 |
||
570 |
// protected static void printSource(Source src) { |
|
571 |
// try { |
|
572 |
// ByteArrayBuffer bos = new ByteArrayBuffer(); |
|
573 |
// StreamResult sr = new StreamResult(bos ); |
|
574 |
// Transformer trans = TransformerFactory.newInstance().newTransformer(); |
|
575 |
// trans.transform(src, sr); |
|
576 |
// LOGGER.info("**** src ******"+bos.toString()); |
|
577 |
// bos.close(); |
|
578 |
// } catch(Exception e) { |
|
579 |
// e.printStackTrace(); |
|
580 |
// } |
|
581 |
// } |
|
582 |
||
583 |
} |