325N/A/*
478N/A * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/Apackage com.sun.xml.internal.ws.client;
325N/A
325N/Aimport com.sun.istack.internal.NotNull;
325N/Aimport com.sun.istack.internal.Nullable;
325N/Aimport com.sun.xml.internal.ws.Closeable;
325N/Aimport com.sun.xml.internal.ws.api.BindingID;
325N/Aimport com.sun.xml.internal.ws.api.EndpointAddress;
325N/Aimport com.sun.xml.internal.ws.api.WSService;
325N/Aimport com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
325N/Aimport com.sun.xml.internal.ws.api.client.ServiceInterceptor;
325N/Aimport com.sun.xml.internal.ws.api.client.ServiceInterceptorFactory;
478N/Aimport com.sun.xml.internal.ws.api.pipe.Stubs;
325N/Aimport com.sun.xml.internal.ws.api.server.Container;
325N/Aimport com.sun.xml.internal.ws.api.server.ContainerResolver;
325N/Aimport com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
325N/Aimport com.sun.xml.internal.ws.binding.BindingImpl;
325N/Aimport com.sun.xml.internal.ws.binding.WebServiceFeatureList;
325N/Aimport com.sun.xml.internal.ws.client.HandlerConfigurator.AnnotationConfigurator;
325N/Aimport com.sun.xml.internal.ws.client.HandlerConfigurator.HandlerResolverImpl;
325N/Aimport com.sun.xml.internal.ws.client.sei.SEIStub;
478N/Aimport com.sun.xml.internal.ws.developer.UsesJAXBContextFeature;
325N/Aimport com.sun.xml.internal.ws.developer.WSBindingProvider;
325N/Aimport com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
325N/Aimport com.sun.xml.internal.ws.model.RuntimeModeler;
325N/Aimport com.sun.xml.internal.ws.model.SOAPSEIModel;
325N/Aimport com.sun.xml.internal.ws.model.wsdl.WSDLModelImpl;
325N/Aimport com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl;
325N/Aimport com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl;
325N/Aimport com.sun.xml.internal.ws.resources.ClientMessages;
325N/Aimport com.sun.xml.internal.ws.resources.DispatchMessages;
325N/Aimport com.sun.xml.internal.ws.resources.ProviderApiMessages;
325N/Aimport com.sun.xml.internal.ws.util.JAXWSUtils;
325N/Aimport com.sun.xml.internal.ws.util.ServiceConfigurationError;
325N/Aimport com.sun.xml.internal.ws.util.ServiceFinder;
325N/Aimport com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;
325N/Aimport org.xml.sax.SAXException;
325N/A
325N/Aimport javax.jws.HandlerChain;
325N/Aimport javax.jws.WebService;
325N/Aimport javax.xml.bind.JAXBContext;
325N/Aimport javax.xml.namespace.QName;
325N/Aimport javax.xml.stream.XMLStreamException;
325N/Aimport javax.xml.transform.Source;
325N/Aimport javax.xml.transform.stream.StreamSource;
325N/Aimport javax.xml.ws.*;
325N/Aimport javax.xml.ws.handler.HandlerResolver;
325N/Aimport javax.xml.ws.soap.AddressingFeature;
325N/Aimport java.io.IOException;
478N/Aimport java.lang.RuntimePermission;
325N/Aimport java.lang.reflect.Proxy;
325N/Aimport java.net.MalformedURLException;
325N/Aimport java.net.URL;
478N/Aimport java.security.*;
325N/Aimport java.util.*;
325N/Aimport java.util.concurrent.Executor;
325N/Aimport java.util.concurrent.ThreadFactory;
325N/A
478N/Aimport static com.sun.xml.internal.ws.util.xml.XmlUtil.createDefaultCatalogResolver;
478N/A
325N/A/**
325N/A * <code>Service</code> objects provide the client view of a Web service.
325N/A *
325N/A * <p><code>Service</code> acts as a factory of the following:
325N/A * <ul>
325N/A * <li>Proxies for a target service endpoint.
325N/A * <li>Instances of <code>javax.xml.ws.Dispatch</code> for
325N/A * dynamic message-oriented invocation of a remote
325N/A * operation.
325N/A * </li>
325N/A *
325N/A * <p>The ports available on a service can be enumerated using the
325N/A * <code>getPorts</code> method. Alternatively, you can pass a
325N/A * service endpoint interface to the unary <code>getPort</code> method
325N/A * and let the runtime select a compatible port.
325N/A *
325N/A * <p>Handler chains for all the objects created by a <code>Service</code>
325N/A * can be set by means of the provided <code>HandlerRegistry</code>.
325N/A *
325N/A * <p>An <code>Executor</code> may be set on the service in order
325N/A * to gain better control over the threads used to dispatch asynchronous
325N/A * callbacks. For instance, thread pooling with certain parameters
325N/A * can be enabled by creating a <code>ThreadPoolExecutor</code> and
325N/A * registering it with the service.
325N/A *
325N/A * @author WS Development Team
325N/A * @see Executor
325N/A * @since JAX-WS 2.0
325N/A */
325N/Apublic class WSServiceDelegate extends WSService {
325N/A /**
325N/A * All ports.
325N/A * <p>
325N/A * This includes ports statically known to WSDL, as well as
325N/A * ones that are dynamically added
325N/A * through {@link #addPort(QName, String, String)}.
325N/A * <p>
325N/A * For statically known ports we'll have {@link SEIPortInfo}.
325N/A * For dynamically added ones we'll have {@link PortInfo}.
325N/A */
325N/A private final Map<QName, PortInfo> ports = new HashMap<QName, PortInfo>();
325N/A // For monitoring
325N/A Map<QName, PortInfo> getQNameToPortInfoMap() { return ports; }
325N/A
325N/A /**
325N/A * Whenever we create {@link BindingProvider}, we use this to configure handlers.
325N/A */
325N/A private @NotNull HandlerConfigurator handlerConfigurator = new HandlerResolverImpl(null);
325N/A
325N/A private final Class<? extends Service> serviceClass;
325N/A
325N/A /**
325N/A * Name of the service for which this {@link WSServiceDelegate} is created for.
325N/A */
325N/A private final @NotNull QName serviceName;
325N/A
325N/A /**
325N/A * Information about SEI, keyed by their interface type.
325N/A */
325N/A // private final Map<Class,SEIPortInfo> seiContext = new HashMap<Class,SEIPortInfo>();
325N/A private final Map<QName,SEIPortInfo> seiContext = new HashMap<QName,SEIPortInfo>();
325N/A
325N/A // This executor is used for all the async invocations for all proxies
325N/A // created from this service. But once the proxy is created, then changing
325N/A // this executor doesn't affect the already created proxies.
325N/A private volatile Executor executor;
325N/A
325N/A /**
325N/A * The WSDL service that this {@link Service} object represents.
325N/A * <p>
325N/A * This field is null iff no WSDL is given to {@link Service}.
325N/A * This fiels can be be null if the service is created without wsdl but later
325N/A * the epr supplies a wsdl that can be parsed.
325N/A */
325N/A private @Nullable WSDLServiceImpl wsdlService;
325N/A
325N/A private final Container container;
325N/A /**
325N/A * Multiple {@link ServiceInterceptor}s are aggregated into one.
325N/A */
325N/A /*package*/ final @NotNull ServiceInterceptor serviceInterceptor;
325N/A
325N/A
325N/A public WSServiceDelegate(URL wsdlDocumentLocation, QName serviceName, Class<? extends Service> serviceClass) {
325N/A this(
325N/A wsdlDocumentLocation==null ? null : new StreamSource(wsdlDocumentLocation.toExternalForm()),
325N/A serviceName,serviceClass);
325N/A }
325N/A
325N/A /**
325N/A * @param serviceClass
325N/A * Either {@link Service}.class or other generated service-derived classes.
325N/A */
325N/A public WSServiceDelegate(@Nullable Source wsdl, @NotNull QName serviceName, @NotNull final Class<? extends Service> serviceClass) {
325N/A //we cant create a Service without serviceName
325N/A if (serviceName == null)
325N/A throw new WebServiceException(ClientMessages.INVALID_SERVICE_NAME_NULL(serviceName));
325N/A
325N/A InitParams initParams = INIT_PARAMS.get();
325N/A INIT_PARAMS.set(null); // mark it as consumed
325N/A if(initParams==null) initParams = EMPTY_PARAMS;
325N/A
325N/A this.serviceName = serviceName;
325N/A this.serviceClass = serviceClass;
325N/A Container tContainer = initParams.getContainer()!=null ? initParams.getContainer() : ContainerResolver.getInstance().getContainer();
325N/A if (tContainer == Container.NONE) {
325N/A tContainer = new ClientContainer();
325N/A }
325N/A this.container = tContainer;
325N/A
325N/A // load interceptor
325N/A ServiceInterceptor interceptor = ServiceInterceptorFactory.load(this, Thread.currentThread().getContextClassLoader());
325N/A ServiceInterceptor si = container.getSPI(ServiceInterceptor.class);
325N/A if (si != null) {
325N/A interceptor = ServiceInterceptor.aggregate(interceptor, si);
325N/A }
325N/A this.serviceInterceptor = interceptor;
325N/A
325N/A
325N/A //if wsdl is null, try and get it from the WebServiceClient.wsdlLocation
325N/A if(wsdl == null){
325N/A if(serviceClass != Service.class){
325N/A WebServiceClient wsClient = AccessController.doPrivileged(new PrivilegedAction<WebServiceClient>() {
325N/A public WebServiceClient run() {
325N/A return serviceClass.getAnnotation(WebServiceClient.class);
325N/A }
325N/A });
325N/A String wsdlLocation = wsClient.wsdlLocation();
325N/A wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation));
325N/A wsdl = new StreamSource(wsdlLocation);
325N/A }
325N/A }
325N/A WSDLServiceImpl service=null;
325N/A if (wsdl != null) {
325N/A try {
325N/A URL url = wsdl.getSystemId()==null ? null : new URL(wsdl.getSystemId());
325N/A WSDLModelImpl model = parseWSDL(url, wsdl);
325N/A service = model.getService(this.serviceName);
325N/A if (service == null)
325N/A throw new WebServiceException(
325N/A ClientMessages.INVALID_SERVICE_NAME(this.serviceName,
325N/A buildNameList(model.getServices().keySet())));
325N/A // fill in statically known ports
325N/A for (WSDLPortImpl port : service.getPorts())
325N/A ports.put(port.getName(), new PortInfo(this, port));
325N/A } catch (MalformedURLException e) {
325N/A throw new WebServiceException(ClientMessages.INVALID_WSDL_URL(wsdl.getSystemId()));
325N/A }
325N/A }
325N/A this.wsdlService = service;
325N/A
325N/A if (serviceClass != Service.class) {
325N/A //if @HandlerChain present, set HandlerResolver on service context
325N/A HandlerChain handlerChain =
325N/A AccessController.doPrivileged(new PrivilegedAction<HandlerChain>() {
325N/A public HandlerChain run() {
325N/A return serviceClass.getAnnotation(HandlerChain.class);
325N/A }
325N/A });
325N/A if (handlerChain != null)
325N/A handlerConfigurator = new AnnotationConfigurator(this);
325N/A }
325N/A
325N/A }
325N/A
325N/A /**
325N/A * Parses the WSDL and builds {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLModel}.
325N/A * @param wsdlDocumentLocation
325N/A * Either this or <tt>wsdl</tt> parameter must be given.
325N/A * Null location means the system won't be able to resolve relative references in the WSDL,
325N/A */
325N/A private WSDLModelImpl parseWSDL(URL wsdlDocumentLocation, Source wsdlSource) {
325N/A try {
325N/A return RuntimeWSDLParser.parse(wsdlDocumentLocation, wsdlSource, createDefaultCatalogResolver(),
325N/A true, getContainer(), ServiceFinder.find(WSDLParserExtension.class).toArray());
325N/A } catch (IOException e) {
325N/A throw new WebServiceException(e);
325N/A } catch (XMLStreamException e) {
325N/A throw new WebServiceException(e);
325N/A } catch (SAXException e) {
325N/A throw new WebServiceException(e);
325N/A } catch (ServiceConfigurationError e) {
325N/A throw new WebServiceException(e);
325N/A }
325N/A }
325N/A
325N/A
325N/A
325N/A
325N/A public Executor getExecutor() {
325N/A return executor;
325N/A }
325N/A
325N/A public void setExecutor(Executor executor) {
325N/A this.executor = executor;
325N/A }
325N/A
325N/A public HandlerResolver getHandlerResolver() {
325N/A return handlerConfigurator.getResolver();
325N/A }
325N/A
325N/A /*package*/ final HandlerConfigurator getHandlerConfigurator() {
325N/A return handlerConfigurator;
325N/A }
325N/A
325N/A public void setHandlerResolver(HandlerResolver resolver) {
325N/A handlerConfigurator = new HandlerResolverImpl(resolver);
325N/A }
325N/A
325N/A public <T> T getPort(QName portName, Class<T> portInterface) throws WebServiceException {
325N/A return getPort(portName, portInterface, EMPTY_FEATURES);
325N/A }
325N/A
325N/A public <T> T getPort(QName portName, Class<T> portInterface, WebServiceFeature... features) {
325N/A if (portName == null || portInterface == null)
325N/A throw new IllegalArgumentException();
325N/A WSDLServiceImpl tWsdlService = this.wsdlService;
325N/A if (tWsdlService == null) {
325N/A // assigning it to local variable and not setting it back to this.wsdlService intentionally
325N/A // as we don't want to include the service instance with information gathered from sei
325N/A tWsdlService = getWSDLModelfromSEI(portInterface);
325N/A //still null? throw error need wsdl metadata to create a proxy
325N/A if (tWsdlService == null) {
325N/A throw new WebServiceException(ProviderApiMessages.NO_WSDL_NO_PORT(portInterface.getName()));
325N/A }
325N/A
325N/A }
325N/A WSDLPortImpl portModel = getPortModel(tWsdlService, portName);
325N/A return getPort(portModel.getEPR(), portName, portInterface, features);
325N/A }
325N/A
325N/A public <T> T getPort(EndpointReference epr, Class<T> portInterface, WebServiceFeature... features) {
325N/A return getPort(WSEndpointReference.create(epr),portInterface,features);
325N/A }
325N/A
325N/A public <T> T getPort(WSEndpointReference wsepr, Class<T> portInterface, WebServiceFeature... features) {
325N/A //get the portType from SEI, so that it can be used if EPR does n't have endpointName
325N/A QName portTypeName = RuntimeModeler.getPortTypeName(portInterface);
325N/A //if port name is not specified in EPR, it will use portTypeName to get it from the WSDL model.
325N/A QName portName = getPortNameFromEPR(wsepr, portTypeName);
325N/A return getPort(wsepr,portName,portInterface,features);
325N/A }
325N/A
325N/A private <T> T getPort(WSEndpointReference wsepr, QName portName, Class<T> portInterface,
325N/A WebServiceFeature... features) {
325N/A SEIPortInfo spi = addSEI(portName, portInterface, features);
325N/A return createEndpointIFBaseProxy(wsepr,portName,portInterface,features, spi);
325N/A }
325N/A public <T> T getPort(Class<T> portInterface, WebServiceFeature... features) {
325N/A //get the portType from SEI
325N/A QName portTypeName = RuntimeModeler.getPortTypeName(portInterface);
325N/A WSDLServiceImpl wsdlService = this.wsdlService;
325N/A if(wsdlService == null) {
325N/A // assigning it to local variable and not setting it back to this.wsdlService intentionally
325N/A // as we don't want to include the service instance with information gathered from sei
325N/A wsdlService = getWSDLModelfromSEI(portInterface);
325N/A //still null? throw error need wsdl metadata to create a proxy
325N/A if(wsdlService == null) {
325N/A throw new WebServiceException(ProviderApiMessages.NO_WSDL_NO_PORT(portInterface.getName()));
325N/A }
325N/A }
325N/A //get the first port corresponding to the SEI
325N/A WSDLPortImpl port = wsdlService.getMatchingPort(portTypeName);
325N/A if (port == null)
325N/A throw new WebServiceException(ClientMessages.UNDEFINED_PORT_TYPE(portTypeName));
325N/A QName portName = port.getName();
325N/A return getPort(portName, portInterface,features);
325N/A }
325N/A
325N/A public <T> T getPort(Class<T> portInterface) throws WebServiceException {
325N/A return getPort(portInterface, EMPTY_FEATURES);
325N/A }
325N/A
325N/A public void addPort(QName portName, String bindingId, String endpointAddress) throws WebServiceException {
325N/A if (!ports.containsKey(portName)) {
325N/A BindingID bid = (bindingId == null) ? BindingID.SOAP11_HTTP : BindingID.parse(bindingId);
325N/A ports.put(portName,
325N/A new PortInfo(this, (endpointAddress == null) ? null :
325N/A EndpointAddress.create(endpointAddress), portName, bid));
325N/A } else
325N/A throw new WebServiceException(DispatchMessages.DUPLICATE_PORT(portName.toString()));
325N/A }
325N/A
325N/A
325N/A public <T> Dispatch<T> createDispatch(QName portName, Class<T> aClass, Service.Mode mode) throws WebServiceException {
325N/A return createDispatch(portName, aClass, mode, EMPTY_FEATURES);
325N/A }
325N/A
325N/A @Override
325N/A public <T> Dispatch<T> createDispatch(QName portName, WSEndpointReference wsepr, Class<T> aClass, Service.Mode mode, WebServiceFeature... features) {
325N/A PortInfo port = safeGetPort(portName);
325N/A BindingImpl binding = port.createBinding(features,null);
325N/A binding.setMode(mode);
325N/A Dispatch<T> dispatch = Stubs.createDispatch(port, this, binding, aClass, mode, wsepr);
325N/A serviceInterceptor.postCreateDispatch((WSBindingProvider) dispatch);
325N/A return dispatch;
325N/A }
325N/A
325N/A public <T> Dispatch<T> createDispatch(QName portName, Class<T> aClass, Service.Mode mode, WebServiceFeature... features) {
325N/A WebServiceFeatureList featureList = new WebServiceFeatureList(features);
325N/A WSEndpointReference wsepr = null;
325N/A if(featureList.isEnabled(AddressingFeature.class) && wsdlService != null && wsdlService.get(portName) != null) {
325N/A wsepr = wsdlService.get(portName).getEPR();
325N/A }
325N/A return createDispatch(portName, wsepr, aClass, mode, features);
325N/A }
325N/A
325N/A public <T> Dispatch<T> createDispatch(EndpointReference endpointReference, Class<T> type, Service.Mode mode, WebServiceFeature... features) {
325N/A WSEndpointReference wsepr = new WSEndpointReference(endpointReference);
325N/A QName portName = addPortEpr(wsepr);
325N/A return createDispatch(portName, wsepr, type, mode, features);
325N/A }
325N/A
325N/A /**
325N/A * Obtains {@link PortInfo} for the given name, with error check.
325N/A */
325N/A public
325N/A @NotNull
325N/A PortInfo safeGetPort(QName portName) {
325N/A PortInfo port = ports.get(portName);
325N/A if (port == null) {
325N/A throw new WebServiceException(ClientMessages.INVALID_PORT_NAME(portName, buildNameList(ports.keySet())));
325N/A }
325N/A return port;
325N/A }
325N/A
325N/A private StringBuilder buildNameList(Collection<QName> names) {
325N/A StringBuilder sb = new StringBuilder();
325N/A for (QName qn : names) {
325N/A if (sb.length() > 0) sb.append(',');
325N/A sb.append(qn);
325N/A }
325N/A return sb;
325N/A }
325N/A
325N/A public EndpointAddress getEndpointAddress(QName qName) {
325N/A return ports.get(qName).targetEndpoint;
325N/A }
325N/A
325N/A public Dispatch<Object> createDispatch(QName portName, JAXBContext jaxbContext, Service.Mode mode) throws WebServiceException {
325N/A return createDispatch(portName, jaxbContext, mode, EMPTY_FEATURES);
325N/A }
325N/A
325N/A @Override
325N/A public Dispatch<Object> createDispatch(QName portName, WSEndpointReference wsepr, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeature... features) {
325N/A PortInfo port = safeGetPort(portName);
325N/A BindingImpl binding = port.createBinding(features,null);
325N/A binding.setMode(mode);
325N/A Dispatch<Object> dispatch = Stubs.createJAXBDispatch(
325N/A port, binding, jaxbContext, mode,wsepr);
325N/A serviceInterceptor.postCreateDispatch((WSBindingProvider)dispatch);
325N/A return dispatch;
325N/A }
325N/A
325N/A @Override
325N/A public @NotNull Container getContainer() {
325N/A return container;
325N/A }
325N/A
325N/A public Dispatch<Object> createDispatch(QName portName, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeature... webServiceFeatures) {
325N/A WebServiceFeatureList featureList = new WebServiceFeatureList(webServiceFeatures);
325N/A WSEndpointReference wsepr = null;
325N/A if(featureList.isEnabled(AddressingFeature.class) && wsdlService != null && wsdlService.get(portName) != null) {
325N/A wsepr = wsdlService.get(portName).getEPR();
325N/A }
325N/A return createDispatch(portName, wsepr, jaxbContext, mode, webServiceFeatures);
325N/A }
325N/A
325N/A public Dispatch<Object> createDispatch(EndpointReference endpointReference, JAXBContext context, Service.Mode mode, WebServiceFeature... features) {
325N/A WSEndpointReference wsepr = new WSEndpointReference(endpointReference);
325N/A QName portName = addPortEpr(wsepr);
325N/A return createDispatch(portName, wsepr, context, mode, features);
325N/A }
325N/A
325N/A private QName addPortEpr(WSEndpointReference wsepr) {
325N/A if (wsepr == null)
325N/A throw new WebServiceException(ProviderApiMessages.NULL_EPR());
325N/A QName eprPortName = getPortNameFromEPR(wsepr, null);
325N/A //add Port, if it does n't exist;
325N/A // TODO: what if it has different epr address?
325N/A {
325N/A PortInfo portInfo = new PortInfo(this, (wsepr.getAddress() == null) ? null : EndpointAddress.create(wsepr.getAddress()), eprPortName,
325N/A getPortModel(wsdlService, eprPortName).getBinding().getBindingId());
325N/A if (!ports.containsKey(eprPortName)) {
325N/A ports.put(eprPortName, portInfo);
325N/A }
325N/A }
325N/A return eprPortName;
325N/A }
325N/A
325N/A /**
325N/A *
325N/A * @param wsepr EndpointReference from which portName will be extracted.
325N/A * If EndpointName ( port name) is null in EPR, then it will try to get if from WSDLModel using portType QName
325N/A * @param portTypeName
325N/A * should be null in dispatch case
325N/A * should be non null in SEI case
325N/A * @return
325N/A * port name from EPR after validating various metadat elements.
325N/A * Also if service instance does n't have wsdl,
325N/A * then it gets the WSDL metadata from EPR and builds wsdl model.
325N/A */
325N/A private QName getPortNameFromEPR(@NotNull WSEndpointReference wsepr, @Nullable QName portTypeName) {
325N/A QName portName;
325N/A WSEndpointReference.Metadata metadata = wsepr.getMetaData();
325N/A QName eprServiceName = metadata.getServiceName();
325N/A QName eprPortName = metadata.getPortName();
325N/A if ((eprServiceName != null ) && !eprServiceName.equals(serviceName)) {
325N/A throw new WebServiceException("EndpointReference WSDL ServiceName differs from Service Instance WSDL Service QName.\n"
325N/A + " The two Service QNames must match");
325N/A }
325N/A if (wsdlService == null) {
325N/A Source eprWsdlSource = metadata.getWsdlSource();
325N/A if (eprWsdlSource == null) {
325N/A throw new WebServiceException(ProviderApiMessages.NULL_WSDL());
325N/A }
325N/A try {
325N/A WSDLModelImpl eprWsdlMdl = parseWSDL(new URL(wsepr.getAddress()), eprWsdlSource);
325N/A wsdlService = eprWsdlMdl.getService(serviceName);
325N/A if (wsdlService == null)
325N/A throw new WebServiceException(ClientMessages.INVALID_SERVICE_NAME(serviceName,
325N/A buildNameList(eprWsdlMdl.getServices().keySet())));
325N/A } catch (MalformedURLException e) {
325N/A throw new WebServiceException(ClientMessages.INVALID_ADDRESS(wsepr.getAddress()));
325N/A }
325N/A }
325N/A portName = eprPortName;
325N/A
325N/A if (portName == null && portTypeName != null) {
325N/A //get the first port corresponding to the SEI
325N/A WSDLPortImpl port = wsdlService.getMatchingPort(portTypeName);
325N/A if (port == null)
325N/A throw new WebServiceException(ClientMessages.UNDEFINED_PORT_TYPE(portTypeName));
325N/A portName = port.getName();
325N/A }
325N/A if (portName == null)
325N/A throw new WebServiceException(ProviderApiMessages.NULL_PORTNAME());
325N/A if (wsdlService.get(portName) == null)
325N/A throw new WebServiceException(ClientMessages.INVALID_EPR_PORT_NAME(portName, buildWsdlPortNames()));
325N/A
325N/A return portName;
325N/A
325N/A }
325N/A
325N/A private WSDLServiceImpl getWSDLModelfromSEI(final Class sei) {
325N/A WebService ws = AccessController.doPrivileged(new PrivilegedAction<WebService>() {
325N/A public WebService run() {
325N/A return (WebService) sei.getAnnotation(WebService.class);
325N/A }
325N/A });
325N/A if (ws == null || ws.wsdlLocation().equals(""))
325N/A return null;
325N/A String wsdlLocation = ws.wsdlLocation();
325N/A wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation));
325N/A Source wsdl = new StreamSource(wsdlLocation);
325N/A WSDLServiceImpl service = null;
325N/A
325N/A try {
325N/A URL url = wsdl.getSystemId() == null ? null : new URL(wsdl.getSystemId());
325N/A WSDLModelImpl model = parseWSDL(url, wsdl);
325N/A service = model.getService(this.serviceName);
325N/A if (service == null)
325N/A throw new WebServiceException(
325N/A ClientMessages.INVALID_SERVICE_NAME(this.serviceName,
325N/A buildNameList(model.getServices().keySet())));
325N/A } catch (MalformedURLException e) {
325N/A throw new WebServiceException(ClientMessages.INVALID_WSDL_URL(wsdl.getSystemId()));
325N/A }
325N/A return service;
325N/A }
325N/A
325N/A public QName getServiceName() {
325N/A return serviceName;
325N/A }
325N/A
325N/A protected Class getServiceClass() {
325N/A return serviceClass;
325N/A }
325N/A
325N/A public Iterator<QName> getPorts() throws WebServiceException {
325N/A // KK: the spec seems to be ambigous about whether
325N/A // this returns ports that are dynamically added or not.
325N/A return ports.keySet().iterator();
325N/A }
325N/A
325N/A public URL getWSDLDocumentLocation() {
325N/A if(wsdlService==null) return null;
325N/A try {
325N/A return new URL(wsdlService.getParent().getLocation().getSystemId());
325N/A } catch (MalformedURLException e) {
325N/A throw new AssertionError(e); // impossible
325N/A }
325N/A }
325N/A
478N/A private <T> T createEndpointIFBaseProxy(@Nullable WSEndpointReference epr,QName portName, final Class<T> portInterface,
325N/A WebServiceFeature[] webServiceFeatures, SEIPortInfo eif) {
325N/A //fail if service doesnt have WSDL
325N/A if (wsdlService == null)
325N/A throw new WebServiceException(ClientMessages.INVALID_SERVICE_NO_WSDL(serviceName));
325N/A
325N/A if (wsdlService.get(portName)==null) {
325N/A throw new WebServiceException(
325N/A ClientMessages.INVALID_PORT_NAME(portName,buildWsdlPortNames()));
325N/A }
325N/A
325N/A BindingImpl binding = eif.createBinding(webServiceFeatures,portInterface);
325N/A SEIStub pis = new SEIStub(eif, binding, eif.model, epr);
325N/A
478N/A T proxy = createProxy(portInterface, pis);
478N/A
325N/A if (serviceInterceptor != null) {
325N/A serviceInterceptor.postCreateProxy((WSBindingProvider)proxy, portInterface);
325N/A }
325N/A return proxy;
325N/A }
325N/A
478N/A private <T> T createProxy(final Class<T> portInterface, final SEIStub pis) {
478N/A
478N/A // accessClassInPackage privilege needs to be granted ...
478N/A RuntimePermission perm = new RuntimePermission("accessClassInPackage.com.sun." + "xml.internal.*");
478N/A PermissionCollection perms = perm.newPermissionCollection();
478N/A perms.add(perm);
478N/A
478N/A return AccessController.doPrivileged(
478N/A new PrivilegedAction<T>() {
478N/A @Override
478N/A public T run() {
478N/A Object proxy = Proxy.newProxyInstance(portInterface.getClassLoader(),
478N/A new Class[]{portInterface, WSBindingProvider.class, Closeable.class}, pis);
478N/A return portInterface.cast(proxy);
478N/A }
478N/A },
478N/A new AccessControlContext(
478N/A new ProtectionDomain[]{
478N/A new ProtectionDomain(null, perms)
478N/A })
478N/A );
478N/A }
478N/A
325N/A /**
325N/A * Lists up the port names in WSDL. For error diagnostics.
325N/A */
325N/A private StringBuilder buildWsdlPortNames() {
325N/A Set<QName> wsdlPortNames = new HashSet<QName>();
325N/A for (WSDLPortImpl port : wsdlService.getPorts())
325N/A wsdlPortNames.add(port.getName());
325N/A return buildNameList(wsdlPortNames);
325N/A }
325N/A
325N/A /**
325N/A * Obtains a {@link WSDLPortImpl} with error check.
325N/A *
325N/A * @return guaranteed to be non-null.
325N/A */
325N/A private @NotNull WSDLPortImpl getPortModel(WSDLServiceImpl wsdlService, QName portName) {
325N/A WSDLPortImpl port = wsdlService.get(portName);
325N/A if (port == null)
325N/A throw new WebServiceException(
325N/A ClientMessages.INVALID_PORT_NAME(portName, buildWsdlPortNames()));
325N/A return port;
325N/A }
325N/A
325N/A /**
325N/A * Contributes to the construction of {@link WSServiceDelegate} by filling in
325N/A * {@link SEIPortInfo} about a given SEI (linked from the {@link Service}-derived class.)
325N/A */
325N/A //todo: valid port in wsdl
325N/A private SEIPortInfo addSEI(QName portName, Class portInterface, WebServiceFeature... features) throws WebServiceException {
325N/A boolean ownModel = useOwnSEIModel(features);
325N/A if (ownModel) {
325N/A // Create a new model and do not cache it
325N/A return createSEIPortInfo(portName, portInterface, features);
325N/A }
325N/A
325N/A SEIPortInfo spi = seiContext.get(portName);
325N/A if (spi == null) {
325N/A spi = createSEIPortInfo(portName, portInterface, features);
325N/A seiContext.put(spi.portName, spi);
325N/A ports.put(spi.portName, spi);
325N/A }
325N/A return spi;
325N/A }
325N/A
325N/A private SEIPortInfo createSEIPortInfo(QName portName, Class portInterface, WebServiceFeature... features) {
325N/A WSDLPortImpl wsdlPort = getPortModel(wsdlService, portName);
325N/A RuntimeModeler modeler = new RuntimeModeler(portInterface, serviceName, wsdlPort, features);
325N/A modeler.setClassLoader(portInterface.getClassLoader());
325N/A modeler.setPortName(portName);
325N/A AbstractSEIModelImpl model = modeler.buildRuntimeModel();
325N/A return new SEIPortInfo(this, portInterface, (SOAPSEIModel) model, wsdlPort);
325N/A }
325N/A
325N/A private boolean useOwnSEIModel(WebServiceFeature... features) {
325N/A return WebServiceFeatureList.getFeature(features, UsesJAXBContextFeature.class) != null;
325N/A }
325N/A
325N/A public WSDLServiceImpl getWsdlService() {
325N/A return wsdlService;
325N/A }
325N/A
325N/A class DaemonThreadFactory implements ThreadFactory {
325N/A public Thread newThread(Runnable r) {
325N/A Thread daemonThread = new Thread(r);
325N/A daemonThread.setDaemon(Boolean.TRUE);
325N/A return daemonThread;
325N/A }
325N/A }
325N/A
325N/A private static final WebServiceFeature[] EMPTY_FEATURES = new WebServiceFeature[0];
325N/A}