/*
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.xml.internal.ws.server;

import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
import com.sun.xml.internal.ws.api.BindingID;
import com.sun.xml.internal.ws.api.WSBinding;
import com.sun.xml.internal.ws.api.WSFeatureList;
import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
import com.sun.xml.internal.ws.api.databinding.MetadataReader;
import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.internal.ws.api.model.SEIModel;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLService;
import com.sun.xml.internal.ws.api.policy.PolicyResolver;
import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory;
import com.sun.xml.internal.ws.api.server.AsyncProvider;
import com.sun.xml.internal.ws.api.server.Container;
import com.sun.xml.internal.ws.api.server.ContainerResolver;
import com.sun.xml.internal.ws.api.server.InstanceResolver;
import com.sun.xml.internal.ws.api.server.Invoker;
import com.sun.xml.internal.ws.api.server.SDDocument;
import com.sun.xml.internal.ws.api.server.SDDocumentSource;
import com.sun.xml.internal.ws.api.server.WSEndpoint;
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver;
import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver.Parser;
import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.internal.ws.binding.BindingImpl;
import com.sun.xml.internal.ws.binding.SOAPBindingImpl;
import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
import com.sun.xml.internal.ws.model.ReflectAnnotationReader;
import com.sun.xml.internal.ws.model.RuntimeModeler;
import com.sun.xml.internal.ws.model.SOAPSEIModel;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.jaxws.PolicyUtil;
import com.sun.xml.internal.ws.resources.ServerMessages;
import com.sun.xml.internal.ws.server.provider.ProviderInvokerTube;
import com.sun.xml.internal.ws.server.sei.SEIInvokerTube;
import com.sun.xml.internal.ws.util.HandlerAnnotationInfo;
import com.sun.xml.internal.ws.util.HandlerAnnotationProcessor;
import com.sun.xml.internal.ws.util.ServiceConfigurationError;
import com.sun.xml.internal.ws.util.ServiceFinder;
import com.sun.xml.internal.ws.util.xml.XmlUtil;
import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.soap.SOAPBinding;

import java.io.IOException;
import java.net.URL;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

Entry point to the JAX-WS RI server-side runtime.
Author:Kohsuke Kawaguchi, Jitendra Kotamraju
/** * Entry point to the JAX-WS RI server-side runtime. * * @author Kohsuke Kawaguchi * @author Jitendra Kotamraju */
public class EndpointFactory { private static final EndpointFactory instance = new EndpointFactory(); public static EndpointFactory getInstance() { return instance; }
Implements WSEndpoint.create. No need to take WebServiceContext implementation. When InvokerPipe is instantiated, it calls InstanceResolver to set up a WebServiceContext. We shall only take delegate to getUserPrincipal and isUserInRole from adapter.

Nobody else should be calling this method.

/** * Implements {@link WSEndpoint#create}. * * No need to take WebServiceContext implementation. When InvokerPipe is * instantiated, it calls InstanceResolver to set up a WebServiceContext. * We shall only take delegate to getUserPrincipal and isUserInRole from adapter. * * <p> * Nobody else should be calling this method. */
public static <T> WSEndpoint<T> createEndpoint( Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection<? extends SDDocumentSource> metadata, EntityResolver resolver, boolean isTransportSynchronous) { return createEndpoint(implType, processHandlerAnnotation, invoker, serviceName, portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true); } public static <T> WSEndpoint<T> createEndpoint( Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection<? extends SDDocumentSource> metadata, EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) { EndpointFactory factory = container != null ? container.getSPI(EndpointFactory.class) : null; if (factory == null) factory = EndpointFactory.getInstance(); return factory.create( implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard); }
Implements WSEndpoint.create. No need to take WebServiceContext implementation. When InvokerPipe is instantiated, it calls InstanceResolver to set up a WebServiceContext. We shall only take delegate to getUserPrincipal and isUserInRole from adapter.

Nobody else should be calling this method.

/** * Implements {@link WSEndpoint#create}. * * No need to take WebServiceContext implementation. When InvokerPipe is * instantiated, it calls InstanceResolver to set up a WebServiceContext. * We shall only take delegate to getUserPrincipal and isUserInRole from adapter. * * <p> * Nobody else should be calling this method. */
public <T> WSEndpoint<T> create( Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection<? extends SDDocumentSource> metadata, EntityResolver resolver, boolean isTransportSynchronous) { return create(implType, processHandlerAnnotation, invoker, serviceName, portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true); } public <T> WSEndpoint<T> create( Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection<? extends SDDocumentSource> metadata, EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) { if(implType ==null) throw new IllegalArgumentException(); MetadataReader metadataReader = getExternalMetadatReader(implType, binding); if (isStandard) { verifyImplementorClass(implType, metadataReader); } if (invoker == null) { invoker = InstanceResolver.createDefault(implType).createInvoker(); } // Performance analysis indicates that reading and parsing imported schemas is // a major component of Endpoint creation time. Therefore, modify SDDocumentSource // handling to delay iterating collection as long as possible. Collection<SDDocumentSource> md = new CollectionCollection<SDDocumentSource>(); if(primaryWsdl!=null) { if(metadata!=null) { Iterator<? extends SDDocumentSource> it = metadata.iterator(); if (it.hasNext() && primaryWsdl.equals(it.next())) md.addAll(metadata); else { md.add(primaryWsdl); md.addAll(metadata); } } else md.add(primaryWsdl); } else if(metadata!=null) md.addAll(metadata); if(container==null) container = ContainerResolver.getInstance().getContainer(); if(serviceName==null) serviceName = getDefaultServiceName(implType, metadataReader); if(portName==null) portName = getDefaultPortName(serviceName,implType, metadataReader); {// error check String serviceNS = serviceName.getNamespaceURI(); String portNS = portName.getNamespaceURI(); if (!serviceNS.equals(portNS)) { throw new ServerRtException("wrong.tns.for.port",portNS, serviceNS); } } // setting a default binding if (binding == null) binding = BindingImpl.create(BindingID.parse(implType)); if ( isStandard && primaryWsdl != null) { verifyPrimaryWSDL(primaryWsdl, serviceName); } QName portTypeName = null; if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) { portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader); } // Categorises the documents as WSDL, Schema etc Collection<SDDocumentImpl> docList = categoriseMetadata(md.iterator(), serviceName, portTypeName); // Finds the primary WSDL and makes sure that metadata doesn't have // two concrete or abstract WSDLs SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList); EndpointAwareTube terminal; WSDLPort wsdlPort = null; AbstractSEIModelImpl seiModel = null; // create WSDL model if (primaryDoc != null) { wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); } WebServiceFeatureList features=((BindingImpl)binding).getFeatures(); if (isStandard) { features.parseAnnotations(implType); } PolicyMap policyMap = null; // create terminal pipe that invokes the application if (isUseProviderTube(implType, isStandard)) { //TODO incase of Provider, provide a way to User for complete control of the message processing by giving // ability to turn off the WSDL/Policy based features and its associated tubes. //Even in case of Provider, merge all features configured via WSDL/Policy or deployment configuration Iterable<WebServiceFeature> configFtrs; if(wsdlPort != null) { policyMap = wsdlPort.getOwner().getParent().getPolicyMap(); //Merge features from WSDL and other policy configuration configFtrs = wsdlPort.getFeatures(); } else { //No WSDL, so try to merge features from Policy configuration policyMap = PolicyResolverFactory.create().resolve( new PolicyResolver.ServerContext(null, container, implType, false)); configFtrs = PolicyUtil.getPortScopedFeatures(policyMap,serviceName,portName); } features.mergeFeatures(configFtrs, true); terminal = createProviderInvokerTube(implType, binding, invoker, container); } else { // Create runtime model for non Provider endpoints seiModel = createSEIModel(wsdlPort, implType, serviceName, portName, binding, primaryDoc); if(binding instanceof SOAPBindingImpl){ //set portKnownHeaders on Binding, so that they can be used for MU processing ((SOAPBindingImpl)binding).setPortKnownHeaders( ((SOAPSEIModel)seiModel).getKnownHeaders()); } // Generate WSDL for SEI endpoints(not for Provider endpoints) if (primaryDoc == null) { primaryDoc = generateWSDL(binding, seiModel, docList, container, implType); // create WSDL model wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver); seiModel.freeze(wsdlPort); } policyMap = wsdlPort.getOwner().getParent().getPolicyMap(); // New Features might have been added in WSDL through Policy. //Merge features from WSDL and other policy configuration // This sets only the wsdl features that are not already set(enabled/disabled) features.mergeFeatures(wsdlPort.getFeatures(), true); terminal = createSEIInvokerTube(seiModel,invoker,binding); } // Process @HandlerChain, if handler-chain is not set via Deployment Descriptor if (processHandlerAnnotation) { processHandlerAnnotation(binding, implType, serviceName, portName); } // Selects only required metadata for this endpoint from the passed-in metadata if (primaryDoc != null) { docList = findMetadataClosure(primaryDoc, docList, resolver); } ServiceDefinitionImpl serviceDefiniton = (primaryDoc != null) ? new ServiceDefinitionImpl(docList, primaryDoc) : null; return create(serviceName, portName, binding, container, seiModel, wsdlPort, implType, serviceDefiniton, terminal, isTransportSynchronous, policyMap); } 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) { return new WSEndpointImpl<T>(serviceName, portName, binding, container, seiModel, wsdlPort, implType, serviceDefinition, terminal, isTransportSynchronous, policyMap); } protected boolean isUseProviderTube(Class<?> implType, boolean isStandard) { return !isStandard || implType.getAnnotation(WebServiceProvider.class)!=null; } protected EndpointAwareTube createSEIInvokerTube(AbstractSEIModelImpl seiModel, Invoker invoker, WSBinding binding) { return new SEIInvokerTube(seiModel,invoker,binding); } protected <T> EndpointAwareTube createProviderInvokerTube(final Class<T> implType, final WSBinding binding, final Invoker invoker, final Container container) { return ProviderInvokerTube.create(implType, binding, invoker, container); }
Goes through the original metadata documents and collects the required ones. This done traversing from primary WSDL and its imports until it builds a complete set of documents(transitive closure) for the endpoint.
Params:
  • primaryDoc – primary WSDL doc
  • docList – complete metadata
Returns:new metadata that doesn't contain extraneous documents.
/** * Goes through the original metadata documents and collects the required ones. * This done traversing from primary WSDL and its imports until it builds a * complete set of documents(transitive closure) for the endpoint. * * @param primaryDoc primary WSDL doc * @param docList complete metadata * @return new metadata that doesn't contain extraneous documents. */
private static Collection<SDDocumentImpl> findMetadataClosure( final SDDocumentImpl primaryDoc, final Collection<SDDocumentImpl> docList, final EntityResolver resolver) { return new AbstractCollection<SDDocumentImpl>() { @Override public Iterator<SDDocumentImpl> iterator() { // create a map for old metadata Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>(); Iterator<SDDocumentImpl> oldDocs = docList.iterator(); // create a map for new metadata Map<String, SDDocumentImpl> newMap = new HashMap<String, SDDocumentImpl>(); newMap.put(primaryDoc.getSystemId().toString(), primaryDoc); List<String> remaining = new ArrayList<String>(); remaining.addAll(primaryDoc.getImports()); while(!remaining.isEmpty()) { String url = remaining.remove(0); SDDocumentImpl doc = oldMap.get(url); if (doc == null) { while (oldDocs.hasNext()) { SDDocumentImpl old = oldDocs.next(); String id = old.getSystemId().toString(); oldMap.put(id, old); if (id.equals(url)) { doc = old; break; } } if (doc == null) { // old metadata doesn't have this imported doc, may be external if (resolver != null) { try { InputSource source = resolver.resolveEntity(null, url); if (source != null) { MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream()); xsb.createFromXMLStreamReader(reader); SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb); doc = SDDocumentImpl.create(sdocSource, null, null); } } catch (Exception ex) { ex.printStackTrace(); } } } } // Check if new metadata already contains this doc if (doc != null && !newMap.containsKey(url)) { newMap.put(url, doc); remaining.addAll(doc.getImports()); } } return newMap.values().iterator(); } @Override public int size() { int size = 0; Iterator<SDDocumentImpl> it = iterator(); while (it.hasNext()) { it.next(); size++; } return size; } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public boolean isEmpty() { return docList.isEmpty(); } }; } private static <T> void processHandlerAnnotation(WSBinding binding, Class<T> implType, QName serviceName, QName portName) { HandlerAnnotationInfo chainInfo = HandlerAnnotationProcessor.buildHandlerInfo( implType, serviceName, portName, binding); if (chainInfo != null) { binding.setHandlerChain(chainInfo.getHandlers()); if (binding instanceof SOAPBinding) { ((SOAPBinding) binding).setRoles(chainInfo.getRoles()); } } }
Verifies if the endpoint implementor class has @WebService or @WebServiceProvider annotation
Throws:
  • IllegalArgumentException – If it doesn't have any one of @WebService or @WebServiceProvider If it has both @WebService and @WebServiceProvider annotations
Returns: true if it is a Provider or AsyncProvider endpoint false otherwise
/** * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider * annotation * * @return * true if it is a Provider or AsyncProvider endpoint * false otherwise * @throws java.lang.IllegalArgumentException * If it doesn't have any one of @WebService or @WebServiceProvider * If it has both @WebService and @WebServiceProvider annotations */
public static boolean verifyImplementorClass(Class<?> clz) { return verifyImplementorClass(clz, null); }
Verifies if the endpoint implementor class has @WebService or @WebServiceProvider annotation; passing MetadataReader instance allows to read annotations from xml descriptor instead of class's annotations
Throws:
  • IllegalArgumentException – If it doesn't have any one of @WebService or @WebServiceProvider If it has both @WebService and @WebServiceProvider annotations
Returns: true if it is a Provider or AsyncProvider endpoint false otherwise
/** * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider * annotation; passing MetadataReader instance allows to read annotations from * xml descriptor instead of class's annotations * * @return * true if it is a Provider or AsyncProvider endpoint * false otherwise * @throws java.lang.IllegalArgumentException * If it doesn't have any one of @WebService or @WebServiceProvider * If it has both @WebService and @WebServiceProvider annotations */
public static boolean verifyImplementorClass(Class<?> clz, MetadataReader metadataReader) { if (metadataReader == null) { metadataReader = new ReflectAnnotationReader(); } WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, clz); WebService ws = metadataReader.getAnnotation(WebService.class, clz); if (wsProvider == null && ws == null) { throw new IllegalArgumentException(clz +" has neither @WebService nor @WebServiceProvider annotation"); } if (wsProvider != null && ws != null) { throw new IllegalArgumentException(clz +" has both @WebService and @WebServiceProvider annotations"); } if (wsProvider != null) { if (Provider.class.isAssignableFrom(clz) || AsyncProvider.class.isAssignableFrom(clz)) { return true; } throw new IllegalArgumentException(clz +" doesn't implement Provider or AsyncProvider interface"); } return false; } private static AbstractSEIModelImpl createSEIModel(WSDLPort wsdlPort, Class<?> implType, @NotNull QName serviceName, @NotNull QName portName, WSBinding binding, SDDocumentSource primaryWsdl) { DatabindingFactory fac = DatabindingFactory.newInstance(); DatabindingConfig config = new DatabindingConfig(); config.setEndpointClass(implType); config.getMappingInfo().setServiceName(serviceName); config.setWsdlPort(wsdlPort); config.setWSBinding(binding); config.setClassLoader(implType.getClassLoader()); config.getMappingInfo().setPortName(portName); if (primaryWsdl != null) config.setWsdlURL(primaryWsdl.getSystemId()); config.setMetadataReader(getExternalMetadatReader(implType, binding)); com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config); return (AbstractSEIModelImpl) rt.getModel(); } public static MetadataReader getExternalMetadatReader(Class<?> implType, WSBinding binding) { com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature ef = binding.getFeature( com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature.class); // TODO-Miran: would it be necessary to disable secure xml processing? if (ef != null) return ef.getMetadataReader(implType.getClassLoader(), false); return null; } /** *Set the mtom enable setting from wsdl model (mtom policy assertion) on to @link WSBinding} if DD has * not already set it on BindingID. Also check conflicts. */ /* private static void applyEffectiveMtomSetting(WSDLBoundPortType wsdlBinding, WSBinding binding){ if(wsdlBinding.isMTOMEnabled()){ BindingID bindingId = binding.getBindingId(); if(bindingId.isMTOMEnabled() == null){ binding.setMTOMEnabled(true); }else if (bindingId.isMTOMEnabled() != null && bindingId.isMTOMEnabled() == Boolean.FALSE){ //TODO: i18N throw new ServerRtException("Deployment failed! Mtom policy assertion in WSDL is enabled whereas the deplyment descriptor setting wants to disable it!"); } } } */
If service name is not already set via DD or programmatically, it uses annotations WebServiceProvider, WebService on implementorClass to get PortName.
Returns:non-null service name
/** * If service name is not already set via DD or programmatically, it uses * annotations {@link WebServiceProvider}, {@link WebService} on implementorClass to get PortName. * * @return non-null service name */
public static @NotNull QName getDefaultServiceName(Class<?> implType) { return getDefaultServiceName(implType, null); } public static @NotNull QName getDefaultServiceName(Class<?> implType, MetadataReader metadataReader) { return getDefaultServiceName(implType, true, metadataReader); } public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard) { return getDefaultServiceName(implType, isStandard, null); } public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard, MetadataReader metadataReader) { if (metadataReader == null) { metadataReader = new ReflectAnnotationReader(); } QName serviceName; WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); if (wsProvider!=null) { String tns = wsProvider.targetNamespace(); String local = wsProvider.serviceName(); serviceName = new QName(tns, local); } else { serviceName = RuntimeModeler.getServiceName(implType, metadataReader, isStandard); } assert serviceName != null; return serviceName; }
If portName is not already set via DD or programmatically, it uses annotations on implementorClass to get PortName.
Returns:non-null port name
/** * If portName is not already set via DD or programmatically, it uses * annotations on implementorClass to get PortName. * * @return non-null port name */
public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType) { return getDefaultPortName(serviceName, implType, null); } public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, MetadataReader metadataReader) { return getDefaultPortName(serviceName, implType, true, metadataReader); } public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard) { return getDefaultPortName(serviceName, implType, isStandard, null); } public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard, MetadataReader metadataReader) { if (metadataReader == null) { metadataReader = new ReflectAnnotationReader(); } QName portName; WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType); if (wsProvider!=null) { String tns = wsProvider.targetNamespace(); String local = wsProvider.portName(); portName = new QName(tns, local); } else { portName = RuntimeModeler.getPortName(implType, metadataReader, serviceName.getNamespaceURI(), isStandard); } assert portName != null; return portName; }
Returns the wsdl from @WebService, or @WebServiceProvider annotation using wsdlLocation element.
Params:
Returns:wsdl if there is wsdlLocation, else null
/** * Returns the wsdl from @WebService, or @WebServiceProvider annotation using * wsdlLocation element. * * @param implType * endpoint implementation class * make sure that you called {@link #verifyImplementorClass} on it. * @return wsdl if there is wsdlLocation, else null */
public static @Nullable String getWsdlLocation(Class<?> implType) { return getWsdlLocation(implType, new ReflectAnnotationReader()); }
Returns the wsdl from @WebService, or @WebServiceProvider annotation using wsdlLocation element.
Params:
Returns:wsdl if there is wsdlLocation, else null
/** * Returns the wsdl from @WebService, or @WebServiceProvider annotation using * wsdlLocation element. * * @param implType * endpoint implementation class * make sure that you called {@link #verifyImplementorClass} on it. * @return wsdl if there is wsdlLocation, else null */
public static @Nullable String getWsdlLocation(Class<?> implType, MetadataReader metadataReader) { if (metadataReader == null) { metadataReader = new ReflectAnnotationReader(); } WebService ws = metadataReader.getAnnotation(WebService.class, implType); if (ws != null) { return nullIfEmpty(ws.wsdlLocation()); } else { WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class); assert wsProvider != null; return nullIfEmpty(wsProvider.wsdlLocation()); } } private static String nullIfEmpty(String string) { if (string.length() < 1) { string = null; } return string; }
Generates the WSDL and XML Schema for the endpoint if necessary It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings
/** * Generates the WSDL and XML Schema for the endpoint if necessary * It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings */
private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, Collection<SDDocumentImpl> docs, Container container, Class implType) { BindingID bindingId = binding.getBindingId(); if (!bindingId.canGenerateWSDL()) { throw new ServerRtException("can.not.generate.wsdl", bindingId); } if (bindingId.toString().equals(SOAPBindingImpl.X_SOAP12HTTP_BINDING)) { String msg = ServerMessages.GENERATE_NON_STANDARD_WSDL(); logger.warning(msg); } // Generate WSDL and schema documents using runtime model WSDLGenResolver wsdlResolver = new WSDLGenResolver(docs,seiModel.getServiceQName(),seiModel.getPortTypeName()); WSDLGenInfo wsdlGenInfo = new WSDLGenInfo(); wsdlGenInfo.setWsdlResolver(wsdlResolver); wsdlGenInfo.setContainer(container); wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); wsdlGenInfo.setInlineSchemas(false); wsdlGenInfo.setSecureXmlProcessingDisabled(isSecureXmlProcessingDisabled(binding.getFeatures())); seiModel.getDatabinding().generateWSDL(wsdlGenInfo); // WSDLGenerator wsdlGen = new WSDLGenerator(seiModel, wsdlResolver, binding, container, implType, false, // ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); // wsdlGen.doGeneration(); return wsdlResolver.updateDocs(); } private static boolean isSecureXmlProcessingDisabled(WSFeatureList featureList) { // TODO-Miran: would it be necessary to disable secure xml processing? return false; } /** * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}. */ private static Collection<SDDocumentImpl> categoriseMetadata( final Iterator<SDDocumentSource> src, final QName serviceName, final QName portTypeName) { return new AbstractCollection<SDDocumentImpl>() { private final Collection<SDDocumentImpl> theConverted = new ArrayList<SDDocumentImpl>(); @Override public boolean add(SDDocumentImpl arg0) { return theConverted.add(arg0); } @Override public Iterator<SDDocumentImpl> iterator() { return new Iterator<SDDocumentImpl>() { private Iterator<SDDocumentImpl> convIt = theConverted.iterator(); @Override public boolean hasNext() { if (convIt != null && convIt.hasNext()) return true; return src.hasNext(); } @Override public SDDocumentImpl next() { if (convIt != null && convIt.hasNext()) return convIt.next(); convIt = null; if (!src.hasNext()) throw new NoSuchElementException(); SDDocumentImpl next = SDDocumentImpl.create(src.next(),serviceName,portTypeName); theConverted.add(next); return next; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int size() { throw new UnsupportedOperationException(); } @Override public boolean isEmpty() { if (!theConverted.isEmpty()) return false; return !src.hasNext(); } }; }
Verifies whether the given primaryWsdl contains the given serviceName. If the WSDL doesn't have the service, it throws an WebServiceException.
/** * Verifies whether the given primaryWsdl contains the given serviceName. * If the WSDL doesn't have the service, it throws an WebServiceException. */
private static void verifyPrimaryWSDL(@NotNull SDDocumentSource primaryWsdl, @NotNull QName serviceName) { SDDocumentImpl primaryDoc = SDDocumentImpl.create(primaryWsdl,serviceName,null); if (!(primaryDoc instanceof SDDocument.WSDL)) { throw new WebServiceException(primaryWsdl.getSystemId()+ " is not a WSDL. But it is passed as a primary WSDL"); } SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)primaryDoc; if (!wsdlDoc.hasService()) { if(wsdlDoc.getAllServices().isEmpty()) throw new WebServiceException("Not a primary WSDL="+primaryWsdl.getSystemId()+ " since it doesn't have Service "+serviceName); else throw new WebServiceException("WSDL "+primaryDoc.getSystemId() +" has the following services "+wsdlDoc.getAllServices() +" but not "+serviceName+". Maybe you forgot to specify a serviceName and/or targetNamespace in @WebService/@WebServiceProvider?"); } }
Finds the primary WSDL document from the list of metadata documents. If there are two metadata documents that qualify for primary, it throws an exception. If there are two metadata documents that qualify for porttype, it throws an exception.
Returns:primay wsdl document, null if is not there in the docList
/** * Finds the primary WSDL document from the list of metadata documents. If * there are two metadata documents that qualify for primary, it throws an * exception. If there are two metadata documents that qualify for porttype, * it throws an exception. * * @return primay wsdl document, null if is not there in the docList * */
private static @Nullable SDDocumentImpl findPrimary(@NotNull Collection<SDDocumentImpl> docList) { SDDocumentImpl primaryDoc = null; boolean foundConcrete = false; boolean foundAbstract = false; for(SDDocumentImpl doc : docList) { if (doc instanceof SDDocument.WSDL) { SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)doc; if (wsdlDoc.hasService()) { primaryDoc = doc; if (foundConcrete) { throw new ServerRtException("duplicate.primary.wsdl", doc.getSystemId() ); } foundConcrete = true; } if (wsdlDoc.hasPortType()) { if (foundAbstract) { throw new ServerRtException("duplicate.abstract.wsdl", doc.getSystemId()); } foundAbstract = true; } } } return primaryDoc; }
Parses the primary WSDL and returns the WSDLPort for the given service and port names
Params:
  • primaryWsdl – Primary WSDL
  • metadata – it may contain imported WSDL and schema documents
  • serviceName – service name in wsdl
  • portName – port name in WSDL
  • container – container in which this service is running
Returns:non-null wsdl port object
/** * Parses the primary WSDL and returns the {@link WSDLPort} for the given service and port names * * @param primaryWsdl Primary WSDL * @param metadata it may contain imported WSDL and schema documents * @param serviceName service name in wsdl * @param portName port name in WSDL * @param container container in which this service is running * @return non-null wsdl port object */
private static @NotNull WSDLPort getWSDLPort(SDDocumentSource primaryWsdl, Collection<? extends SDDocumentSource> metadata, @NotNull QName serviceName, @NotNull QName portName, Container container, EntityResolver resolver) { URL wsdlUrl = primaryWsdl.getSystemId(); try { // TODO: delegate to another entity resolver WSDLModel wsdlDoc = RuntimeWSDLParser.parse( new Parser(primaryWsdl), new EntityResolverImpl(metadata, resolver), false, container, ServiceFinder.find(WSDLParserExtension.class).toArray()); if(wsdlDoc.getServices().size() == 0) { throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_NOSERVICE_IN_WSDLMODEL(wsdlUrl)); } WSDLService wsdlService = wsdlDoc.getService(serviceName); if (wsdlService == null) { throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICE(serviceName,wsdlUrl)); } WSDLPort wsdlPort = wsdlService.get(portName); if (wsdlPort == null) { throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICEPORT(serviceName, portName, wsdlUrl)); } return wsdlPort; } catch (IOException e) { throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); } catch (XMLStreamException e) { throw new ServerRtException("runtime.saxparser.exception", e.getMessage(), e.getLocation(), e); } catch (SAXException e) { throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); } catch (ServiceConfigurationError e) { throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e); } }
XMLEntityResolver that can resolve to SDDocumentSources.
/** * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s. */
private static final class EntityResolverImpl implements XMLEntityResolver { private Iterator<? extends SDDocumentSource> origMetadata; private Map<String,SDDocumentSource> metadata = new ConcurrentHashMap<String,SDDocumentSource>(); private EntityResolver resolver; public EntityResolverImpl(Collection<? extends SDDocumentSource> metadata, EntityResolver resolver) { this.origMetadata = metadata.iterator(); this.resolver = resolver; } public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException { if (systemId != null) { SDDocumentSource doc = metadata.get(systemId); if (doc != null) return new Parser(doc); synchronized(this) { while(origMetadata.hasNext()) { doc = origMetadata.next(); String extForm = doc.getSystemId().toExternalForm(); this.metadata.put(extForm,doc); if (systemId.equals(extForm)) return new Parser(doc); } } } if (resolver != null) { try { InputSource source = resolver.resolveEntity(publicId, systemId); if (source != null) { Parser p = new Parser(null, XMLStreamReaderFactory.create(source, true)); return p; } } catch (SAXException e) { throw new XMLStreamException(e); } } return null; } } private static final Logger logger = Logger.getLogger( com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint"); private static class CollectionCollection<T> extends AbstractCollection<T> { private final Collection<Collection<? extends T>> cols = new ArrayList<Collection<? extends T>>(); @Override public Iterator<T> iterator() { final Iterator<Collection<? extends T>> colIt = cols.iterator(); return new Iterator<T>() { private Iterator<? extends T> current = null; @Override public boolean hasNext() { if (current == null || !current.hasNext()) { do { if (!colIt.hasNext()) return false; current = colIt.next().iterator(); } while (!current.hasNext()); return true; } return true; } @Override public T next() { if (!hasNext()) throw new NoSuchElementException(); return current.next(); } @Override public void remove() { if (current == null) throw new IllegalStateException(); current.remove(); } }; } @Override public int size() { int size = 0; for (Collection<? extends T> c : cols) size += c.size(); return size; } @Override public boolean add(T arg0) { return cols.add(Collections.singleton(arg0)); } @Override public boolean addAll(Collection<? extends T> arg0) { return cols.add(arg0); } @Override public void clear() { cols.clear(); } @Override public boolean isEmpty() { return !iterator().hasNext(); } } }