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

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

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 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.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.WSDLPort;
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.model.wsdl.WSDLModelImpl;
import com.sun.xml.ws.model.wsdl.WSDLPortImpl;
import com.sun.xml.ws.model.wsdl.WSDLServiceImpl;
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.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.XMLInputFactory;
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.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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(); } List md = new ArrayList(); if(metadata!=null) md.addAll(metadata); if(primaryWsdl!=null && !md.contains(primaryWsdl)) md.add(primaryWsdl); 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 List docList = categoriseMetadata(md, 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; WSDLPortImpl 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); 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 documnets. */ private static List findMetadataClosure(SDDocumentImpl primaryDoc, List docList, EntityResolver resolver) { // create a map for old metadata Map oldMap = new HashMap(); for(SDDocumentImpl doc : docList) { oldMap.put(doc.getSystemId().toString(), doc); } // 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) { // 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 = XMLInputFactory.newInstance().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()); } } List newMetadata = new ArrayList(); newMetadata.addAll(newMap.values()); return newMetadata; } 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) { // RuntimeModeler rap; // // Create runtime model for non Provider endpoints // // // wsdlPort will be null, means we will generate WSDL. Hence no need to apply // // bindings or need to look in the WSDL // if(wsdlPort == null){ // rap = new RuntimeModeler(implType,serviceName, binding.getBindingId(), binding.getFeatures().toArray()); // } else { // /* // This not needed anymore as wsdlFeatures are merged later anyway // and so is the MTOMFeature. // applyEffectiveMtomSetting(wsdlPort.getBinding(), binding); // */ // //now we got the Binding so lets build the model // rap = new RuntimeModeler(implType, serviceName, (WSDLPortImpl)wsdlPort, binding.getFeatures().toArray()); // } // rap.setClassLoader(implType.getClassLoader()); // rap.setPortName(portName); // return rap.buildRuntimeModel(); DatabindingFactory fac = DatabindingFactory.newInstance(); DatabindingConfig config = new DatabindingConfig(); config.setEndpointClass(implType); config.getMappingInfo().setServiceName(serviceName); config.setWsdlPort(wsdlPort); config.setWSBinding(binding); // config.setFeatures(binding.getFeatures().toArray()); // config.getMappingInfo().setBindingID(binding.getBindingId()); config.setClassLoader(implType.getClassLoader()); config.getMappingInfo().setPortName(portName); 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) { // new com.oracle.webservices.api.databinding.ExternalMetadataFeature ef = binding.getFeature( com.oracle.webservices.api.databinding.ExternalMetadataFeature.class); if (ef != null) return ef.getMetadataReader(implType.getClassLoader()); //old org.jvnet.ws.databinding.ExternalMetadataFeature f = binding.getFeature( org.jvnet.ws.databinding.ExternalMetadataFeature.class); if (f != null) return f.getMetadataReader(implType.getClassLoader()); 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, List 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); seiModel.getDatabinding().generateWSDL(wsdlGenInfo); // WSDLGenerator wsdlGen = new WSDLGenerator(seiModel, wsdlResolver, binding, container, implType, false, // ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); // wsdlGen.doGeneration(); return wsdlResolver.updateDocs(); } /** * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}. */ private static List categoriseMetadata( List src, QName serviceName, QName portTypeName) { List r = new ArrayList(src.size()); for (SDDocumentSource doc : src) { r.add(SDDocumentImpl.create(doc,serviceName,portTypeName)); } return r; } /** * 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 List 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 WSDLPortImpl getWSDLPort(SDDocumentSource primaryWsdl, List metadata, @NotNull QName serviceName, @NotNull QName portName, Container container, EntityResolver resolver) { URL wsdlUrl = primaryWsdl.getSystemId(); try { // TODO: delegate to another entity resolver WSDLModelImpl 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)); } WSDLServiceImpl wsdlService = wsdlDoc.getService(serviceName); if (wsdlService == null) { throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICE(serviceName,wsdlUrl)); } WSDLPortImpl 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 Map metadata = new HashMap(); private EntityResolver resolver; public EntityResolverImpl(List metadata, EntityResolver resolver) { for (SDDocumentSource doc : metadata) { this.metadata.put(doc.getSystemId().toExternalForm(),doc); } 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); } 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"); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy