All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.ws.server.EndpointFactory Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.xml.ws.server;

import com.sun.istack.NotNull;
import com.sun.istack.Nullable;
import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
import com.sun.xml.ws.api.BindingID;
import com.sun.xml.ws.api.WSBinding;
import com.sun.xml.ws.api.WSFeatureList;
import com.sun.xml.ws.api.databinding.DatabindingConfig;
import com.sun.xml.ws.api.databinding.DatabindingFactory;
import com.sun.xml.ws.api.databinding.MetadataReader;
import com.sun.xml.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.ws.api.model.SEIModel;
import com.sun.xml.ws.api.model.wsdl.WSDLModel;
import com.sun.xml.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.ws.api.model.wsdl.WSDLService;
import com.sun.xml.ws.api.policy.PolicyResolver;
import com.sun.xml.ws.api.policy.PolicyResolverFactory;
import com.sun.xml.ws.api.server.AsyncProvider;
import com.sun.xml.ws.api.server.Container;
import com.sun.xml.ws.api.server.ContainerResolver;
import com.sun.xml.ws.api.server.InstanceResolver;
import com.sun.xml.ws.api.server.Invoker;
import com.sun.xml.ws.api.server.SDDocument;
import com.sun.xml.ws.api.server.SDDocumentSource;
import com.sun.xml.ws.api.server.WSEndpoint;
import com.sun.xml.ws.api.streaming.XMLStreamReaderFactory;
import com.sun.xml.ws.api.wsdl.parser.WSDLParserExtension;
import com.sun.xml.ws.api.wsdl.parser.XMLEntityResolver;
import com.sun.xml.ws.api.wsdl.parser.XMLEntityResolver.Parser;
import com.sun.xml.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.ws.binding.BindingImpl;
import com.sun.xml.ws.binding.SOAPBindingImpl;
import com.sun.xml.ws.binding.WebServiceFeatureList;
import com.sun.xml.ws.model.AbstractSEIModelImpl;
import com.sun.xml.ws.model.ReflectAnnotationReader;
import com.sun.xml.ws.model.RuntimeModeler;
import com.sun.xml.ws.model.SOAPSEIModel;
import com.sun.xml.ws.policy.PolicyMap;
import com.sun.xml.ws.policy.jaxws.PolicyUtil;
import com.sun.xml.ws.resources.ServerMessages;
import com.sun.xml.ws.server.provider.ProviderInvokerTube;
import com.sun.xml.ws.server.sei.SEIInvokerTube;
import com.sun.xml.ws.util.HandlerAnnotationInfo;
import com.sun.xml.ws.util.HandlerAnnotationProcessor;
import com.sun.xml.ws.util.ServiceConfigurationError;
import com.sun.xml.ws.util.ServiceFinder;
import com.sun.xml.ws.util.xml.XmlUtil;
import com.sun.xml.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
 * @author Jitendra Kotamraju
 */
public class EndpointFactory {
	private static final EndpointFactory instance = new EndpointFactory();
	
	public static EndpointFactory getInstance() {
		return instance;
	}
	
    /**
     * 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.
     *
     * 

* Nobody else should be calling this method. */ public static WSEndpoint createEndpoint( Class implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection metadata, EntityResolver resolver, boolean isTransportSynchronous) { return createEndpoint(implType, processHandlerAnnotation, invoker, serviceName, portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true); } public static WSEndpoint createEndpoint( Class implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection 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 {@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. * *

* Nobody else should be calling this method. */ public WSEndpoint create( Class implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection metadata, EntityResolver resolver, boolean isTransportSynchronous) { return create(implType, processHandlerAnnotation, invoker, serviceName, portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true); } public WSEndpoint create( Class implType, boolean processHandlerAnnotation, @Nullable Invoker invoker, @Nullable QName serviceName, @Nullable QName portName, @Nullable Container container, @Nullable WSBinding binding, @Nullable SDDocumentSource primaryWsdl, @Nullable Collection 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 md = new CollectionCollection(); if(primaryWsdl!=null) { if(metadata!=null) { Iterator 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 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 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 WSEndpoint create(QName serviceName, QName portName, WSBinding binding, Container container, SEIModel seiModel, WSDLPort wsdlPort, Class implType, ServiceDefinitionImpl serviceDefinition, EndpointAwareTube terminal, boolean isTransportSynchronous, PolicyMap policyMap) { return new WSEndpointImpl(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 EndpointAwareTube createProviderInvokerTube(final Class 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. * * @param primaryDoc primary WSDL doc * @param docList complete metadata * @return new metadata that doesn't contain extraneous documents. */ private static Collection findMetadataClosure( final SDDocumentImpl primaryDoc, final Collection docList, final EntityResolver resolver) { return new AbstractCollection() { @Override public Iterator iterator() { // create a map for old metadata Map oldMap = new HashMap(); Iterator oldDocs = docList.iterator(); // create a map for new metadata Map newMap = new HashMap(); newMap.put(primaryDoc.getSystemId().toString(), primaryDoc); List remaining = new ArrayList(); 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 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 void processHandlerAnnotation(WSBinding binding, Class 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 * * @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 * * @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.ws.db.DatabindingImpl rt = (com.sun.xml.ws.db.DatabindingImpl)fac.createRuntime(config); return (AbstractSEIModelImpl) rt.getModel(); } public static MetadataReader getExternalMetadatReader(Class implType, WSBinding binding) { com.oracle.webservices.api.databinding.ExternalMetadataFeature ef = binding.getFeature( com.oracle.webservices.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 {@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. * * @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. * * @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. * * @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 */ private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, Collection 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 categoriseMetadata( final Iterator src, final QName serviceName, final QName portTypeName) { return new AbstractCollection() { private final Collection theConverted = new ArrayList(); @Override public boolean add(SDDocumentImpl arg0) { return theConverted.add(arg0); } @Override public Iterator iterator() { return new Iterator() { private Iterator 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. */ 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. * * @return primay wsdl document, null if is not there in the docList * */ private static @Nullable SDDocumentImpl findPrimary(@NotNull Collection 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 {@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 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); } } /** * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s. */ private static final class EntityResolverImpl implements XMLEntityResolver { private Iterator origMetadata; private Map metadata = new ConcurrentHashMap(); private EntityResolver resolver; public EntityResolverImpl(Collection 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.ws.util.Constants.LoggingDomain + ".server.endpoint"); private static class CollectionCollection extends AbstractCollection { private final Collection> cols = new ArrayList>(); @Override public Iterator iterator() { final Iterator> colIt = cols.iterator(); return new Iterator() { private Iterator 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 c : cols) size += c.size(); return size; } @Override public boolean add(T arg0) { return cols.add(Collections.singleton(arg0)); } @Override public boolean addAll(Collection arg0) { return cols.add(arg0); } @Override public void clear() { cols.clear(); } @Override public boolean isEmpty() { return !iterator().hasNext(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy