Tue, 09 Apr 2013 14:51:13 +0100
8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com
ohair@286 | 1 | /* |
alanb@368 | 2 | * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
ohair@286 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ohair@286 | 4 | * |
ohair@286 | 5 | * This code is free software; you can redistribute it and/or modify it |
ohair@286 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ohair@286 | 7 | * published by the Free Software Foundation. Oracle designates this |
ohair@286 | 8 | * particular file as subject to the "Classpath" exception as provided |
ohair@286 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
ohair@286 | 10 | * |
ohair@286 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ohair@286 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ohair@286 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ohair@286 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
ohair@286 | 15 | * accompanied this code). |
ohair@286 | 16 | * |
ohair@286 | 17 | * You should have received a copy of the GNU General Public License version |
ohair@286 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
ohair@286 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ohair@286 | 20 | * |
ohair@286 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
ohair@286 | 22 | * or visit www.oracle.com if you need additional information or have any |
ohair@286 | 23 | * questions. |
ohair@286 | 24 | */ |
ohair@286 | 25 | |
ohair@286 | 26 | package com.sun.xml.internal.ws.server; |
ohair@286 | 27 | |
ohair@286 | 28 | import com.sun.istack.internal.NotNull; |
ohair@286 | 29 | import com.sun.istack.internal.Nullable; |
alanb@368 | 30 | import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer; |
ohair@286 | 31 | import com.sun.xml.internal.ws.api.BindingID; |
ohair@286 | 32 | import com.sun.xml.internal.ws.api.WSBinding; |
alanb@368 | 33 | import com.sun.xml.internal.ws.api.WSFeatureList; |
alanb@368 | 34 | import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; |
alanb@368 | 35 | import com.sun.xml.internal.ws.api.databinding.DatabindingFactory; |
alanb@368 | 36 | import com.sun.xml.internal.ws.api.databinding.MetadataReader; |
ohair@286 | 37 | import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo; |
ohair@286 | 38 | import com.sun.xml.internal.ws.api.model.SEIModel; |
ohair@286 | 39 | import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; |
alanb@368 | 40 | import com.sun.xml.internal.ws.api.policy.PolicyResolver; |
alanb@368 | 41 | import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory; |
alanb@368 | 42 | import com.sun.xml.internal.ws.api.server.AsyncProvider; |
alanb@368 | 43 | import com.sun.xml.internal.ws.api.server.Container; |
alanb@368 | 44 | import com.sun.xml.internal.ws.api.server.ContainerResolver; |
alanb@368 | 45 | import com.sun.xml.internal.ws.api.server.InstanceResolver; |
alanb@368 | 46 | import com.sun.xml.internal.ws.api.server.Invoker; |
alanb@368 | 47 | import com.sun.xml.internal.ws.api.server.SDDocument; |
alanb@368 | 48 | import com.sun.xml.internal.ws.api.server.SDDocumentSource; |
alanb@368 | 49 | import com.sun.xml.internal.ws.api.server.WSEndpoint; |
alanb@368 | 50 | import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; |
ohair@286 | 51 | import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension; |
ohair@286 | 52 | import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver; |
ohair@286 | 53 | import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver.Parser; |
ohair@286 | 54 | import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension; |
ohair@286 | 55 | import com.sun.xml.internal.ws.binding.BindingImpl; |
ohair@286 | 56 | import com.sun.xml.internal.ws.binding.SOAPBindingImpl; |
ohair@286 | 57 | import com.sun.xml.internal.ws.binding.WebServiceFeatureList; |
ohair@286 | 58 | import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; |
alanb@368 | 59 | import com.sun.xml.internal.ws.model.ReflectAnnotationReader; |
ohair@286 | 60 | import com.sun.xml.internal.ws.model.RuntimeModeler; |
ohair@286 | 61 | import com.sun.xml.internal.ws.model.SOAPSEIModel; |
ohair@286 | 62 | import com.sun.xml.internal.ws.model.wsdl.WSDLModelImpl; |
ohair@286 | 63 | import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl; |
ohair@286 | 64 | import com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl; |
alanb@368 | 65 | import com.sun.xml.internal.ws.policy.PolicyMap; |
alanb@368 | 66 | import com.sun.xml.internal.ws.policy.jaxws.PolicyUtil; |
ohair@286 | 67 | import com.sun.xml.internal.ws.resources.ServerMessages; |
ohair@286 | 68 | import com.sun.xml.internal.ws.server.provider.ProviderInvokerTube; |
ohair@286 | 69 | import com.sun.xml.internal.ws.server.sei.SEIInvokerTube; |
ohair@286 | 70 | import com.sun.xml.internal.ws.util.HandlerAnnotationInfo; |
ohair@286 | 71 | import com.sun.xml.internal.ws.util.HandlerAnnotationProcessor; |
ohair@286 | 72 | import com.sun.xml.internal.ws.util.ServiceConfigurationError; |
ohair@286 | 73 | import com.sun.xml.internal.ws.util.ServiceFinder; |
alanb@368 | 74 | import com.sun.xml.internal.ws.util.xml.XmlUtil; |
ohair@286 | 75 | import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser; |
ohair@286 | 76 | import org.xml.sax.EntityResolver; |
alanb@368 | 77 | import org.xml.sax.InputSource; |
ohair@286 | 78 | import org.xml.sax.SAXException; |
ohair@286 | 79 | |
ohair@286 | 80 | import javax.jws.WebService; |
ohair@286 | 81 | import javax.xml.namespace.QName; |
ohair@286 | 82 | import javax.xml.stream.XMLStreamException; |
alanb@368 | 83 | import javax.xml.stream.XMLStreamReader; |
ohair@286 | 84 | import javax.xml.ws.Provider; |
ohair@286 | 85 | import javax.xml.ws.WebServiceException; |
alanb@368 | 86 | import javax.xml.ws.WebServiceFeature; |
ohair@286 | 87 | import javax.xml.ws.WebServiceProvider; |
ohair@286 | 88 | import javax.xml.ws.soap.SOAPBinding; |
ohair@286 | 89 | import java.io.IOException; |
ohair@286 | 90 | import java.net.URL; |
ohair@286 | 91 | import java.util.ArrayList; |
ohair@286 | 92 | import java.util.Collection; |
ohair@286 | 93 | import java.util.HashMap; |
ohair@286 | 94 | import java.util.List; |
ohair@286 | 95 | import java.util.Map; |
ohair@286 | 96 | import java.util.logging.Logger; |
ohair@286 | 97 | |
ohair@286 | 98 | /** |
ohair@286 | 99 | * Entry point to the JAX-WS RI server-side runtime. |
ohair@286 | 100 | * |
ohair@286 | 101 | * @author Kohsuke Kawaguchi |
ohair@286 | 102 | * @author Jitendra Kotamraju |
ohair@286 | 103 | */ |
ohair@286 | 104 | public class EndpointFactory { |
ohair@286 | 105 | private static final EndpointFactory instance = new EndpointFactory(); |
ohair@286 | 106 | |
ohair@286 | 107 | public static EndpointFactory getInstance() { |
ohair@286 | 108 | return instance; |
ohair@286 | 109 | } |
ohair@286 | 110 | |
ohair@286 | 111 | /** |
ohair@286 | 112 | * Implements {@link WSEndpoint#create}. |
ohair@286 | 113 | * |
ohair@286 | 114 | * No need to take WebServiceContext implementation. When InvokerPipe is |
ohair@286 | 115 | * instantiated, it calls InstanceResolver to set up a WebServiceContext. |
ohair@286 | 116 | * We shall only take delegate to getUserPrincipal and isUserInRole from adapter. |
ohair@286 | 117 | * |
ohair@286 | 118 | * <p> |
ohair@286 | 119 | * Nobody else should be calling this method. |
ohair@286 | 120 | */ |
ohair@286 | 121 | public static <T> WSEndpoint<T> createEndpoint( |
ohair@286 | 122 | Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, |
ohair@286 | 123 | @Nullable QName serviceName, @Nullable QName portName, |
ohair@286 | 124 | @Nullable Container container, @Nullable WSBinding binding, |
ohair@286 | 125 | @Nullable SDDocumentSource primaryWsdl, |
ohair@286 | 126 | @Nullable Collection<? extends SDDocumentSource> metadata, |
ohair@286 | 127 | EntityResolver resolver, boolean isTransportSynchronous) { |
ohair@286 | 128 | return createEndpoint(implType, processHandlerAnnotation, invoker, serviceName, |
ohair@286 | 129 | portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true); |
ohair@286 | 130 | } |
ohair@286 | 131 | |
ohair@286 | 132 | public static <T> WSEndpoint<T> createEndpoint( |
ohair@286 | 133 | Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, |
ohair@286 | 134 | @Nullable QName serviceName, @Nullable QName portName, |
ohair@286 | 135 | @Nullable Container container, @Nullable WSBinding binding, |
ohair@286 | 136 | @Nullable SDDocumentSource primaryWsdl, |
ohair@286 | 137 | @Nullable Collection<? extends SDDocumentSource> metadata, |
ohair@286 | 138 | EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) { |
ohair@286 | 139 | EndpointFactory factory = container != null ? container.getSPI(EndpointFactory.class) : null; |
ohair@286 | 140 | if (factory == null) |
ohair@286 | 141 | factory = EndpointFactory.getInstance(); |
ohair@286 | 142 | |
ohair@286 | 143 | return factory.create( |
ohair@286 | 144 | implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard); |
ohair@286 | 145 | } |
ohair@286 | 146 | |
ohair@286 | 147 | /** |
ohair@286 | 148 | * Implements {@link WSEndpoint#create}. |
ohair@286 | 149 | * |
ohair@286 | 150 | * No need to take WebServiceContext implementation. When InvokerPipe is |
ohair@286 | 151 | * instantiated, it calls InstanceResolver to set up a WebServiceContext. |
ohair@286 | 152 | * We shall only take delegate to getUserPrincipal and isUserInRole from adapter. |
ohair@286 | 153 | * |
ohair@286 | 154 | * <p> |
ohair@286 | 155 | * Nobody else should be calling this method. |
ohair@286 | 156 | */ |
ohair@286 | 157 | public <T> WSEndpoint<T> create( |
ohair@286 | 158 | Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, |
ohair@286 | 159 | @Nullable QName serviceName, @Nullable QName portName, |
ohair@286 | 160 | @Nullable Container container, @Nullable WSBinding binding, |
ohair@286 | 161 | @Nullable SDDocumentSource primaryWsdl, |
ohair@286 | 162 | @Nullable Collection<? extends SDDocumentSource> metadata, |
ohair@286 | 163 | EntityResolver resolver, boolean isTransportSynchronous) { |
ohair@286 | 164 | return create(implType, processHandlerAnnotation, invoker, serviceName, |
ohair@286 | 165 | portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, |
ohair@286 | 166 | true); |
ohair@286 | 167 | |
ohair@286 | 168 | } |
ohair@286 | 169 | |
ohair@286 | 170 | public <T> WSEndpoint<T> create( |
ohair@286 | 171 | Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, |
ohair@286 | 172 | @Nullable QName serviceName, @Nullable QName portName, |
ohair@286 | 173 | @Nullable Container container, @Nullable WSBinding binding, |
ohair@286 | 174 | @Nullable SDDocumentSource primaryWsdl, |
ohair@286 | 175 | @Nullable Collection<? extends SDDocumentSource> metadata, |
ohair@286 | 176 | EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) { |
ohair@286 | 177 | |
ohair@286 | 178 | if(implType ==null) |
ohair@286 | 179 | throw new IllegalArgumentException(); |
ohair@286 | 180 | |
alanb@368 | 181 | MetadataReader metadataReader = getExternalMetadatReader(implType, binding); |
alanb@368 | 182 | |
ohair@286 | 183 | if (isStandard) { |
alanb@368 | 184 | verifyImplementorClass(implType, metadataReader); |
ohair@286 | 185 | } |
ohair@286 | 186 | |
ohair@286 | 187 | if (invoker == null) { |
ohair@286 | 188 | invoker = InstanceResolver.createDefault(implType).createInvoker(); |
ohair@286 | 189 | } |
ohair@286 | 190 | |
ohair@286 | 191 | List<SDDocumentSource> md = new ArrayList<SDDocumentSource>(); |
ohair@286 | 192 | if(metadata!=null) |
ohair@286 | 193 | md.addAll(metadata); |
ohair@286 | 194 | |
ohair@286 | 195 | if(primaryWsdl!=null && !md.contains(primaryWsdl)) |
ohair@286 | 196 | md.add(primaryWsdl); |
ohair@286 | 197 | |
ohair@286 | 198 | if(container==null) |
ohair@286 | 199 | container = ContainerResolver.getInstance().getContainer(); |
ohair@286 | 200 | |
ohair@286 | 201 | if(serviceName==null) |
alanb@368 | 202 | serviceName = getDefaultServiceName(implType, metadataReader); |
ohair@286 | 203 | |
ohair@286 | 204 | if(portName==null) |
alanb@368 | 205 | portName = getDefaultPortName(serviceName,implType, metadataReader); |
ohair@286 | 206 | |
ohair@286 | 207 | {// error check |
ohair@286 | 208 | String serviceNS = serviceName.getNamespaceURI(); |
ohair@286 | 209 | String portNS = portName.getNamespaceURI(); |
ohair@286 | 210 | if (!serviceNS.equals(portNS)) { |
ohair@286 | 211 | throw new ServerRtException("wrong.tns.for.port",portNS, serviceNS); |
ohair@286 | 212 | } |
ohair@286 | 213 | } |
ohair@286 | 214 | |
ohair@286 | 215 | // setting a default binding |
ohair@286 | 216 | if (binding == null) |
ohair@286 | 217 | binding = BindingImpl.create(BindingID.parse(implType)); |
ohair@286 | 218 | |
ohair@286 | 219 | if ( isStandard && primaryWsdl != null) { |
ohair@286 | 220 | verifyPrimaryWSDL(primaryWsdl, serviceName); |
ohair@286 | 221 | } |
ohair@286 | 222 | |
ohair@286 | 223 | QName portTypeName = null; |
ohair@286 | 224 | if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) { |
alanb@368 | 225 | portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader); |
ohair@286 | 226 | } |
ohair@286 | 227 | |
ohair@286 | 228 | // Categorises the documents as WSDL, Schema etc |
ohair@286 | 229 | List<SDDocumentImpl> docList = categoriseMetadata(md, serviceName, portTypeName); |
ohair@286 | 230 | // Finds the primary WSDL and makes sure that metadata doesn't have |
ohair@286 | 231 | // two concrete or abstract WSDLs |
alanb@368 | 232 | SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList); |
ohair@286 | 233 | |
ohair@286 | 234 | EndpointAwareTube terminal; |
ohair@286 | 235 | WSDLPortImpl wsdlPort = null; |
ohair@286 | 236 | AbstractSEIModelImpl seiModel = null; |
ohair@286 | 237 | // create WSDL model |
ohair@286 | 238 | if (primaryDoc != null) { |
alanb@368 | 239 | wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); |
ohair@286 | 240 | } |
ohair@286 | 241 | |
ohair@286 | 242 | WebServiceFeatureList features=((BindingImpl)binding).getFeatures(); |
ohair@286 | 243 | if (isStandard) { |
ohair@286 | 244 | features.parseAnnotations(implType); |
ohair@286 | 245 | } |
ohair@286 | 246 | PolicyMap policyMap = null; |
ohair@286 | 247 | // create terminal pipe that invokes the application |
ohair@286 | 248 | if (isUseProviderTube(implType, isStandard)) { |
ohair@286 | 249 | //TODO incase of Provider, provide a way to User for complete control of the message processing by giving |
ohair@286 | 250 | // ability to turn off the WSDL/Policy based features and its associated tubes. |
ohair@286 | 251 | |
ohair@286 | 252 | //Even in case of Provider, merge all features configured via WSDL/Policy or deployment configuration |
ohair@286 | 253 | Iterable<WebServiceFeature> configFtrs; |
ohair@286 | 254 | if(wsdlPort != null) { |
ohair@286 | 255 | policyMap = wsdlPort.getOwner().getParent().getPolicyMap(); |
ohair@286 | 256 | //Merge features from WSDL and other policy configuration |
ohair@286 | 257 | configFtrs = wsdlPort.getFeatures(); |
ohair@286 | 258 | } else { |
ohair@286 | 259 | //No WSDL, so try to merge features from Policy configuration |
ohair@286 | 260 | policyMap = PolicyResolverFactory.create().resolve( |
ohair@286 | 261 | new PolicyResolver.ServerContext(null, container, implType, false)); |
ohair@286 | 262 | configFtrs = PolicyUtil.getPortScopedFeatures(policyMap,serviceName,portName); |
ohair@286 | 263 | } |
ohair@286 | 264 | features.mergeFeatures(configFtrs, true); |
alanb@368 | 265 | terminal = createProviderInvokerTube(implType, binding, invoker, container); |
ohair@286 | 266 | } else { |
ohair@286 | 267 | // Create runtime model for non Provider endpoints |
ohair@286 | 268 | seiModel = createSEIModel(wsdlPort, implType, serviceName, portName, binding); |
ohair@286 | 269 | if(binding instanceof SOAPBindingImpl){ |
ohair@286 | 270 | //set portKnownHeaders on Binding, so that they can be used for MU processing |
ohair@286 | 271 | ((SOAPBindingImpl)binding).setPortKnownHeaders( |
ohair@286 | 272 | ((SOAPSEIModel)seiModel).getKnownHeaders()); |
ohair@286 | 273 | } |
ohair@286 | 274 | // Generate WSDL for SEI endpoints(not for Provider endpoints) |
ohair@286 | 275 | if (primaryDoc == null) { |
ohair@286 | 276 | primaryDoc = generateWSDL(binding, seiModel, docList, container, implType); |
ohair@286 | 277 | // create WSDL model |
alanb@368 | 278 | wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); |
ohair@286 | 279 | seiModel.freeze(wsdlPort); |
ohair@286 | 280 | } |
ohair@286 | 281 | policyMap = wsdlPort.getOwner().getParent().getPolicyMap(); |
ohair@286 | 282 | // New Features might have been added in WSDL through Policy. |
ohair@286 | 283 | //Merge features from WSDL and other policy configuration |
ohair@286 | 284 | // This sets only the wsdl features that are not already set(enabled/disabled) |
ohair@286 | 285 | features.mergeFeatures(wsdlPort.getFeatures(), true); |
ohair@286 | 286 | terminal = createSEIInvokerTube(seiModel,invoker,binding); |
ohair@286 | 287 | } |
ohair@286 | 288 | |
ohair@286 | 289 | // Process @HandlerChain, if handler-chain is not set via Deployment Descriptor |
ohair@286 | 290 | if (processHandlerAnnotation) { |
ohair@286 | 291 | processHandlerAnnotation(binding, implType, serviceName, portName); |
ohair@286 | 292 | } |
ohair@286 | 293 | // Selects only required metadata for this endpoint from the passed-in metadata |
ohair@286 | 294 | if (primaryDoc != null) { |
alanb@368 | 295 | docList = findMetadataClosure(primaryDoc, docList, resolver); |
ohair@286 | 296 | } |
alanb@368 | 297 | |
ohair@286 | 298 | ServiceDefinitionImpl serviceDefiniton = (primaryDoc != null) ? new ServiceDefinitionImpl(docList, primaryDoc) : null; |
ohair@286 | 299 | |
ohair@286 | 300 | return create(serviceName, portName, binding, container, seiModel, wsdlPort, implType, serviceDefiniton, |
ohair@286 | 301 | terminal, isTransportSynchronous, policyMap); |
ohair@286 | 302 | } |
ohair@286 | 303 | |
ohair@286 | 304 | protected <T> WSEndpoint<T> create(QName serviceName, QName portName, WSBinding binding, Container container, SEIModel seiModel, WSDLPort wsdlPort, Class<T> implType, ServiceDefinitionImpl serviceDefinition, EndpointAwareTube terminal, boolean isTransportSynchronous, PolicyMap policyMap) { |
ohair@286 | 305 | return new WSEndpointImpl<T>(serviceName, portName, binding, container, seiModel, |
ohair@286 | 306 | wsdlPort, implType, serviceDefinition, terminal, isTransportSynchronous, policyMap); |
ohair@286 | 307 | } |
ohair@286 | 308 | |
ohair@286 | 309 | protected boolean isUseProviderTube(Class<?> implType, boolean isStandard) { |
ohair@286 | 310 | return !isStandard || implType.getAnnotation(WebServiceProvider.class)!=null; |
ohair@286 | 311 | } |
ohair@286 | 312 | |
ohair@286 | 313 | protected EndpointAwareTube createSEIInvokerTube(AbstractSEIModelImpl seiModel, Invoker invoker, WSBinding binding) { |
ohair@286 | 314 | return new SEIInvokerTube(seiModel,invoker,binding); |
ohair@286 | 315 | } |
ohair@286 | 316 | |
alanb@368 | 317 | protected <T> EndpointAwareTube createProviderInvokerTube(final Class<T> implType, final WSBinding binding, |
alanb@368 | 318 | final Invoker invoker, final Container container) { |
alanb@368 | 319 | return ProviderInvokerTube.create(implType, binding, invoker, container); |
ohair@286 | 320 | } |
ohair@286 | 321 | /** |
ohair@286 | 322 | * Goes through the original metadata documents and collects the required ones. |
ohair@286 | 323 | * This done traversing from primary WSDL and its imports until it builds a |
ohair@286 | 324 | * complete set of documents(transitive closure) for the endpoint. |
ohair@286 | 325 | * |
ohair@286 | 326 | * @param primaryDoc primary WSDL doc |
ohair@286 | 327 | * @param docList complete metadata |
ohair@286 | 328 | * @return new metadata that doesn't contain extraneous documnets. |
ohair@286 | 329 | */ |
alanb@368 | 330 | private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList, EntityResolver resolver) { |
ohair@286 | 331 | // create a map for old metadata |
ohair@286 | 332 | Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>(); |
ohair@286 | 333 | for(SDDocumentImpl doc : docList) { |
ohair@286 | 334 | oldMap.put(doc.getSystemId().toString(), doc); |
ohair@286 | 335 | } |
ohair@286 | 336 | // create a map for new metadata |
ohair@286 | 337 | Map<String, SDDocumentImpl> newMap = new HashMap<String, SDDocumentImpl>(); |
ohair@286 | 338 | newMap.put(primaryDoc.getSystemId().toString(), primaryDoc); |
ohair@286 | 339 | |
ohair@286 | 340 | List<String> remaining = new ArrayList<String>(); |
ohair@286 | 341 | remaining.addAll(primaryDoc.getImports()); |
ohair@286 | 342 | while(!remaining.isEmpty()) { |
ohair@286 | 343 | String url = remaining.remove(0); |
ohair@286 | 344 | SDDocumentImpl doc = oldMap.get(url); |
ohair@286 | 345 | if (doc == null) { |
ohair@286 | 346 | // old metadata doesn't have this imported doc, may be external |
alanb@368 | 347 | if (resolver != null) { |
alanb@368 | 348 | try { |
alanb@368 | 349 | InputSource source = resolver.resolveEntity(null, url); |
alanb@368 | 350 | if (source != null) { |
alanb@368 | 351 | MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); |
alanb@368 | 352 | XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream()); |
alanb@368 | 353 | xsb.createFromXMLStreamReader(reader); |
alanb@368 | 354 | |
alanb@368 | 355 | SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb); |
alanb@368 | 356 | doc = SDDocumentImpl.create(sdocSource, null, null); |
alanb@368 | 357 | } |
alanb@368 | 358 | } catch (Exception ex) { |
alanb@368 | 359 | ex.printStackTrace(); |
alanb@368 | 360 | } |
alanb@368 | 361 | } |
ohair@286 | 362 | } |
ohair@286 | 363 | // Check if new metadata already contains this doc |
alanb@368 | 364 | if (doc != null && !newMap.containsKey(url)) { |
ohair@286 | 365 | newMap.put(url, doc); |
ohair@286 | 366 | remaining.addAll(doc.getImports()); |
ohair@286 | 367 | } |
ohair@286 | 368 | } |
ohair@286 | 369 | List<SDDocumentImpl> newMetadata = new ArrayList<SDDocumentImpl>(); |
ohair@286 | 370 | newMetadata.addAll(newMap.values()); |
ohair@286 | 371 | return newMetadata; |
ohair@286 | 372 | } |
ohair@286 | 373 | |
ohair@286 | 374 | private static <T> void processHandlerAnnotation(WSBinding binding, Class<T> implType, QName serviceName, QName portName) { |
ohair@286 | 375 | HandlerAnnotationInfo chainInfo = |
ohair@286 | 376 | HandlerAnnotationProcessor.buildHandlerInfo( |
ohair@286 | 377 | implType, serviceName, portName, binding); |
ohair@286 | 378 | if (chainInfo != null) { |
ohair@286 | 379 | binding.setHandlerChain(chainInfo.getHandlers()); |
ohair@286 | 380 | if (binding instanceof SOAPBinding) { |
ohair@286 | 381 | ((SOAPBinding) binding).setRoles(chainInfo.getRoles()); |
ohair@286 | 382 | } |
ohair@286 | 383 | } |
ohair@286 | 384 | |
ohair@286 | 385 | } |
ohair@286 | 386 | |
ohair@286 | 387 | /** |
ohair@286 | 388 | * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider |
ohair@286 | 389 | * annotation |
ohair@286 | 390 | * |
ohair@286 | 391 | * @return |
ohair@286 | 392 | * true if it is a Provider or AsyncProvider endpoint |
ohair@286 | 393 | * false otherwise |
ohair@286 | 394 | * @throws java.lang.IllegalArgumentException |
ohair@286 | 395 | * If it doesn't have any one of @WebService or @WebServiceProvider |
ohair@286 | 396 | * If it has both @WebService and @WebServiceProvider annotations |
ohair@286 | 397 | */ |
ohair@286 | 398 | public static boolean verifyImplementorClass(Class<?> clz) { |
alanb@368 | 399 | return verifyImplementorClass(clz, null); |
alanb@368 | 400 | } |
alanb@368 | 401 | |
alanb@368 | 402 | /** |
alanb@368 | 403 | * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider |
alanb@368 | 404 | * annotation; passing MetadataReader instance allows to read annotations from |
alanb@368 | 405 | * xml descriptor instead of class's annotations |
alanb@368 | 406 | * |
alanb@368 | 407 | * @return |
alanb@368 | 408 | * true if it is a Provider or AsyncProvider endpoint |
alanb@368 | 409 | * false otherwise |
alanb@368 | 410 | * @throws java.lang.IllegalArgumentException |
alanb@368 | 411 | * If it doesn't have any one of @WebService or @WebServiceProvider |
alanb@368 | 412 | * If it has both @WebService and @WebServiceProvider annotations |
alanb@368 | 413 | */ |
alanb@368 | 414 | public static boolean verifyImplementorClass(Class<?> clz, MetadataReader metadataReader) { |
alanb@368 | 415 | |
alanb@368 | 416 | if (metadataReader == null) { |
alanb@368 | 417 | metadataReader = new ReflectAnnotationReader(); |
alanb@368 | 418 | } |
alanb@368 | 419 | |
alanb@368 | 420 | WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, clz); |
alanb@368 | 421 | WebService ws = metadataReader.getAnnotation(WebService.class, clz); |
ohair@286 | 422 | if (wsProvider == null && ws == null) { |
ohair@286 | 423 | throw new IllegalArgumentException(clz +" has neither @WebService nor @WebServiceProvider annotation"); |
ohair@286 | 424 | } |
ohair@286 | 425 | if (wsProvider != null && ws != null) { |
ohair@286 | 426 | throw new IllegalArgumentException(clz +" has both @WebService and @WebServiceProvider annotations"); |
ohair@286 | 427 | } |
ohair@286 | 428 | if (wsProvider != null) { |
ohair@286 | 429 | if (Provider.class.isAssignableFrom(clz) || AsyncProvider.class.isAssignableFrom(clz)) { |
ohair@286 | 430 | return true; |
ohair@286 | 431 | } |
ohair@286 | 432 | throw new IllegalArgumentException(clz +" doesn't implement Provider or AsyncProvider interface"); |
ohair@286 | 433 | } |
ohair@286 | 434 | return false; |
ohair@286 | 435 | } |
ohair@286 | 436 | |
ohair@286 | 437 | |
ohair@286 | 438 | private static AbstractSEIModelImpl createSEIModel(WSDLPort wsdlPort, |
ohair@286 | 439 | Class<?> implType, @NotNull QName serviceName, @NotNull QName portName, WSBinding binding) { |
ohair@286 | 440 | // RuntimeModeler rap; |
ohair@286 | 441 | // // Create runtime model for non Provider endpoints |
ohair@286 | 442 | // |
ohair@286 | 443 | // // wsdlPort will be null, means we will generate WSDL. Hence no need to apply |
ohair@286 | 444 | // // bindings or need to look in the WSDL |
ohair@286 | 445 | // if(wsdlPort == null){ |
ohair@286 | 446 | // rap = new RuntimeModeler(implType,serviceName, binding.getBindingId(), binding.getFeatures().toArray()); |
ohair@286 | 447 | // } else { |
ohair@286 | 448 | // /* |
ohair@286 | 449 | // This not needed anymore as wsdlFeatures are merged later anyway |
ohair@286 | 450 | // and so is the MTOMFeature. |
ohair@286 | 451 | // applyEffectiveMtomSetting(wsdlPort.getBinding(), binding); |
ohair@286 | 452 | // */ |
ohair@286 | 453 | // //now we got the Binding so lets build the model |
ohair@286 | 454 | // rap = new RuntimeModeler(implType, serviceName, (WSDLPortImpl)wsdlPort, binding.getFeatures().toArray()); |
ohair@286 | 455 | // } |
ohair@286 | 456 | // rap.setClassLoader(implType.getClassLoader()); |
ohair@286 | 457 | // rap.setPortName(portName); |
ohair@286 | 458 | // return rap.buildRuntimeModel(); |
ohair@286 | 459 | DatabindingFactory fac = DatabindingFactory.newInstance(); |
ohair@286 | 460 | DatabindingConfig config = new DatabindingConfig(); |
ohair@286 | 461 | config.setEndpointClass(implType); |
ohair@286 | 462 | config.getMappingInfo().setServiceName(serviceName); |
ohair@286 | 463 | config.setWsdlPort(wsdlPort); |
ohair@286 | 464 | config.setWSBinding(binding); |
ohair@286 | 465 | // config.setFeatures(binding.getFeatures().toArray()); |
ohair@286 | 466 | // config.getMappingInfo().setBindingID(binding.getBindingId()); |
ohair@286 | 467 | config.setClassLoader(implType.getClassLoader()); |
ohair@286 | 468 | config.getMappingInfo().setPortName(portName); |
alanb@368 | 469 | |
alanb@368 | 470 | config.setMetadataReader(getExternalMetadatReader(implType, binding)); |
alanb@368 | 471 | |
ohair@286 | 472 | com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config); |
ohair@286 | 473 | return (AbstractSEIModelImpl) rt.getModel(); |
ohair@286 | 474 | } |
ohair@286 | 475 | |
alanb@368 | 476 | public static MetadataReader getExternalMetadatReader(Class<?> implType, WSBinding binding) { |
alanb@368 | 477 | com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature ef = binding.getFeature( |
alanb@368 | 478 | com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature.class); |
alanb@368 | 479 | // TODO-Miran: would it be necessary to disable secure xml processing? |
alanb@368 | 480 | if (ef != null) |
alanb@368 | 481 | return ef.getMetadataReader(implType.getClassLoader(), false); |
alanb@368 | 482 | return null; |
alanb@368 | 483 | } |
alanb@368 | 484 | |
ohair@286 | 485 | /** |
ohair@286 | 486 | *Set the mtom enable setting from wsdl model (mtom policy assertion) on to @link WSBinding} if DD has |
ohair@286 | 487 | * not already set it on BindingID. Also check conflicts. |
ohair@286 | 488 | */ |
ohair@286 | 489 | /* |
ohair@286 | 490 | private static void applyEffectiveMtomSetting(WSDLBoundPortType wsdlBinding, WSBinding binding){ |
ohair@286 | 491 | if(wsdlBinding.isMTOMEnabled()){ |
ohair@286 | 492 | BindingID bindingId = binding.getBindingId(); |
ohair@286 | 493 | if(bindingId.isMTOMEnabled() == null){ |
ohair@286 | 494 | binding.setMTOMEnabled(true); |
ohair@286 | 495 | }else if (bindingId.isMTOMEnabled() != null && bindingId.isMTOMEnabled() == Boolean.FALSE){ |
ohair@286 | 496 | //TODO: i18N |
ohair@286 | 497 | throw new ServerRtException("Deployment failed! Mtom policy assertion in WSDL is enabled whereas the deplyment descriptor setting wants to disable it!"); |
ohair@286 | 498 | } |
ohair@286 | 499 | } |
ohair@286 | 500 | } |
ohair@286 | 501 | */ |
ohair@286 | 502 | /** |
ohair@286 | 503 | * If service name is not already set via DD or programmatically, it uses |
ohair@286 | 504 | * annotations {@link WebServiceProvider}, {@link WebService} on implementorClass to get PortName. |
ohair@286 | 505 | * |
ohair@286 | 506 | * @return non-null service name |
ohair@286 | 507 | */ |
ohair@286 | 508 | public static @NotNull QName getDefaultServiceName(Class<?> implType) { |
alanb@368 | 509 | return getDefaultServiceName(implType, null); |
alanb@368 | 510 | } |
alanb@368 | 511 | |
alanb@368 | 512 | public static @NotNull QName getDefaultServiceName(Class<?> implType, MetadataReader metadataReader) { |
alanb@368 | 513 | return getDefaultServiceName(implType, true, metadataReader); |
ohair@286 | 514 | } |
ohair@286 | 515 | |
ohair@286 | 516 | public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard) { |
alanb@368 | 517 | return getDefaultServiceName(implType, isStandard, null); |
alanb@368 | 518 | } |
alanb@368 | 519 | |
alanb@368 | 520 | public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard, MetadataReader metadataReader) { |
alanb@368 | 521 | if (metadataReader == null) { |
alanb@368 | 522 | metadataReader = new ReflectAnnotationReader(); |
alanb@368 | 523 | } |
ohair@286 | 524 | QName serviceName; |
alanb@368 | 525 | WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); |
ohair@286 | 526 | if (wsProvider!=null) { |
ohair@286 | 527 | String tns = wsProvider.targetNamespace(); |
ohair@286 | 528 | String local = wsProvider.serviceName(); |
ohair@286 | 529 | serviceName = new QName(tns, local); |
ohair@286 | 530 | } else { |
alanb@368 | 531 | serviceName = RuntimeModeler.getServiceName(implType, metadataReader, isStandard); |
ohair@286 | 532 | } |
ohair@286 | 533 | assert serviceName != null; |
ohair@286 | 534 | return serviceName; |
ohair@286 | 535 | } |
ohair@286 | 536 | |
ohair@286 | 537 | /** |
ohair@286 | 538 | * If portName is not already set via DD or programmatically, it uses |
ohair@286 | 539 | * annotations on implementorClass to get PortName. |
ohair@286 | 540 | * |
ohair@286 | 541 | * @return non-null port name |
ohair@286 | 542 | */ |
ohair@286 | 543 | public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType) { |
alanb@368 | 544 | return getDefaultPortName(serviceName, implType, null); |
alanb@368 | 545 | } |
alanb@368 | 546 | |
alanb@368 | 547 | public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, MetadataReader metadataReader) { |
alanb@368 | 548 | return getDefaultPortName(serviceName, implType, true, metadataReader); |
ohair@286 | 549 | } |
ohair@286 | 550 | |
ohair@286 | 551 | public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard) { |
alanb@368 | 552 | return getDefaultPortName(serviceName, implType, isStandard, null); |
alanb@368 | 553 | } |
alanb@368 | 554 | |
alanb@368 | 555 | public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard, MetadataReader metadataReader) { |
alanb@368 | 556 | if (metadataReader == null) { |
alanb@368 | 557 | metadataReader = new ReflectAnnotationReader(); |
alanb@368 | 558 | } |
ohair@286 | 559 | QName portName; |
alanb@368 | 560 | WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); |
ohair@286 | 561 | if (wsProvider!=null) { |
ohair@286 | 562 | String tns = wsProvider.targetNamespace(); |
ohair@286 | 563 | String local = wsProvider.portName(); |
ohair@286 | 564 | portName = new QName(tns, local); |
ohair@286 | 565 | } else { |
alanb@368 | 566 | portName = RuntimeModeler.getPortName(implType, metadataReader, serviceName.getNamespaceURI(), isStandard); |
ohair@286 | 567 | } |
ohair@286 | 568 | assert portName != null; |
ohair@286 | 569 | return portName; |
ohair@286 | 570 | } |
ohair@286 | 571 | |
ohair@286 | 572 | /** |
ohair@286 | 573 | * Returns the wsdl from @WebService, or @WebServiceProvider annotation using |
ohair@286 | 574 | * wsdlLocation element. |
ohair@286 | 575 | * |
ohair@286 | 576 | * @param implType |
ohair@286 | 577 | * endpoint implementation class |
ohair@286 | 578 | * make sure that you called {@link #verifyImplementorClass} on it. |
ohair@286 | 579 | * @return wsdl if there is wsdlLocation, else null |
ohair@286 | 580 | */ |
ohair@286 | 581 | public static @Nullable String getWsdlLocation(Class<?> implType) { |
alanb@368 | 582 | return getWsdlLocation(implType, new ReflectAnnotationReader()); |
alanb@368 | 583 | } |
alanb@368 | 584 | |
alanb@368 | 585 | /** |
alanb@368 | 586 | * Returns the wsdl from @WebService, or @WebServiceProvider annotation using |
alanb@368 | 587 | * wsdlLocation element. |
alanb@368 | 588 | * |
alanb@368 | 589 | * @param implType |
alanb@368 | 590 | * endpoint implementation class |
alanb@368 | 591 | * make sure that you called {@link #verifyImplementorClass} on it. |
alanb@368 | 592 | * @return wsdl if there is wsdlLocation, else null |
alanb@368 | 593 | */ |
alanb@368 | 594 | public static @Nullable String getWsdlLocation(Class<?> implType, MetadataReader metadataReader) { |
alanb@368 | 595 | |
alanb@368 | 596 | if (metadataReader == null) { |
alanb@368 | 597 | metadataReader = new ReflectAnnotationReader(); |
alanb@368 | 598 | } |
alanb@368 | 599 | |
alanb@368 | 600 | WebService ws = metadataReader.getAnnotation(WebService.class, implType); |
ohair@286 | 601 | if (ws != null) { |
alanb@368 | 602 | return nullIfEmpty(ws.wsdlLocation()); |
ohair@286 | 603 | } else { |
ohair@286 | 604 | WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class); |
ohair@286 | 605 | assert wsProvider != null; |
alanb@368 | 606 | return nullIfEmpty(wsProvider.wsdlLocation()); |
ohair@286 | 607 | } |
alanb@368 | 608 | } |
alanb@368 | 609 | |
alanb@368 | 610 | private static String nullIfEmpty(String string) { |
alanb@368 | 611 | if (string.length() < 1) { |
alanb@368 | 612 | string = null; |
ohair@286 | 613 | } |
alanb@368 | 614 | return string; |
ohair@286 | 615 | } |
ohair@286 | 616 | |
ohair@286 | 617 | /** |
ohair@286 | 618 | * Generates the WSDL and XML Schema for the endpoint if necessary |
ohair@286 | 619 | * It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings |
ohair@286 | 620 | */ |
ohair@286 | 621 | private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, List<SDDocumentImpl> docs, |
ohair@286 | 622 | Container container, Class implType) { |
ohair@286 | 623 | BindingID bindingId = binding.getBindingId(); |
ohair@286 | 624 | if (!bindingId.canGenerateWSDL()) { |
ohair@286 | 625 | throw new ServerRtException("can.not.generate.wsdl", bindingId); |
ohair@286 | 626 | } |
ohair@286 | 627 | |
ohair@286 | 628 | if (bindingId.toString().equals(SOAPBindingImpl.X_SOAP12HTTP_BINDING)) { |
ohair@286 | 629 | String msg = ServerMessages.GENERATE_NON_STANDARD_WSDL(); |
ohair@286 | 630 | logger.warning(msg); |
ohair@286 | 631 | } |
ohair@286 | 632 | |
ohair@286 | 633 | // Generate WSDL and schema documents using runtime model |
ohair@286 | 634 | WSDLGenResolver wsdlResolver = new WSDLGenResolver(docs,seiModel.getServiceQName(),seiModel.getPortTypeName()); |
ohair@286 | 635 | WSDLGenInfo wsdlGenInfo = new WSDLGenInfo(); |
ohair@286 | 636 | wsdlGenInfo.setWsdlResolver(wsdlResolver); |
ohair@286 | 637 | wsdlGenInfo.setContainer(container); |
ohair@286 | 638 | wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); |
ohair@286 | 639 | wsdlGenInfo.setInlineSchemas(false); |
alanb@368 | 640 | wsdlGenInfo.setSecureXmlProcessingDisabled(isSecureXmlProcessingDisabled(binding.getFeatures())); |
ohair@286 | 641 | seiModel.getDatabinding().generateWSDL(wsdlGenInfo); |
ohair@286 | 642 | // WSDLGenerator wsdlGen = new WSDLGenerator(seiModel, wsdlResolver, binding, container, implType, false, |
ohair@286 | 643 | // ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); |
ohair@286 | 644 | // wsdlGen.doGeneration(); |
ohair@286 | 645 | return wsdlResolver.updateDocs(); |
ohair@286 | 646 | } |
ohair@286 | 647 | |
alanb@368 | 648 | private static boolean isSecureXmlProcessingDisabled(WSFeatureList featureList) { |
alanb@368 | 649 | // TODO-Miran: would it be necessary to disable secure xml processing? |
alanb@368 | 650 | return false; |
alanb@368 | 651 | } |
alanb@368 | 652 | |
ohair@286 | 653 | /** |
ohair@286 | 654 | * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}. |
ohair@286 | 655 | */ |
ohair@286 | 656 | private static List<SDDocumentImpl> categoriseMetadata( |
ohair@286 | 657 | List<SDDocumentSource> src, QName serviceName, QName portTypeName) { |
ohair@286 | 658 | |
ohair@286 | 659 | List<SDDocumentImpl> r = new ArrayList<SDDocumentImpl>(src.size()); |
ohair@286 | 660 | for (SDDocumentSource doc : src) { |
ohair@286 | 661 | r.add(SDDocumentImpl.create(doc,serviceName,portTypeName)); |
ohair@286 | 662 | } |
ohair@286 | 663 | return r; |
ohair@286 | 664 | } |
ohair@286 | 665 | |
ohair@286 | 666 | /** |
ohair@286 | 667 | * Verifies whether the given primaryWsdl contains the given serviceName. |
ohair@286 | 668 | * If the WSDL doesn't have the service, it throws an WebServiceException. |
ohair@286 | 669 | */ |
ohair@286 | 670 | private static void verifyPrimaryWSDL(@NotNull SDDocumentSource primaryWsdl, @NotNull QName serviceName) { |
ohair@286 | 671 | SDDocumentImpl primaryDoc = SDDocumentImpl.create(primaryWsdl,serviceName,null); |
ohair@286 | 672 | if (!(primaryDoc instanceof SDDocument.WSDL)) { |
ohair@286 | 673 | throw new WebServiceException(primaryWsdl.getSystemId()+ |
ohair@286 | 674 | " is not a WSDL. But it is passed as a primary WSDL"); |
ohair@286 | 675 | } |
ohair@286 | 676 | SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)primaryDoc; |
ohair@286 | 677 | if (!wsdlDoc.hasService()) { |
ohair@286 | 678 | if(wsdlDoc.getAllServices().isEmpty()) |
ohair@286 | 679 | throw new WebServiceException("Not a primary WSDL="+primaryWsdl.getSystemId()+ |
ohair@286 | 680 | " since it doesn't have Service "+serviceName); |
ohair@286 | 681 | else |
ohair@286 | 682 | throw new WebServiceException("WSDL "+primaryDoc.getSystemId() |
ohair@286 | 683 | +" has the following services "+wsdlDoc.getAllServices() |
ohair@286 | 684 | +" but not "+serviceName+". Maybe you forgot to specify a serviceName and/or targetNamespace in @WebService/@WebServiceProvider?"); |
ohair@286 | 685 | } |
ohair@286 | 686 | } |
ohair@286 | 687 | |
ohair@286 | 688 | /** |
ohair@286 | 689 | * Finds the primary WSDL document from the list of metadata documents. If |
ohair@286 | 690 | * there are two metadata documents that qualify for primary, it throws an |
ohair@286 | 691 | * exception. If there are two metadata documents that qualify for porttype, |
ohair@286 | 692 | * it throws an exception. |
ohair@286 | 693 | * |
ohair@286 | 694 | * @return primay wsdl document, null if is not there in the docList |
ohair@286 | 695 | * |
ohair@286 | 696 | */ |
ohair@286 | 697 | private static @Nullable SDDocumentImpl findPrimary(@NotNull List<SDDocumentImpl> docList) { |
ohair@286 | 698 | SDDocumentImpl primaryDoc = null; |
ohair@286 | 699 | boolean foundConcrete = false; |
ohair@286 | 700 | boolean foundAbstract = false; |
ohair@286 | 701 | for(SDDocumentImpl doc : docList) { |
ohair@286 | 702 | if (doc instanceof SDDocument.WSDL) { |
ohair@286 | 703 | SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)doc; |
ohair@286 | 704 | if (wsdlDoc.hasService()) { |
ohair@286 | 705 | primaryDoc = doc; |
ohair@286 | 706 | if (foundConcrete) { |
ohair@286 | 707 | throw new ServerRtException("duplicate.primary.wsdl", doc.getSystemId() ); |
ohair@286 | 708 | } |
ohair@286 | 709 | foundConcrete = true; |
ohair@286 | 710 | } |
ohair@286 | 711 | if (wsdlDoc.hasPortType()) { |
ohair@286 | 712 | if (foundAbstract) { |
ohair@286 | 713 | throw new ServerRtException("duplicate.abstract.wsdl", doc.getSystemId()); |
ohair@286 | 714 | } |
ohair@286 | 715 | foundAbstract = true; |
ohair@286 | 716 | } |
ohair@286 | 717 | } |
ohair@286 | 718 | } |
ohair@286 | 719 | return primaryDoc; |
ohair@286 | 720 | } |
ohair@286 | 721 | |
ohair@286 | 722 | /** |
ohair@286 | 723 | * Parses the primary WSDL and returns the {@link WSDLPort} for the given service and port names |
ohair@286 | 724 | * |
ohair@286 | 725 | * @param primaryWsdl Primary WSDL |
ohair@286 | 726 | * @param metadata it may contain imported WSDL and schema documents |
ohair@286 | 727 | * @param serviceName service name in wsdl |
ohair@286 | 728 | * @param portName port name in WSDL |
ohair@286 | 729 | * @param container container in which this service is running |
ohair@286 | 730 | * @return non-null wsdl port object |
ohair@286 | 731 | */ |
ohair@286 | 732 | private static @NotNull WSDLPortImpl getWSDLPort(SDDocumentSource primaryWsdl, List<? extends SDDocumentSource> metadata, |
alanb@368 | 733 | @NotNull QName serviceName, @NotNull QName portName, Container container, |
alanb@368 | 734 | EntityResolver resolver) { |
ohair@286 | 735 | URL wsdlUrl = primaryWsdl.getSystemId(); |
ohair@286 | 736 | try { |
ohair@286 | 737 | // TODO: delegate to another entity resolver |
ohair@286 | 738 | WSDLModelImpl wsdlDoc = RuntimeWSDLParser.parse( |
alanb@368 | 739 | new Parser(primaryWsdl), new EntityResolverImpl(metadata, resolver), |
ohair@286 | 740 | false, container, ServiceFinder.find(WSDLParserExtension.class).toArray()); |
ohair@286 | 741 | if(wsdlDoc.getServices().size() == 0) { |
ohair@286 | 742 | throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_NOSERVICE_IN_WSDLMODEL(wsdlUrl)); |
ohair@286 | 743 | } |
ohair@286 | 744 | WSDLServiceImpl wsdlService = wsdlDoc.getService(serviceName); |
ohair@286 | 745 | if (wsdlService == null) { |
ohair@286 | 746 | throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICE(serviceName,wsdlUrl)); |
ohair@286 | 747 | } |
ohair@286 | 748 | WSDLPortImpl wsdlPort = wsdlService.get(portName); |
ohair@286 | 749 | if (wsdlPort == null) { |
ohair@286 | 750 | throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICEPORT(serviceName, portName, wsdlUrl)); |
ohair@286 | 751 | } |
ohair@286 | 752 | return wsdlPort; |
ohair@286 | 753 | } catch (IOException e) { |
ohair@286 | 754 | throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); |
ohair@286 | 755 | } catch (XMLStreamException e) { |
ohair@286 | 756 | throw new ServerRtException("runtime.saxparser.exception", e.getMessage(), e.getLocation(), e); |
ohair@286 | 757 | } catch (SAXException e) { |
ohair@286 | 758 | throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); |
ohair@286 | 759 | } catch (ServiceConfigurationError e) { |
ohair@286 | 760 | throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); |
ohair@286 | 761 | } |
ohair@286 | 762 | } |
ohair@286 | 763 | |
ohair@286 | 764 | /** |
ohair@286 | 765 | * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s. |
ohair@286 | 766 | */ |
ohair@286 | 767 | private static final class EntityResolverImpl implements XMLEntityResolver { |
ohair@286 | 768 | private Map<String,SDDocumentSource> metadata = new HashMap<String,SDDocumentSource>(); |
alanb@368 | 769 | private EntityResolver resolver; |
ohair@286 | 770 | |
alanb@368 | 771 | public EntityResolverImpl(List<? extends SDDocumentSource> metadata, EntityResolver resolver) { |
ohair@286 | 772 | for (SDDocumentSource doc : metadata) { |
ohair@286 | 773 | this.metadata.put(doc.getSystemId().toExternalForm(),doc); |
ohair@286 | 774 | } |
alanb@368 | 775 | this.resolver = resolver; |
ohair@286 | 776 | } |
ohair@286 | 777 | |
ohair@286 | 778 | public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException { |
ohair@286 | 779 | if (systemId != null) { |
ohair@286 | 780 | SDDocumentSource doc = metadata.get(systemId); |
ohair@286 | 781 | if (doc != null) |
ohair@286 | 782 | return new Parser(doc); |
ohair@286 | 783 | } |
alanb@368 | 784 | if (resolver != null) { |
alanb@368 | 785 | try { |
alanb@368 | 786 | InputSource source = resolver.resolveEntity(publicId, systemId); |
alanb@368 | 787 | if (source != null) { |
alanb@368 | 788 | Parser p = new Parser(null, XMLStreamReaderFactory.create(source, true)); |
alanb@368 | 789 | return p; |
alanb@368 | 790 | } |
alanb@368 | 791 | } catch (SAXException e) { |
alanb@368 | 792 | throw new XMLStreamException(e); |
alanb@368 | 793 | } |
alanb@368 | 794 | } |
ohair@286 | 795 | return null; |
ohair@286 | 796 | } |
ohair@286 | 797 | |
ohair@286 | 798 | } |
ohair@286 | 799 | |
ohair@286 | 800 | private static final Logger logger = Logger.getLogger( |
ohair@286 | 801 | com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint"); |
ohair@286 | 802 | } |