1.1 --- a/src/share/jaxws_classes/com/sun/xml/internal/ws/server/EndpointFactory.java Thu Apr 04 19:05:24 2013 -0700 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/server/EndpointFactory.java Tue Apr 09 14:51:13 2013 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -27,17 +27,27 @@ 1.11 1.12 import com.sun.istack.internal.NotNull; 1.13 import com.sun.istack.internal.Nullable; 1.14 +import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer; 1.15 import com.sun.xml.internal.ws.api.BindingID; 1.16 import com.sun.xml.internal.ws.api.WSBinding; 1.17 -import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory; 1.18 -import com.sun.xml.internal.ws.api.policy.PolicyResolver; 1.19 +import com.sun.xml.internal.ws.api.WSFeatureList; 1.20 +import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; 1.21 +import com.sun.xml.internal.ws.api.databinding.DatabindingFactory; 1.22 +import com.sun.xml.internal.ws.api.databinding.MetadataReader; 1.23 import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo; 1.24 -import com.sun.xml.internal.ws.api.databinding.DatabindingFactory; 1.25 -import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; 1.26 import com.sun.xml.internal.ws.api.model.SEIModel; 1.27 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 1.28 -import com.sun.xml.internal.ws.api.pipe.Tube; 1.29 -import com.sun.xml.internal.ws.api.server.*; 1.30 +import com.sun.xml.internal.ws.api.policy.PolicyResolver; 1.31 +import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory; 1.32 +import com.sun.xml.internal.ws.api.server.AsyncProvider; 1.33 +import com.sun.xml.internal.ws.api.server.Container; 1.34 +import com.sun.xml.internal.ws.api.server.ContainerResolver; 1.35 +import com.sun.xml.internal.ws.api.server.InstanceResolver; 1.36 +import com.sun.xml.internal.ws.api.server.Invoker; 1.37 +import com.sun.xml.internal.ws.api.server.SDDocument; 1.38 +import com.sun.xml.internal.ws.api.server.SDDocumentSource; 1.39 +import com.sun.xml.internal.ws.api.server.WSEndpoint; 1.40 +import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; 1.41 import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension; 1.42 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver; 1.43 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver.Parser; 1.44 @@ -46,11 +56,14 @@ 1.45 import com.sun.xml.internal.ws.binding.SOAPBindingImpl; 1.46 import com.sun.xml.internal.ws.binding.WebServiceFeatureList; 1.47 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; 1.48 +import com.sun.xml.internal.ws.model.ReflectAnnotationReader; 1.49 import com.sun.xml.internal.ws.model.RuntimeModeler; 1.50 import com.sun.xml.internal.ws.model.SOAPSEIModel; 1.51 import com.sun.xml.internal.ws.model.wsdl.WSDLModelImpl; 1.52 import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl; 1.53 import com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl; 1.54 +import com.sun.xml.internal.ws.policy.PolicyMap; 1.55 +import com.sun.xml.internal.ws.policy.jaxws.PolicyUtil; 1.56 import com.sun.xml.internal.ws.resources.ServerMessages; 1.57 import com.sun.xml.internal.ws.server.provider.ProviderInvokerTube; 1.58 import com.sun.xml.internal.ws.server.sei.SEIInvokerTube; 1.59 @@ -58,20 +71,20 @@ 1.60 import com.sun.xml.internal.ws.util.HandlerAnnotationProcessor; 1.61 import com.sun.xml.internal.ws.util.ServiceConfigurationError; 1.62 import com.sun.xml.internal.ws.util.ServiceFinder; 1.63 +import com.sun.xml.internal.ws.util.xml.XmlUtil; 1.64 import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser; 1.65 -import com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator; 1.66 -import com.sun.xml.internal.ws.policy.PolicyMap; 1.67 -import com.sun.xml.internal.ws.policy.jaxws.PolicyUtil; 1.68 import org.xml.sax.EntityResolver; 1.69 +import org.xml.sax.InputSource; 1.70 import org.xml.sax.SAXException; 1.71 1.72 import javax.jws.WebService; 1.73 import javax.xml.namespace.QName; 1.74 import javax.xml.stream.XMLStreamException; 1.75 +import javax.xml.stream.XMLStreamReader; 1.76 import javax.xml.ws.Provider; 1.77 import javax.xml.ws.WebServiceException; 1.78 +import javax.xml.ws.WebServiceFeature; 1.79 import javax.xml.ws.WebServiceProvider; 1.80 -import javax.xml.ws.WebServiceFeature; 1.81 import javax.xml.ws.soap.SOAPBinding; 1.82 import java.io.IOException; 1.83 import java.net.URL; 1.84 @@ -165,8 +178,10 @@ 1.85 if(implType ==null) 1.86 throw new IllegalArgumentException(); 1.87 1.88 + MetadataReader metadataReader = getExternalMetadatReader(implType, binding); 1.89 + 1.90 if (isStandard) { 1.91 - verifyImplementorClass(implType); 1.92 + verifyImplementorClass(implType, metadataReader); 1.93 } 1.94 1.95 if (invoker == null) { 1.96 @@ -184,10 +199,10 @@ 1.97 container = ContainerResolver.getInstance().getContainer(); 1.98 1.99 if(serviceName==null) 1.100 - serviceName = getDefaultServiceName(implType); 1.101 + serviceName = getDefaultServiceName(implType, metadataReader); 1.102 1.103 if(portName==null) 1.104 - portName = getDefaultPortName(serviceName,implType); 1.105 + portName = getDefaultPortName(serviceName,implType, metadataReader); 1.106 1.107 {// error check 1.108 String serviceNS = serviceName.getNamespaceURI(); 1.109 @@ -207,21 +222,21 @@ 1.110 1.111 QName portTypeName = null; 1.112 if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) { 1.113 - portTypeName = RuntimeModeler.getPortTypeName(implType); 1.114 + portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader); 1.115 } 1.116 1.117 // Categorises the documents as WSDL, Schema etc 1.118 List<SDDocumentImpl> docList = categoriseMetadata(md, serviceName, portTypeName); 1.119 // Finds the primary WSDL and makes sure that metadata doesn't have 1.120 // two concrete or abstract WSDLs 1.121 - SDDocumentImpl primaryDoc = findPrimary(docList); 1.122 + SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList); 1.123 1.124 EndpointAwareTube terminal; 1.125 WSDLPortImpl wsdlPort = null; 1.126 AbstractSEIModelImpl seiModel = null; 1.127 // create WSDL model 1.128 if (primaryDoc != null) { 1.129 - wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container); 1.130 + wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); 1.131 } 1.132 1.133 WebServiceFeatureList features=((BindingImpl)binding).getFeatures(); 1.134 @@ -247,7 +262,7 @@ 1.135 configFtrs = PolicyUtil.getPortScopedFeatures(policyMap,serviceName,portName); 1.136 } 1.137 features.mergeFeatures(configFtrs, true); 1.138 - terminal = createProviderInvokerTube(implType,binding,invoker); 1.139 + terminal = createProviderInvokerTube(implType, binding, invoker, container); 1.140 } else { 1.141 // Create runtime model for non Provider endpoints 1.142 seiModel = createSEIModel(wsdlPort, implType, serviceName, portName, binding); 1.143 @@ -260,7 +275,7 @@ 1.144 if (primaryDoc == null) { 1.145 primaryDoc = generateWSDL(binding, seiModel, docList, container, implType); 1.146 // create WSDL model 1.147 - wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container); 1.148 + wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); 1.149 seiModel.freeze(wsdlPort); 1.150 } 1.151 policyMap = wsdlPort.getOwner().getParent().getPolicyMap(); 1.152 @@ -277,8 +292,9 @@ 1.153 } 1.154 // Selects only required metadata for this endpoint from the passed-in metadata 1.155 if (primaryDoc != null) { 1.156 - docList = findMetadataClosure(primaryDoc, docList); 1.157 + docList = findMetadataClosure(primaryDoc, docList, resolver); 1.158 } 1.159 + 1.160 ServiceDefinitionImpl serviceDefiniton = (primaryDoc != null) ? new ServiceDefinitionImpl(docList, primaryDoc) : null; 1.161 1.162 return create(serviceName, portName, binding, container, seiModel, wsdlPort, implType, serviceDefiniton, 1.163 @@ -298,10 +314,10 @@ 1.164 return new SEIInvokerTube(seiModel,invoker,binding); 1.165 } 1.166 1.167 - protected <T> EndpointAwareTube createProviderInvokerTube(Class<T> implType, WSBinding binding, Invoker invoker) { 1.168 - return ProviderInvokerTube.create(implType, binding, invoker); 1.169 + protected <T> EndpointAwareTube createProviderInvokerTube(final Class<T> implType, final WSBinding binding, 1.170 + final Invoker invoker, final Container container) { 1.171 + return ProviderInvokerTube.create(implType, binding, invoker, container); 1.172 } 1.173 - 1.174 /** 1.175 * Goes through the original metadata documents and collects the required ones. 1.176 * This done traversing from primary WSDL and its imports until it builds a 1.177 @@ -311,7 +327,7 @@ 1.178 * @param docList complete metadata 1.179 * @return new metadata that doesn't contain extraneous documnets. 1.180 */ 1.181 - private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList) { 1.182 + private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList, EntityResolver resolver) { 1.183 // create a map for old metadata 1.184 Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>(); 1.185 for(SDDocumentImpl doc : docList) { 1.186 @@ -328,10 +344,24 @@ 1.187 SDDocumentImpl doc = oldMap.get(url); 1.188 if (doc == null) { 1.189 // old metadata doesn't have this imported doc, may be external 1.190 - continue; 1.191 + if (resolver != null) { 1.192 + try { 1.193 + InputSource source = resolver.resolveEntity(null, url); 1.194 + if (source != null) { 1.195 + MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); 1.196 + XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream()); 1.197 + xsb.createFromXMLStreamReader(reader); 1.198 + 1.199 + SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb); 1.200 + doc = SDDocumentImpl.create(sdocSource, null, null); 1.201 + } 1.202 + } catch (Exception ex) { 1.203 + ex.printStackTrace(); 1.204 + } 1.205 + } 1.206 } 1.207 // Check if new metadata already contains this doc 1.208 - if (!newMap.containsKey(url)) { 1.209 + if (doc != null && !newMap.containsKey(url)) { 1.210 newMap.put(url, doc); 1.211 remaining.addAll(doc.getImports()); 1.212 } 1.213 @@ -366,8 +396,29 @@ 1.214 * If it has both @WebService and @WebServiceProvider annotations 1.215 */ 1.216 public static boolean verifyImplementorClass(Class<?> clz) { 1.217 - WebServiceProvider wsProvider = clz.getAnnotation(WebServiceProvider.class); 1.218 - WebService ws = clz.getAnnotation(WebService.class); 1.219 + return verifyImplementorClass(clz, null); 1.220 + } 1.221 + 1.222 + /** 1.223 + * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider 1.224 + * annotation; passing MetadataReader instance allows to read annotations from 1.225 + * xml descriptor instead of class's annotations 1.226 + * 1.227 + * @return 1.228 + * true if it is a Provider or AsyncProvider endpoint 1.229 + * false otherwise 1.230 + * @throws java.lang.IllegalArgumentException 1.231 + * If it doesn't have any one of @WebService or @WebServiceProvider 1.232 + * If it has both @WebService and @WebServiceProvider annotations 1.233 + */ 1.234 + public static boolean verifyImplementorClass(Class<?> clz, MetadataReader metadataReader) { 1.235 + 1.236 + if (metadataReader == null) { 1.237 + metadataReader = new ReflectAnnotationReader(); 1.238 + } 1.239 + 1.240 + WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, clz); 1.241 + WebService ws = metadataReader.getAnnotation(WebService.class, clz); 1.242 if (wsProvider == null && ws == null) { 1.243 throw new IllegalArgumentException(clz +" has neither @WebService nor @WebServiceProvider annotation"); 1.244 } 1.245 @@ -415,10 +466,22 @@ 1.246 // config.getMappingInfo().setBindingID(binding.getBindingId()); 1.247 config.setClassLoader(implType.getClassLoader()); 1.248 config.getMappingInfo().setPortName(portName); 1.249 + 1.250 + config.setMetadataReader(getExternalMetadatReader(implType, binding)); 1.251 + 1.252 com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config); 1.253 return (AbstractSEIModelImpl) rt.getModel(); 1.254 } 1.255 1.256 + public static MetadataReader getExternalMetadatReader(Class<?> implType, WSBinding binding) { 1.257 + com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature ef = binding.getFeature( 1.258 + com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature.class); 1.259 + // TODO-Miran: would it be necessary to disable secure xml processing? 1.260 + if (ef != null) 1.261 + return ef.getMetadataReader(implType.getClassLoader(), false); 1.262 + return null; 1.263 + } 1.264 + 1.265 /** 1.266 *Set the mtom enable setting from wsdl model (mtom policy assertion) on to @link WSBinding} if DD has 1.267 * not already set it on BindingID. Also check conflicts. 1.268 @@ -443,18 +506,29 @@ 1.269 * @return non-null service name 1.270 */ 1.271 public static @NotNull QName getDefaultServiceName(Class<?> implType) { 1.272 - return getDefaultServiceName(implType, true); 1.273 + return getDefaultServiceName(implType, null); 1.274 + } 1.275 + 1.276 + public static @NotNull QName getDefaultServiceName(Class<?> implType, MetadataReader metadataReader) { 1.277 + return getDefaultServiceName(implType, true, metadataReader); 1.278 } 1.279 1.280 public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard) { 1.281 + return getDefaultServiceName(implType, isStandard, null); 1.282 + } 1.283 + 1.284 + public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard, MetadataReader metadataReader) { 1.285 + if (metadataReader == null) { 1.286 + metadataReader = new ReflectAnnotationReader(); 1.287 + } 1.288 QName serviceName; 1.289 - WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class); 1.290 + WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); 1.291 if (wsProvider!=null) { 1.292 String tns = wsProvider.targetNamespace(); 1.293 String local = wsProvider.serviceName(); 1.294 serviceName = new QName(tns, local); 1.295 } else { 1.296 - serviceName = RuntimeModeler.getServiceName(implType, isStandard); 1.297 + serviceName = RuntimeModeler.getServiceName(implType, metadataReader, isStandard); 1.298 } 1.299 assert serviceName != null; 1.300 return serviceName; 1.301 @@ -467,18 +541,29 @@ 1.302 * @return non-null port name 1.303 */ 1.304 public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType) { 1.305 - return getDefaultPortName(serviceName, implType, true); 1.306 + return getDefaultPortName(serviceName, implType, null); 1.307 + } 1.308 + 1.309 + public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, MetadataReader metadataReader) { 1.310 + return getDefaultPortName(serviceName, implType, true, metadataReader); 1.311 } 1.312 1.313 public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard) { 1.314 + return getDefaultPortName(serviceName, implType, isStandard, null); 1.315 + } 1.316 + 1.317 + public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard, MetadataReader metadataReader) { 1.318 + if (metadataReader == null) { 1.319 + metadataReader = new ReflectAnnotationReader(); 1.320 + } 1.321 QName portName; 1.322 - WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class); 1.323 + WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); 1.324 if (wsProvider!=null) { 1.325 String tns = wsProvider.targetNamespace(); 1.326 String local = wsProvider.portName(); 1.327 portName = new QName(tns, local); 1.328 } else { 1.329 - portName = RuntimeModeler.getPortName(implType, serviceName.getNamespaceURI(), isStandard); 1.330 + portName = RuntimeModeler.getPortName(implType, metadataReader, serviceName.getNamespaceURI(), isStandard); 1.331 } 1.332 assert portName != null; 1.333 return portName; 1.334 @@ -494,19 +579,39 @@ 1.335 * @return wsdl if there is wsdlLocation, else null 1.336 */ 1.337 public static @Nullable String getWsdlLocation(Class<?> implType) { 1.338 - String wsdl; 1.339 - WebService ws = implType.getAnnotation(WebService.class); 1.340 + return getWsdlLocation(implType, new ReflectAnnotationReader()); 1.341 + } 1.342 + 1.343 + /** 1.344 + * Returns the wsdl from @WebService, or @WebServiceProvider annotation using 1.345 + * wsdlLocation element. 1.346 + * 1.347 + * @param implType 1.348 + * endpoint implementation class 1.349 + * make sure that you called {@link #verifyImplementorClass} on it. 1.350 + * @return wsdl if there is wsdlLocation, else null 1.351 + */ 1.352 + public static @Nullable String getWsdlLocation(Class<?> implType, MetadataReader metadataReader) { 1.353 + 1.354 + if (metadataReader == null) { 1.355 + metadataReader = new ReflectAnnotationReader(); 1.356 + } 1.357 + 1.358 + WebService ws = metadataReader.getAnnotation(WebService.class, implType); 1.359 if (ws != null) { 1.360 - wsdl = ws.wsdlLocation(); 1.361 + return nullIfEmpty(ws.wsdlLocation()); 1.362 } else { 1.363 WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class); 1.364 assert wsProvider != null; 1.365 - wsdl = wsProvider.wsdlLocation(); 1.366 + return nullIfEmpty(wsProvider.wsdlLocation()); 1.367 } 1.368 - if (wsdl.length() < 1) { 1.369 - wsdl = null; 1.370 + } 1.371 + 1.372 + private static String nullIfEmpty(String string) { 1.373 + if (string.length() < 1) { 1.374 + string = null; 1.375 } 1.376 - return wsdl; 1.377 + return string; 1.378 } 1.379 1.380 /** 1.381 @@ -532,6 +637,7 @@ 1.382 wsdlGenInfo.setContainer(container); 1.383 wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); 1.384 wsdlGenInfo.setInlineSchemas(false); 1.385 + wsdlGenInfo.setSecureXmlProcessingDisabled(isSecureXmlProcessingDisabled(binding.getFeatures())); 1.386 seiModel.getDatabinding().generateWSDL(wsdlGenInfo); 1.387 // WSDLGenerator wsdlGen = new WSDLGenerator(seiModel, wsdlResolver, binding, container, implType, false, 1.388 // ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); 1.389 @@ -539,6 +645,11 @@ 1.390 return wsdlResolver.updateDocs(); 1.391 } 1.392 1.393 + private static boolean isSecureXmlProcessingDisabled(WSFeatureList featureList) { 1.394 + // TODO-Miran: would it be necessary to disable secure xml processing? 1.395 + return false; 1.396 + } 1.397 + 1.398 /** 1.399 * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}. 1.400 */ 1.401 @@ -619,12 +730,13 @@ 1.402 * @return non-null wsdl port object 1.403 */ 1.404 private static @NotNull WSDLPortImpl getWSDLPort(SDDocumentSource primaryWsdl, List<? extends SDDocumentSource> metadata, 1.405 - @NotNull QName serviceName, @NotNull QName portName, Container container) { 1.406 + @NotNull QName serviceName, @NotNull QName portName, Container container, 1.407 + EntityResolver resolver) { 1.408 URL wsdlUrl = primaryWsdl.getSystemId(); 1.409 try { 1.410 // TODO: delegate to another entity resolver 1.411 WSDLModelImpl wsdlDoc = RuntimeWSDLParser.parse( 1.412 - new Parser(primaryWsdl), new EntityResolverImpl(metadata), 1.413 + new Parser(primaryWsdl), new EntityResolverImpl(metadata, resolver), 1.414 false, container, ServiceFinder.find(WSDLParserExtension.class).toArray()); 1.415 if(wsdlDoc.getServices().size() == 0) { 1.416 throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_NOSERVICE_IN_WSDLMODEL(wsdlUrl)); 1.417 @@ -654,11 +766,13 @@ 1.418 */ 1.419 private static final class EntityResolverImpl implements XMLEntityResolver { 1.420 private Map<String,SDDocumentSource> metadata = new HashMap<String,SDDocumentSource>(); 1.421 + private EntityResolver resolver; 1.422 1.423 - public EntityResolverImpl(List<? extends SDDocumentSource> metadata) { 1.424 + public EntityResolverImpl(List<? extends SDDocumentSource> metadata, EntityResolver resolver) { 1.425 for (SDDocumentSource doc : metadata) { 1.426 this.metadata.put(doc.getSystemId().toExternalForm(),doc); 1.427 } 1.428 + this.resolver = resolver; 1.429 } 1.430 1.431 public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException { 1.432 @@ -667,6 +781,17 @@ 1.433 if (doc != null) 1.434 return new Parser(doc); 1.435 } 1.436 + if (resolver != null) { 1.437 + try { 1.438 + InputSource source = resolver.resolveEntity(publicId, systemId); 1.439 + if (source != null) { 1.440 + Parser p = new Parser(null, XMLStreamReaderFactory.create(source, true)); 1.441 + return p; 1.442 + } 1.443 + } catch (SAXException e) { 1.444 + throw new XMLStreamException(e); 1.445 + } 1.446 + } 1.447 return null; 1.448 } 1.449