feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.server.AbstractInstanceResolver;
|
||||
import com.sun.xml.internal.ws.api.server.InstanceResolver;
|
||||
import com.sun.xml.internal.ws.api.server.ResourceInjector;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.api.server.WSWebServiceContext;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Partial implementation of {@link InstanceResolver} with code
|
||||
* to handle multiple instances per server.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class AbstractMultiInstanceResolver<T> extends AbstractInstanceResolver<T> {
|
||||
protected final Class<T> clazz;
|
||||
|
||||
// fields for resource injection.
|
||||
private /*almost final*/ WSWebServiceContext webServiceContext;
|
||||
protected /*almost final*/ WSEndpoint owner;
|
||||
private final Method postConstructMethod;
|
||||
private final Method preDestroyMethod;
|
||||
private /*almost final*/ ResourceInjector resourceInjector;
|
||||
|
||||
public AbstractMultiInstanceResolver(Class<T> clazz) {
|
||||
this.clazz = clazz;
|
||||
|
||||
postConstructMethod = findAnnotatedMethod(clazz, PostConstruct.class);
|
||||
preDestroyMethod = findAnnotatedMethod(clazz, PreDestroy.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform resource injection on the given instance.
|
||||
*/
|
||||
protected final void prepare(T t) {
|
||||
// we can only start creating new instances after the start method is invoked.
|
||||
assert webServiceContext!=null;
|
||||
|
||||
resourceInjector.inject(webServiceContext,t);
|
||||
invokeMethod(postConstructMethod,t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance via the default constructor.
|
||||
*/
|
||||
protected final T create() {
|
||||
T t = createNewInstance(clazz);
|
||||
prepare(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(WSWebServiceContext wsc, WSEndpoint endpoint) {
|
||||
resourceInjector = getResourceInjector(endpoint);
|
||||
this.webServiceContext = wsc;
|
||||
this.owner = endpoint;
|
||||
}
|
||||
|
||||
protected final void dispose(T instance) {
|
||||
invokeMethod(preDestroyMethod,instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.api.server.WSWebServiceContext;
|
||||
import com.sun.xml.internal.ws.server.provider.AsyncProviderInvokerTube;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.ws.EndpointReference;
|
||||
import javax.xml.ws.handler.MessageContext;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
import java.security.Principal;
|
||||
|
||||
/**
|
||||
* Partial {@link WSWebServiceContext} implementation. This implementation depends on
|
||||
* {@link Packet} and concrete implementations provide it via
|
||||
* {@link #getRequestPacket()}.
|
||||
*
|
||||
* @see InvokerTube,
|
||||
* @see AsyncProviderInvokerTube
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class AbstractWebServiceContext implements WSWebServiceContext {
|
||||
|
||||
private final WSEndpoint endpoint;
|
||||
|
||||
public AbstractWebServiceContext(@NotNull WSEndpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public MessageContext getMessageContext() {
|
||||
Packet packet = getRequestPacket();
|
||||
if (packet == null) {
|
||||
throw new IllegalStateException("getMessageContext() can only be called while servicing a request");
|
||||
}
|
||||
return new EndpointMessageContextImpl(packet);
|
||||
}
|
||||
|
||||
public Principal getUserPrincipal() {
|
||||
Packet packet = getRequestPacket();
|
||||
if (packet == null) {
|
||||
throw new IllegalStateException("getUserPrincipal() can only be called while servicing a request");
|
||||
}
|
||||
return packet.webServiceContextDelegate.getUserPrincipal(packet);
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String role) {
|
||||
Packet packet = getRequestPacket();
|
||||
if (packet == null) {
|
||||
throw new IllegalStateException("isUserInRole() can only be called while servicing a request");
|
||||
}
|
||||
return packet.webServiceContextDelegate.isUserInRole(packet,role);
|
||||
}
|
||||
|
||||
public EndpointReference getEndpointReference(Element...referenceParameters) {
|
||||
return getEndpointReference(W3CEndpointReference.class, referenceParameters);
|
||||
}
|
||||
|
||||
public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element...referenceParameters) {
|
||||
Packet packet = getRequestPacket();
|
||||
if (packet == null) {
|
||||
throw new IllegalStateException("getEndpointReference() can only be called while servicing a request");
|
||||
}
|
||||
String address = packet.webServiceContextDelegate.getEPRAddress(packet, endpoint);
|
||||
String wsdlAddress = null;
|
||||
if(endpoint.getServiceDefinition() != null) {
|
||||
wsdlAddress = packet.webServiceContextDelegate.getWSDLAddress(packet,endpoint);
|
||||
}
|
||||
return clazz.cast(endpoint.getEndpointReference(clazz,address,wsdlAddress, referenceParameters));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.server.ResourceInjector;
|
||||
import com.sun.xml.internal.ws.api.server.WSWebServiceContext;
|
||||
import com.sun.xml.internal.ws.util.InjectionPlan;
|
||||
|
||||
import javax.xml.ws.WebServiceContext;
|
||||
|
||||
/**
|
||||
* Default {@link ResourceInjector}.
|
||||
*
|
||||
* @see ResourceInjector#STANDALONE
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class DefaultResourceInjector extends ResourceInjector {
|
||||
public void inject(@NotNull WSWebServiceContext context, @NotNull Object instance) {
|
||||
InjectionPlan.buildInjectionPlan(
|
||||
instance.getClass(),WebServiceContext.class,false).inject(instance,context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.developer.ValidationErrorHandler;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Default {@link ValidationErrorHandler} that just rethrows SAXException
|
||||
* in case of errors.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class DraconianValidationErrorHandler extends ValidationErrorHandler {
|
||||
|
||||
public void warning(SAXParseException e) throws SAXException {
|
||||
// noop
|
||||
}
|
||||
|
||||
public void error(SAXParseException e) throws SAXException {
|
||||
throw e;
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException e) throws SAXException {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.pipe.Tube;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
|
||||
/**
|
||||
* Tubes that implement this interface will receive notification of the WSEndpoint
|
||||
* holding the tubeline after successful endpoint creation.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public interface EndpointAwareTube extends Tube {
|
||||
/**
|
||||
* Setter for WSEndpoint holding this tube
|
||||
* @param endpoint WSEndpoint holding this tube
|
||||
*/
|
||||
public void setEndpoint(WSEndpoint<?> endpoint);
|
||||
}
|
||||
783
jdkSrc/jdk8/com/sun/xml/internal/ws/server/EndpointFactory.java
Normal file
783
jdkSrc/jdk8/com/sun/xml/internal/ws/server/EndpointFactory.java
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.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.
|
||||
*
|
||||
* <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 {@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();
|
||||
}
|
||||
|
||||
List<SDDocumentSource> md = new ArrayList<SDDocumentSource>();
|
||||
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<SDDocumentImpl> 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;
|
||||
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.
|
||||
*
|
||||
* @param primaryDoc primary WSDL doc
|
||||
* @param docList complete metadata
|
||||
* @return new metadata that doesn't contain extraneous documnets.
|
||||
*/
|
||||
private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList, EntityResolver resolver) {
|
||||
// create a map for old metadata
|
||||
Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>();
|
||||
for(SDDocumentImpl doc : docList) {
|
||||
oldMap.put(doc.getSystemId().toString(), doc);
|
||||
}
|
||||
// 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) {
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
List<SDDocumentImpl> newMetadata = new ArrayList<SDDocumentImpl>();
|
||||
newMetadata.addAll(newMap.values());
|
||||
return newMetadata;
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* @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.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 {@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<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 List<SDDocumentImpl> categoriseMetadata(
|
||||
List<SDDocumentSource> src, QName serviceName, QName portTypeName) {
|
||||
|
||||
List<SDDocumentImpl> r = new ArrayList<SDDocumentImpl>(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<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 {@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, List<? 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s.
|
||||
*/
|
||||
private static final class EntityResolverImpl implements XMLEntityResolver {
|
||||
private Map<String,SDDocumentSource> metadata = new HashMap<String,SDDocumentSource>();
|
||||
private EntityResolver resolver;
|
||||
|
||||
public EntityResolverImpl(List<? extends SDDocumentSource> 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.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
|
||||
import java.util.*;
|
||||
import javax.xml.ws.handler.MessageContext;
|
||||
import javax.xml.ws.WebServiceContext;
|
||||
import javax.activation.DataHandler;
|
||||
|
||||
/**
|
||||
* Implements {@link WebServiceContext}'s {@link MessageContext} on top of {@link Packet}.
|
||||
*
|
||||
* <p>
|
||||
* This class creates a {@link Map} view for APPLICATION scoped properties that
|
||||
* gets exposed to endpoint implementations during the invocation
|
||||
* of web methods. The implementations access this map using
|
||||
* WebServiceContext.getMessageContext().
|
||||
*
|
||||
* <p>
|
||||
* Some of the {@link Map} methods requre this class to
|
||||
* build the complete {@link Set} of properties, but we
|
||||
* try to avoid that as much as possible.
|
||||
*
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class EndpointMessageContextImpl extends AbstractMap<String,Object> implements MessageContext {
|
||||
|
||||
/**
|
||||
* Lazily computed.
|
||||
*/
|
||||
private Set<Map.Entry<String,Object>> entrySet;
|
||||
private final Packet packet;
|
||||
|
||||
/**
|
||||
* @param packet
|
||||
* The {@link Packet} to wrap.
|
||||
*/
|
||||
public EndpointMessageContextImpl(Packet packet) {
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("element-type-mismatch")
|
||||
public Object get(Object key) {
|
||||
if (packet.supports(key)) {
|
||||
return packet.get(key); // strongly typed
|
||||
}
|
||||
if (packet.getHandlerScopePropertyNames(true).contains(key)) {
|
||||
return null; // no such application-scope property
|
||||
}
|
||||
Object value = packet.invocationProperties.get(key);
|
||||
|
||||
//add the attachments from the Message to the corresponding attachment property
|
||||
if(key.equals(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS) ||
|
||||
key.equals(MessageContext.INBOUND_MESSAGE_ATTACHMENTS)){
|
||||
Map<String, DataHandler> atts = (Map<String, DataHandler>) value;
|
||||
if(atts == null)
|
||||
atts = new HashMap<String, DataHandler>();
|
||||
AttachmentSet attSet = packet.getMessage().getAttachments();
|
||||
for(Attachment att : attSet){
|
||||
atts.put(att.getContentId(), att.asDataHandler());
|
||||
}
|
||||
return atts;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(String key, Object value) {
|
||||
if (packet.supports(key)) {
|
||||
return packet.put(key, value); // strongly typed
|
||||
}
|
||||
Object old = packet.invocationProperties.get(key);
|
||||
if (old != null) {
|
||||
if (packet.getHandlerScopePropertyNames(true).contains(key)) {
|
||||
throw new IllegalArgumentException("Cannot overwrite property in HANDLER scope");
|
||||
}
|
||||
// Overwrite existing APPLICATION scoped property
|
||||
packet.invocationProperties.put(key, value);
|
||||
return old;
|
||||
}
|
||||
// No existing property. So Add a new property
|
||||
packet.invocationProperties.put(key, value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("element-type-mismatch")
|
||||
public Object remove(Object key) {
|
||||
if (packet.supports(key)) {
|
||||
return packet.remove(key);
|
||||
}
|
||||
Object old = packet.invocationProperties.get(key);
|
||||
if (old != null) {
|
||||
if (packet.getHandlerScopePropertyNames(true).contains(key)) {
|
||||
throw new IllegalArgumentException("Cannot remove property in HANDLER scope");
|
||||
}
|
||||
// Remove existing APPLICATION scoped property
|
||||
packet.invocationProperties.remove(key);
|
||||
return old;
|
||||
}
|
||||
// No existing property.
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<Map.Entry<String, Object>> entrySet() {
|
||||
if (entrySet == null) {
|
||||
entrySet = new EntrySet();
|
||||
}
|
||||
return entrySet;
|
||||
}
|
||||
|
||||
public void setScope(String name, MessageContext.Scope scope) {
|
||||
throw new UnsupportedOperationException(
|
||||
"All the properties in this context are in APPLICATION scope. Cannot do setScope().");
|
||||
}
|
||||
|
||||
public MessageContext.Scope getScope(String name) {
|
||||
throw new UnsupportedOperationException(
|
||||
"All the properties in this context are in APPLICATION scope. Cannot do getScope().");
|
||||
}
|
||||
|
||||
private class EntrySet extends AbstractSet<Map.Entry<String, Object>> {
|
||||
|
||||
public Iterator<Map.Entry<String, Object>> iterator() {
|
||||
final Iterator<Map.Entry<String, Object>> it = createBackupMap().entrySet().iterator();
|
||||
|
||||
return new Iterator<Map.Entry<String, Object>>() {
|
||||
Map.Entry<String, Object> cur;
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public Map.Entry<String, Object> next() {
|
||||
cur = it.next();
|
||||
return cur;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
it.remove();
|
||||
EndpointMessageContextImpl.this.remove(cur.getKey());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return createBackupMap().size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Object> createBackupMap() {
|
||||
Map<String, Object> backupMap = new HashMap<String, Object>();
|
||||
backupMap.putAll(packet.createMapView());
|
||||
Set<String> handlerProps = packet.getHandlerScopePropertyNames(true);
|
||||
for(Map.Entry<String, Object> e : packet.invocationProperties.entrySet()) {
|
||||
if (!handlerProps.contains(e.getKey())) {
|
||||
backupMap.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
return backupMap;
|
||||
}
|
||||
|
||||
}
|
||||
167
jdkSrc/jdk8/com/sun/xml/internal/ws/server/InvokerTube.java
Normal file
167
jdkSrc/jdk8/com/sun/xml/internal/ws/server/InvokerTube.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
|
||||
import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl;
|
||||
import com.sun.xml.internal.ws.api.server.*;
|
||||
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 javax.xml.ws.WebServiceContext;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Base code for {@link ProviderInvokerTube} and {@link SEIInvokerTube}.
|
||||
*
|
||||
* <p>
|
||||
* This hides {@link InstanceResolver} and performs a set up
|
||||
* necessary for {@link WebServiceContext} to correctly.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class InvokerTube<T> extends com.sun.xml.internal.ws.server.sei.InvokerTube<Invoker> implements EndpointAwareTube {
|
||||
|
||||
private WSEndpoint endpoint;
|
||||
|
||||
protected InvokerTube(Invoker invoker) {
|
||||
super(invoker);
|
||||
}
|
||||
|
||||
public void setEndpoint(WSEndpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
WSWebServiceContext webServiceContext = new AbstractWebServiceContext(endpoint) {
|
||||
public @Nullable Packet getRequestPacket() {
|
||||
Packet p = packets.get();
|
||||
return p;
|
||||
}
|
||||
};
|
||||
invoker.start(webServiceContext,endpoint);
|
||||
}
|
||||
|
||||
protected WSEndpoint getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application object that serves the request.
|
||||
*
|
||||
public final @NotNull T getServant(Packet request) {
|
||||
// this allows WebServiceContext to find this packet
|
||||
packets.set(request);
|
||||
return invoker.resolve(request);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the {@link Invoker} object that serves the request.
|
||||
*/
|
||||
public final @NotNull Invoker getInvoker(Packet request) {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* processRequest() and processResponse() do not share any instance variables
|
||||
* while processing the request. {@link InvokerTube} is stateless and terminal,
|
||||
* so no need to create copies.
|
||||
*/
|
||||
public final AbstractTubeImpl copy(TubeCloner cloner) {
|
||||
cloner.add(this,this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void preDestroy() {
|
||||
invoker.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Heart of {@link WebServiceContext}.
|
||||
* Remembers which thread is serving which packet.
|
||||
*/
|
||||
private static final ThreadLocal<Packet> packets = new ThreadLocal<Packet>();
|
||||
|
||||
/**
|
||||
* This method can be called while the user service is servicing the request
|
||||
* synchronously, to obtain the current request packet.
|
||||
*
|
||||
* <p>
|
||||
* This is primarily designed for {@link StatefulInstanceResolver}. Use with care.
|
||||
*/
|
||||
public static @NotNull Packet getCurrentPacket() {
|
||||
Packet packet = packets.get();
|
||||
if(packet==null)
|
||||
throw new WebServiceException(ServerMessages.NO_CURRENT_PACKET());
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Invoker} filter that sets and restores the current packet.
|
||||
*/
|
||||
private final Invoker wrapper = new Invoker() {
|
||||
@Override
|
||||
public Object invoke(Packet p, Method m, Object... args) throws InvocationTargetException, IllegalAccessException {
|
||||
Packet old = set(p);
|
||||
try {
|
||||
return invoker.invoke(p, m, args);
|
||||
} finally {
|
||||
set(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T>T invokeProvider(Packet p, T arg) throws IllegalAccessException, InvocationTargetException {
|
||||
Packet old = set(p);
|
||||
try {
|
||||
return invoker.invokeProvider(p, arg);
|
||||
} finally {
|
||||
set(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T>void invokeAsyncProvider(Packet p, T arg, AsyncProviderCallback cbak, WebServiceContext ctxt) throws IllegalAccessException, InvocationTargetException {
|
||||
Packet old = set(p);
|
||||
try {
|
||||
invoker.invokeAsyncProvider(p, arg, cbak, ctxt);
|
||||
} finally {
|
||||
set(old);
|
||||
}
|
||||
}
|
||||
|
||||
private Packet set(Packet p) {
|
||||
Packet old = packets.get();
|
||||
packets.set(p);
|
||||
return old;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
412
jdkSrc/jdk8/com/sun/xml/internal/ws/server/MonitorBase.java
Normal file
412
jdkSrc/jdk8/com/sun/xml/internal/ws/server/MonitorBase.java
Normal file
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.EndpointAddress;
|
||||
import com.sun.xml.internal.ws.api.config.management.policy.ManagedClientAssertion;
|
||||
import com.sun.xml.internal.ws.api.config.management.policy.ManagedServiceAssertion;
|
||||
import com.sun.xml.internal.ws.api.config.management.policy.ManagementAssertion.Setting;
|
||||
import com.sun.xml.internal.ws.api.server.Container;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.client.Stub;
|
||||
import com.sun.org.glassfish.external.amx.AMXGlassfish;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
import com.sun.org.glassfish.gmbal.InheritedAttribute;
|
||||
import com.sun.org.glassfish.gmbal.InheritedAttributes;
|
||||
import com.sun.org.glassfish.gmbal.ManagedData;
|
||||
import com.sun.org.glassfish.gmbal.ManagedObjectManager;
|
||||
import com.sun.org.glassfish.gmbal.ManagedObjectManagerFactory;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
// BEGIN IMPORTS FOR RewritingMOM
|
||||
import java.util.ResourceBundle ;
|
||||
import java.lang.reflect.AnnotatedElement ;
|
||||
import java.lang.annotation.Annotation ;
|
||||
import javax.management.ObjectName ;
|
||||
import javax.management.MBeanServer ;
|
||||
import com.sun.org.glassfish.gmbal.AMXClient;
|
||||
import com.sun.org.glassfish.gmbal.GmbalMBean;
|
||||
// END IMPORTS FOR RewritingMOM
|
||||
|
||||
/**
|
||||
* @author Harold Carr
|
||||
*/
|
||||
public abstract class MonitorBase {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(
|
||||
com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
|
||||
|
||||
/**
|
||||
* Endpoint monitoring is ON by default.
|
||||
*
|
||||
* prop | no assert | assert/no mon | assert/mon off | assert/mon on
|
||||
* -------------------------------------------------------------------
|
||||
* not set | on | on | off | on
|
||||
* false | off | off | off | off
|
||||
* true | on | on | off | on
|
||||
*/
|
||||
@NotNull public ManagedObjectManager createManagedObjectManager(final WSEndpoint endpoint) {
|
||||
// serviceName + portName identifies the managed objects under it.
|
||||
// There can be multiple services in the container.
|
||||
// The same serviceName+portName can live in different apps at
|
||||
// different endpoint addresses.
|
||||
//
|
||||
// In general, monitoring will add -N, where N is unique integer,
|
||||
// in case of collisions.
|
||||
//
|
||||
// The endpoint address would be unique, but we do not know
|
||||
// the endpoint address until the first request comes in,
|
||||
// which is after monitoring is setup.
|
||||
|
||||
String rootName =
|
||||
endpoint.getServiceName().getLocalPart()
|
||||
+ "-"
|
||||
+ endpoint.getPortName().getLocalPart();
|
||||
|
||||
if (rootName.equals("-")) {
|
||||
rootName = "provider";
|
||||
}
|
||||
|
||||
// contextPath is not always available
|
||||
final String contextPath = getContextPath(endpoint);
|
||||
if (contextPath != null) {
|
||||
rootName = contextPath + "-" + rootName;
|
||||
}
|
||||
|
||||
final ManagedServiceAssertion assertion =
|
||||
ManagedServiceAssertion.getAssertion(endpoint);
|
||||
if (assertion != null) {
|
||||
final String id = assertion.getId();
|
||||
if (id != null) {
|
||||
rootName = id;
|
||||
}
|
||||
if (assertion.monitoringAttribute() == Setting.OFF) {
|
||||
return disabled("This endpoint", rootName);
|
||||
}
|
||||
}
|
||||
|
||||
if (endpointMonitoring.equals(Setting.OFF)) {
|
||||
return disabled("Global endpoint", rootName);
|
||||
}
|
||||
return createMOMLoop(rootName, 0);
|
||||
}
|
||||
|
||||
private String getContextPath(final WSEndpoint endpoint) {
|
||||
try {
|
||||
Container container = endpoint.getContainer();
|
||||
Method getSPI =
|
||||
container.getClass().getDeclaredMethod("getSPI", Class.class);
|
||||
getSPI.setAccessible(true);
|
||||
Class servletContextClass =
|
||||
Class.forName("javax.servlet.ServletContext");
|
||||
Object servletContext =
|
||||
getSPI.invoke(container, servletContextClass);
|
||||
if (servletContext != null) {
|
||||
Method getContextPath = servletContextClass.getDeclaredMethod("getContextPath");
|
||||
getContextPath.setAccessible(true);
|
||||
return (String) getContextPath.invoke(servletContext);
|
||||
}
|
||||
return null;
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.FINEST, "getContextPath", t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Client monitoring is OFF by default because there is
|
||||
* no standard stub.close() method. Therefore people do
|
||||
* not typically close a stub when they are done with it
|
||||
* (even though the RI does provide a .close).
|
||||
* <pre>
|
||||
* prop | no assert | assert/no mon | assert/mon off | assert/mon on
|
||||
* -------------------------------------------------------------------
|
||||
* not set | off | off | off | on
|
||||
* false | off | off | off | off
|
||||
* true | on | on | off | on
|
||||
* </pre>
|
||||
*/
|
||||
@NotNull public ManagedObjectManager createManagedObjectManager(final Stub stub) {
|
||||
EndpointAddress ea = stub.requestContext.getEndpointAddress();
|
||||
if (ea == null) {
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
|
||||
String rootName = ea.toString();
|
||||
|
||||
final ManagedClientAssertion assertion =
|
||||
ManagedClientAssertion.getAssertion(stub.getPortInfo());
|
||||
if (assertion != null) {
|
||||
final String id = assertion.getId();
|
||||
if (id != null) {
|
||||
rootName = id;
|
||||
}
|
||||
if (assertion.monitoringAttribute() == Setting.OFF) {
|
||||
return disabled("This client", rootName);
|
||||
} else if (assertion.monitoringAttribute() == Setting.ON &&
|
||||
clientMonitoring != Setting.OFF) {
|
||||
return createMOMLoop(rootName, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (clientMonitoring == Setting.NOT_SET ||
|
||||
clientMonitoring == Setting.OFF)
|
||||
{
|
||||
return disabled("Global client", rootName);
|
||||
}
|
||||
return createMOMLoop(rootName, 0);
|
||||
}
|
||||
|
||||
@NotNull private ManagedObjectManager disabled(final String x, final String rootName) {
|
||||
final String msg = x + " monitoring disabled. " + rootName + " will not be monitored";
|
||||
logger.log(Level.CONFIG, msg);
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
|
||||
private @NotNull ManagedObjectManager createMOMLoop(final String rootName, final int unique) {
|
||||
final boolean isFederated = AMXGlassfish.getGlassfishVersion() != null;
|
||||
ManagedObjectManager mom = createMOM(isFederated);
|
||||
mom = initMOM(mom);
|
||||
mom = createRoot(mom, rootName, unique);
|
||||
return mom;
|
||||
}
|
||||
|
||||
private @NotNull ManagedObjectManager createMOM(final boolean isFederated) {
|
||||
try {
|
||||
return new RewritingMOM(isFederated ?
|
||||
ManagedObjectManagerFactory.createFederated(
|
||||
AMXGlassfish.DEFAULT.serverMon(AMXGlassfish.DEFAULT.dasName()))
|
||||
:
|
||||
ManagedObjectManagerFactory.createStandalone("com.sun.metro"));
|
||||
} catch (Throwable t) {
|
||||
if (isFederated) {
|
||||
logger.log(Level.CONFIG, "Problem while attempting to federate with GlassFish AMX monitoring. Trying standalone.", t);
|
||||
return createMOM(false);
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @NotNull ManagedObjectManager initMOM(final ManagedObjectManager mom) {
|
||||
try {
|
||||
if (typelibDebug != -1) {
|
||||
mom.setTypelibDebug(typelibDebug);
|
||||
}
|
||||
if (registrationDebug.equals("FINE")) {
|
||||
mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.FINE);
|
||||
} else if (registrationDebug.equals("NORMAL")) {
|
||||
mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NORMAL);
|
||||
} else {
|
||||
mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NONE);
|
||||
}
|
||||
|
||||
mom.setRuntimeDebug(runtimeDebug);
|
||||
|
||||
// Instead of GMBAL throwing an exception and logging
|
||||
// duplicate name, just have it return null.
|
||||
mom.suppressDuplicateRootReport(true);
|
||||
|
||||
mom.stripPrefix(
|
||||
"com.sun.xml.internal.ws.server",
|
||||
"com.sun.xml.internal.ws.rx.rm.runtime.sequence");
|
||||
|
||||
// Add annotations to a standard class
|
||||
mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(ManagedData.class));
|
||||
mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(Description.class));
|
||||
mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(InheritedAttributes.class));
|
||||
|
||||
// Defer so we can register "this" as root from
|
||||
// within constructor.
|
||||
mom.suspendJMXRegistration();
|
||||
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
mom.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
|
||||
}
|
||||
logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
return mom;
|
||||
}
|
||||
|
||||
private ManagedObjectManager createRoot(final ManagedObjectManager mom, final String rootName, int unique) {
|
||||
final String name = rootName + (unique == 0 ? "" : "-" + String.valueOf(unique));
|
||||
try {
|
||||
final Object ignored = mom.createRoot(this, name);
|
||||
if (ignored != null) {
|
||||
ObjectName ignoredName = mom.getObjectName(mom.getRoot());
|
||||
// The name is null when the MOM is a NOOP.
|
||||
if (ignoredName != null) {
|
||||
logger.log(Level.INFO, "Metro monitoring rootname successfully set to: {0}", ignoredName);
|
||||
}
|
||||
return mom;
|
||||
}
|
||||
try {
|
||||
mom.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
|
||||
}
|
||||
final String basemsg ="Duplicate Metro monitoring rootname: " + name + " : ";
|
||||
if (unique > maxUniqueEndpointRootNameRetries) {
|
||||
final String msg = basemsg + "Giving up.";
|
||||
logger.log(Level.INFO, msg);
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
final String msg = basemsg + "Will try to make unique";
|
||||
logger.log(Level.CONFIG, msg);
|
||||
return createMOMLoop(rootName, ++unique);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.WARNING, "Error while creating monitoring root with name: " + rootName, t);
|
||||
return ManagedObjectManagerFactory.createNOOP();
|
||||
}
|
||||
}
|
||||
|
||||
private static Setting clientMonitoring = Setting.NOT_SET;
|
||||
private static Setting endpointMonitoring = Setting.NOT_SET;
|
||||
private static int typelibDebug = -1;
|
||||
private static String registrationDebug = "NONE";
|
||||
private static boolean runtimeDebug = false;
|
||||
private static int maxUniqueEndpointRootNameRetries = 100;
|
||||
private static final String monitorProperty = "com.sun.xml.internal.ws.monitoring.";
|
||||
|
||||
private static Setting propertyToSetting(String propName) {
|
||||
String s = System.getProperty(propName);
|
||||
if (s == null) {
|
||||
return Setting.NOT_SET;
|
||||
}
|
||||
s = s.toLowerCase();
|
||||
if (s.equals("false") || s.equals("off")) {
|
||||
return Setting.OFF;
|
||||
} else if (s.equals("true") || s.equals("on")) {
|
||||
return Setting.ON;
|
||||
}
|
||||
return Setting.NOT_SET;
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
endpointMonitoring = propertyToSetting(monitorProperty + "endpoint");
|
||||
|
||||
clientMonitoring = propertyToSetting(monitorProperty + "client");
|
||||
|
||||
Integer i = Integer.getInteger(monitorProperty + "typelibDebug");
|
||||
if (i != null) {
|
||||
typelibDebug = i;
|
||||
}
|
||||
|
||||
String s = System.getProperty(monitorProperty + "registrationDebug");
|
||||
if (s != null) {
|
||||
registrationDebug = s.toUpperCase();
|
||||
}
|
||||
|
||||
s = System.getProperty(monitorProperty + "runtimeDebug");
|
||||
if (s != null && s.toLowerCase().equals("true")) {
|
||||
runtimeDebug = true;
|
||||
}
|
||||
|
||||
i = Integer.getInteger(monitorProperty + "maxUniqueEndpointRootNameRetries");
|
||||
if (i != null) {
|
||||
maxUniqueEndpointRootNameRetries = i;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Error while reading monitoring properties", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This enables us to annotate the WebServiceFeature class even thought
|
||||
// we can't explicitly put the annotations in the class itself.
|
||||
@ManagedData
|
||||
@Description("WebServiceFeature")
|
||||
@InheritedAttributes({
|
||||
@InheritedAttribute(methodName="getID", description="unique id for this feature"),
|
||||
@InheritedAttribute(methodName="isEnabled", description="true if this feature is enabled")
|
||||
})
|
||||
interface DummyWebServiceFeature {}
|
||||
|
||||
class RewritingMOM implements ManagedObjectManager
|
||||
{
|
||||
private final ManagedObjectManager mom;
|
||||
|
||||
private final static String gmbalQuotingCharsRegex = "\n|\\|\"|\\*|\\?|:|=|,";
|
||||
private final static String replacementChar = "-";
|
||||
|
||||
RewritingMOM(final ManagedObjectManager mom) { this.mom = mom; }
|
||||
|
||||
private String rewrite(final String x) {
|
||||
return x.replaceAll(gmbalQuotingCharsRegex, replacementChar);
|
||||
}
|
||||
|
||||
// The interface
|
||||
|
||||
@Override public void suspendJMXRegistration() { mom.suspendJMXRegistration(); }
|
||||
@Override public void resumeJMXRegistration() { mom.resumeJMXRegistration(); }
|
||||
@Override public GmbalMBean createRoot() { return mom.createRoot(); }
|
||||
@Override public GmbalMBean createRoot(Object root) { return mom.createRoot(root); }
|
||||
@Override public GmbalMBean createRoot(Object root, String name) {
|
||||
return mom.createRoot(root, rewrite(name));
|
||||
}
|
||||
@Override public Object getRoot() { return mom.getRoot(); }
|
||||
@Override public GmbalMBean register(Object parent, Object obj, String name) {
|
||||
return mom.register(parent, obj, rewrite(name));
|
||||
}
|
||||
@Override public GmbalMBean register(Object parent, Object obj) { return mom.register(parent, obj);}
|
||||
@Override public GmbalMBean registerAtRoot(Object obj, String name) {
|
||||
return mom.registerAtRoot(obj, rewrite(name));
|
||||
}
|
||||
@Override public GmbalMBean registerAtRoot(Object obj) { return mom.registerAtRoot(obj); }
|
||||
@Override public void unregister(Object obj) { mom.unregister(obj); }
|
||||
@Override public ObjectName getObjectName(Object obj) { return mom.getObjectName(obj); }
|
||||
@Override public AMXClient getAMXClient(Object obj) { return mom.getAMXClient(obj); }
|
||||
@Override public Object getObject(ObjectName oname) { return mom.getObject(oname); }
|
||||
@Override public void stripPrefix(String... str) { mom.stripPrefix(str); }
|
||||
@Override public void stripPackagePrefix() { mom.stripPackagePrefix(); }
|
||||
@Override public String getDomain() { return mom.getDomain(); }
|
||||
@Override public void setMBeanServer(MBeanServer server){mom.setMBeanServer(server); }
|
||||
@Override public MBeanServer getMBeanServer() { return mom.getMBeanServer(); }
|
||||
@Override public void setResourceBundle(ResourceBundle rb) { mom.setResourceBundle(rb); }
|
||||
@Override public ResourceBundle getResourceBundle() { return mom.getResourceBundle(); }
|
||||
@Override public void addAnnotation(AnnotatedElement element, Annotation annotation) { mom.addAnnotation(element, annotation); }
|
||||
@Override public void setRegistrationDebug(RegistrationDebugLevel level) { mom.setRegistrationDebug(level); }
|
||||
@Override public void setRuntimeDebug(boolean flag) { mom.setRuntimeDebug(flag); }
|
||||
@Override public void setTypelibDebug(int level) { mom.setTypelibDebug(level); }
|
||||
@Override public String dumpSkeleton(Object obj) { return mom.dumpSkeleton(obj); }
|
||||
@Override public void suppressDuplicateRootReport(boolean suppressReport) { mom.suppressDuplicateRootReport(suppressReport); }
|
||||
@Override public void close() throws IOException { mom.close(); }
|
||||
@Override public void setJMXRegistrationDebug(boolean x) { mom.setJMXRegistrationDebug(x); }
|
||||
@Override public boolean isManagedObject(Object x) { return mom.isManagedObject(x); }
|
||||
}
|
||||
|
||||
// End of file.
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.BindingID;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.EndpointAddress;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.server.*;
|
||||
import com.sun.xml.internal.ws.transport.http.HttpAdapter;
|
||||
import com.sun.xml.internal.ws.util.RuntimeVersion;
|
||||
import com.sun.org.glassfish.gmbal.AMXMetadata;
|
||||
import com.sun.org.glassfish.gmbal.Description;
|
||||
import com.sun.org.glassfish.gmbal.ManagedAttribute;
|
||||
import com.sun.org.glassfish.gmbal.ManagedObject;
|
||||
import java.net.URL;
|
||||
import javax.xml.namespace.QName;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Harold Carr
|
||||
*/
|
||||
@ManagedObject
|
||||
@Description("Metro Web Service endpoint")
|
||||
@AMXMetadata(type="WSEndpoint")
|
||||
public final class MonitorRootService extends MonitorBase {
|
||||
|
||||
private final WSEndpoint endpoint;
|
||||
|
||||
MonitorRootService(final WSEndpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
//
|
||||
// Items from WSEndpoint
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Policy associated with Endpoint")
|
||||
public String policy() {
|
||||
return endpoint.getPolicyMap() != null ?
|
||||
endpoint.getPolicyMap().toString() : null;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Container")
|
||||
public @NotNull Container container() {
|
||||
return endpoint.getContainer();
|
||||
}
|
||||
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Port name")
|
||||
public @NotNull QName portName() {
|
||||
return endpoint.getPortName();
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Service name")
|
||||
public @NotNull QName serviceName() {
|
||||
return endpoint.getServiceName();
|
||||
}
|
||||
|
||||
//
|
||||
// Items from WSBinding
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Binding SOAP Version")
|
||||
public String soapVersionHttpBindingId() {
|
||||
return endpoint.getBinding().getSOAPVersion().httpBindingId;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Binding Addressing Version")
|
||||
public AddressingVersion addressingVersion() {
|
||||
return endpoint.getBinding().getAddressingVersion();
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Binding Identifier")
|
||||
public @NotNull BindingID bindingID() {
|
||||
return endpoint.getBinding().getBindingId();
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Binding features")
|
||||
public @NotNull WSFeatureList features() {
|
||||
return endpoint.getBinding().getFeatures();
|
||||
}
|
||||
|
||||
//
|
||||
// Items from WSDLPort
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("WSDLPort bound port type")
|
||||
public QName wsdlPortTypeName() {
|
||||
return endpoint.getPort() != null ?
|
||||
endpoint.getPort().getBinding().getPortTypeName() : null;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Endpoint address")
|
||||
public EndpointAddress wsdlEndpointAddress() {
|
||||
return endpoint.getPort() != null ?
|
||||
endpoint.getPort().getAddress() : null;
|
||||
}
|
||||
|
||||
//
|
||||
// Items from ServiceDefinition
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Documents referenced")
|
||||
public Set<String> serviceDefinitionImports() {
|
||||
return endpoint.getServiceDefinition() != null ?
|
||||
endpoint.getServiceDefinition().getPrimary().getImports() : null;
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("System ID where document is taken from")
|
||||
public URL serviceDefinitionURL() {
|
||||
return endpoint.getServiceDefinition() != null ?
|
||||
endpoint.getServiceDefinition().getPrimary().getURL() : null;
|
||||
}
|
||||
|
||||
//
|
||||
// Items from SEIModel
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("SEI model WSDL location")
|
||||
public String seiModelWSDLLocation() {
|
||||
return endpoint.getSEIModel() != null ?
|
||||
endpoint.getSEIModel().getWSDLLocation() : null;
|
||||
}
|
||||
|
||||
//
|
||||
// Items from RuntimeVersion
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("JAX-WS runtime version")
|
||||
public String jaxwsRuntimeVersion() {
|
||||
return RuntimeVersion.VERSION.toString();
|
||||
}
|
||||
|
||||
//
|
||||
// Items from HttpAdapter
|
||||
//
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("If true: show what goes across HTTP transport")
|
||||
public boolean dumpHTTPMessages() { return HttpAdapter.dump; }
|
||||
|
||||
|
||||
@ManagedAttribute
|
||||
@Description("Show what goes across HTTP transport")
|
||||
public void dumpHTTPMessages(final boolean x) { HttpAdapter.setDump(x); }
|
||||
|
||||
}
|
||||
|
||||
// End of file.
|
||||
392
jdkSrc/jdk8/com/sun/xml/internal/ws/server/SDDocumentImpl.java
Normal file
392
jdkSrc/jdk8/com/sun/xml/internal/ws/server/SDDocumentImpl.java
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.Nullable;
|
||||
import com.sun.xml.internal.ws.api.server.*;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.wsdl.SDDocumentResolver;
|
||||
import com.sun.xml.internal.ws.util.RuntimeVersion;
|
||||
import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter;
|
||||
import com.sun.xml.internal.ws.wsdl.parser.ParserUtil;
|
||||
import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
|
||||
import com.sun.xml.internal.ws.wsdl.writer.DocumentLocationResolver;
|
||||
import com.sun.xml.internal.ws.wsdl.writer.WSDLPatcher;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.*;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@link SDDocument} implmentation.
|
||||
*
|
||||
* <p>
|
||||
* This extends from {@link SDDocumentSource} so that
|
||||
* JAX-WS server runtime code can use {@link SDDocument}
|
||||
* as {@link SDDocumentSource}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class SDDocumentImpl extends SDDocumentSource implements SDDocument {
|
||||
|
||||
private static final String NS_XSD = "http://www.w3.org/2001/XMLSchema";
|
||||
private static final QName SCHEMA_INCLUDE_QNAME = new QName(NS_XSD, "include");
|
||||
private static final QName SCHEMA_IMPORT_QNAME = new QName(NS_XSD, "import");
|
||||
private static final QName SCHEMA_REDEFINE_QNAME = new QName(NS_XSD, "redefine");
|
||||
private static final String VERSION_COMMENT =
|
||||
" Published by JAX-WS RI (http://jax-ws.java.net). RI's version is "+RuntimeVersion.VERSION+". ";
|
||||
|
||||
private final QName rootName;
|
||||
private final SDDocumentSource source;
|
||||
|
||||
/**
|
||||
* Set when {@link ServiceDefinitionImpl} is constructed.
|
||||
*/
|
||||
@Nullable List<SDDocumentFilter> filters;
|
||||
@Nullable SDDocumentResolver sddocResolver;
|
||||
|
||||
|
||||
/**
|
||||
* The original system ID of this document.
|
||||
*
|
||||
* When this document contains relative references to other resources,
|
||||
* this field is used to find which {@link com.sun.xml.internal.ws.server.SDDocumentImpl} it refers to.
|
||||
*
|
||||
* Must not be null.
|
||||
*/
|
||||
private final URL url;
|
||||
private final Set<String> imports;
|
||||
|
||||
/**
|
||||
* Creates {@link SDDocument} from {@link SDDocumentSource}.
|
||||
* @param src WSDL document infoset
|
||||
* @param serviceName wsdl:service name
|
||||
* @param portTypeName
|
||||
* The information about the port of {@link WSEndpoint} to which this document is built for.
|
||||
* These values are used to determine which document is the concrete and abstract WSDLs
|
||||
* for this endpoint.
|
||||
*
|
||||
* @return null
|
||||
* Always non-null.
|
||||
*/
|
||||
public static SDDocumentImpl create(SDDocumentSource src, QName serviceName, QName portTypeName) {
|
||||
URL systemId = src.getSystemId();
|
||||
|
||||
try {
|
||||
// RuntimeWSDLParser parser = new RuntimeWSDLParser(null);
|
||||
XMLStreamReader reader = src.read();
|
||||
try {
|
||||
XMLStreamReaderUtil.nextElementContent(reader);
|
||||
|
||||
QName rootName = reader.getName();
|
||||
if(rootName.equals(WSDLConstants.QNAME_SCHEMA)) {
|
||||
String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS);
|
||||
Set<String> importedDocs = new HashSet<String>();
|
||||
while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) {
|
||||
if (reader.getEventType() != XMLStreamConstants.START_ELEMENT)
|
||||
continue;
|
||||
QName name = reader.getName();
|
||||
if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) ||
|
||||
SCHEMA_REDEFINE_QNAME.equals(name)) {
|
||||
String importedDoc = reader.getAttributeValue(null, "schemaLocation");
|
||||
if (importedDoc != null) {
|
||||
importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new SchemaImpl(rootName,systemId,src,tns,importedDocs);
|
||||
} else if (rootName.equals(WSDLConstants.QNAME_DEFINITIONS)) {
|
||||
String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS);
|
||||
|
||||
boolean hasPortType = false;
|
||||
boolean hasService = false;
|
||||
Set<String> importedDocs = new HashSet<String>();
|
||||
Set<QName> allServices = new HashSet<QName>();
|
||||
|
||||
// if WSDL, parse more
|
||||
while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) {
|
||||
if(reader.getEventType() != XMLStreamConstants.START_ELEMENT)
|
||||
continue;
|
||||
|
||||
QName name = reader.getName();
|
||||
if (WSDLConstants.QNAME_PORT_TYPE.equals(name)) {
|
||||
String pn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME);
|
||||
if (portTypeName != null) {
|
||||
if(portTypeName.getLocalPart().equals(pn)&&portTypeName.getNamespaceURI().equals(tns)) {
|
||||
hasPortType = true;
|
||||
}
|
||||
}
|
||||
} else if (WSDLConstants.QNAME_SERVICE.equals(name)) {
|
||||
String sn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME);
|
||||
QName sqn = new QName(tns,sn);
|
||||
allServices.add(sqn);
|
||||
if(serviceName.equals(sqn)) {
|
||||
hasService = true;
|
||||
}
|
||||
} else if (WSDLConstants.QNAME_IMPORT.equals(name)) {
|
||||
String importedDoc = reader.getAttributeValue(null, "location");
|
||||
if (importedDoc != null) {
|
||||
importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
|
||||
}
|
||||
} else if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) ||
|
||||
SCHEMA_REDEFINE_QNAME.equals(name)) {
|
||||
String importedDoc = reader.getAttributeValue(null, "schemaLocation");
|
||||
if (importedDoc != null) {
|
||||
importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new WSDLImpl(
|
||||
rootName,systemId,src,tns,hasPortType,hasService,importedDocs,allServices);
|
||||
} else {
|
||||
return new SDDocumentImpl(rootName,systemId,src);
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} catch (WebServiceException e) {
|
||||
throw new ServerRtException("runtime.parser.wsdl", systemId,e);
|
||||
} catch (IOException e) {
|
||||
throw new ServerRtException("runtime.parser.wsdl", systemId,e);
|
||||
} catch (XMLStreamException e) {
|
||||
throw new ServerRtException("runtime.parser.wsdl", systemId,e);
|
||||
}
|
||||
}
|
||||
|
||||
protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source) {
|
||||
this(rootName, url, source, new HashSet<String>());
|
||||
}
|
||||
|
||||
protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source, Set<String> imports) {
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException("Cannot construct SDDocument with null URL.");
|
||||
}
|
||||
this.rootName = rootName;
|
||||
this.source = source;
|
||||
this.url = url;
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
void setFilters(List<SDDocumentFilter> filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
|
||||
void setResolver(SDDocumentResolver sddocResolver) {
|
||||
this.sddocResolver = sddocResolver;
|
||||
}
|
||||
|
||||
public QName getRootName() {
|
||||
return rootName;
|
||||
}
|
||||
|
||||
public boolean isWSDL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSchema() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException {
|
||||
return source.read(xif);
|
||||
}
|
||||
|
||||
public XMLStreamReader read() throws IOException, XMLStreamException {
|
||||
return source.read();
|
||||
}
|
||||
|
||||
public URL getSystemId() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Set<String> getImports() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream os) throws IOException {
|
||||
XMLStreamWriter w = null;
|
||||
try {
|
||||
//generate the WSDL with utf-8 encoding and XML version 1.0
|
||||
w = XMLStreamWriterFactory.create(os, "UTF-8");
|
||||
w.writeStartDocument("UTF-8", "1.0");
|
||||
new XMLStreamReaderToXMLStreamWriter().bridge(source.read(), w);
|
||||
w.writeEndDocument();
|
||||
} catch (XMLStreamException e) {
|
||||
IOException ioe = new IOException(e.getMessage());
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
} finally {
|
||||
try {
|
||||
if (w != null)
|
||||
w.close();
|
||||
} catch (XMLStreamException e) {
|
||||
IOException ioe = new IOException(e.getMessage());
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, OutputStream os) throws IOException {
|
||||
XMLStreamWriter w = null;
|
||||
try {
|
||||
//generate the WSDL with utf-8 encoding and XML version 1.0
|
||||
w = XMLStreamWriterFactory.create(os, "UTF-8");
|
||||
w.writeStartDocument("UTF-8", "1.0");
|
||||
writeTo(portAddressResolver,resolver,w);
|
||||
w.writeEndDocument();
|
||||
} catch (XMLStreamException e) {
|
||||
IOException ioe = new IOException(e.getMessage());
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
} finally {
|
||||
try {
|
||||
if (w != null)
|
||||
w.close();
|
||||
} catch (XMLStreamException e) {
|
||||
IOException ioe = new IOException(e.getMessage());
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, XMLStreamWriter out) throws XMLStreamException, IOException {
|
||||
if (filters != null) {
|
||||
for (SDDocumentFilter f : filters) {
|
||||
out = f.filter(this,out);
|
||||
}
|
||||
}
|
||||
|
||||
XMLStreamReader xsr = source.read();
|
||||
try {
|
||||
out.writeComment(VERSION_COMMENT);
|
||||
new WSDLPatcher(portAddressResolver, new DocumentLocationResolverImpl(resolver)).bridge(xsr,out);
|
||||
} finally {
|
||||
xsr.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link SDDocument.Schema} implementation.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
private static final class SchemaImpl extends SDDocumentImpl implements SDDocument.Schema {
|
||||
private final String targetNamespace;
|
||||
|
||||
public SchemaImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace,
|
||||
Set<String> imports) {
|
||||
super(rootName, url, source, imports);
|
||||
this.targetNamespace = targetNamespace;
|
||||
}
|
||||
|
||||
public String getTargetNamespace() {
|
||||
return targetNamespace;
|
||||
}
|
||||
|
||||
public boolean isSchema() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class WSDLImpl extends SDDocumentImpl implements SDDocument.WSDL {
|
||||
private final String targetNamespace;
|
||||
private final boolean hasPortType;
|
||||
private final boolean hasService;
|
||||
private final Set<QName> allServices;
|
||||
|
||||
public WSDLImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace, boolean hasPortType,
|
||||
boolean hasService, Set<String> imports,Set<QName> allServices) {
|
||||
super(rootName, url, source, imports);
|
||||
this.targetNamespace = targetNamespace;
|
||||
this.hasPortType = hasPortType;
|
||||
this.hasService = hasService;
|
||||
this.allServices = allServices;
|
||||
}
|
||||
|
||||
public String getTargetNamespace() {
|
||||
return targetNamespace;
|
||||
}
|
||||
|
||||
public boolean hasPortType() {
|
||||
return hasPortType;
|
||||
}
|
||||
|
||||
public boolean hasService() {
|
||||
return hasService;
|
||||
}
|
||||
|
||||
public Set<QName> getAllServices() {
|
||||
return allServices;
|
||||
}
|
||||
|
||||
public boolean isWSDL() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class DocumentLocationResolverImpl implements DocumentLocationResolver {
|
||||
private DocumentAddressResolver delegate;
|
||||
|
||||
DocumentLocationResolverImpl(DocumentAddressResolver delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public String getLocationFor(String namespaceURI, String systemId) {
|
||||
if (sddocResolver == null) {
|
||||
return systemId;
|
||||
}
|
||||
try {
|
||||
URL ref = new URL(getURL(), systemId);
|
||||
SDDocument refDoc = sddocResolver.resolve(ref.toExternalForm());
|
||||
if (refDoc == null)
|
||||
return systemId; // not something we know. just leave it as is.
|
||||
|
||||
return delegate.getRelativeAddressFor(SDDocumentImpl.this, refDoc);
|
||||
} catch (MalformedURLException mue) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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;
|
||||
|
||||
/**
|
||||
* @author Vivek Pandey
|
||||
*
|
||||
* Defines server side constants
|
||||
*
|
||||
*/
|
||||
public interface ServerPropertyConstants {
|
||||
/*public static final String ATTACHMENT_CONTEXT =
|
||||
"com.sun.xml.internal.ws.attachment.AttachmentContext";*/
|
||||
public static final String SET_ATTACHMENT_PROPERTY =
|
||||
"com.sun.xml.internal.ws.attachment.SetAttachmentContext";
|
||||
public static final String GET_ATTACHMENT_PROPERTY =
|
||||
"com.sun.xml.internal.ws.attachment.GetAttachmentContext";
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.localization.Localizable;
|
||||
import com.sun.xml.internal.ws.util.exception.JAXWSExceptionBase;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ServerRtException extends JAXWSExceptionBase {
|
||||
|
||||
public ServerRtException(String key, Object... args) {
|
||||
super(key, args);
|
||||
}
|
||||
|
||||
public ServerRtException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
public ServerRtException(Localizable arg) {
|
||||
super("server.rt.err", arg);
|
||||
}
|
||||
|
||||
public String getDefaultResourceBundleName() {
|
||||
return "com.sun.xml.internal.ws.resources.server";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.SEIModel;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.NextAction;
|
||||
import com.sun.xml.internal.ws.api.pipe.Tube;
|
||||
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
|
||||
import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.util.pipe.AbstractSchemaValidationTube;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.Validator;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* {@link Tube} that does the schema validation on the server side.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class ServerSchemaValidationTube extends AbstractSchemaValidationTube {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ServerSchemaValidationTube.class.getName());
|
||||
|
||||
private final Schema schema;
|
||||
private final Validator validator;
|
||||
|
||||
private final boolean noValidation;
|
||||
private final SEIModel seiModel;
|
||||
private final WSDLPort wsdlPort;
|
||||
|
||||
public ServerSchemaValidationTube(WSEndpoint endpoint, WSBinding binding,
|
||||
SEIModel seiModel, WSDLPort wsdlPort, Tube next) {
|
||||
super(binding, next);
|
||||
this.seiModel = seiModel;
|
||||
this.wsdlPort = wsdlPort;
|
||||
|
||||
if (endpoint.getServiceDefinition() != null) {
|
||||
MetadataResolverImpl mdresolver = new MetadataResolverImpl(endpoint.getServiceDefinition());
|
||||
Source[] sources = getSchemaSources(endpoint.getServiceDefinition(), mdresolver);
|
||||
for(Source source : sources) {
|
||||
LOGGER.fine("Constructing service validation schema from = "+source.getSystemId());
|
||||
//printDOM((DOMSource)source);
|
||||
}
|
||||
if (sources.length != 0) {
|
||||
noValidation = false;
|
||||
sf.setResourceResolver(mdresolver);
|
||||
try {
|
||||
schema = sf.newSchema(sources);
|
||||
} catch(SAXException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
validator = schema.newValidator();
|
||||
return;
|
||||
}
|
||||
}
|
||||
noValidation = true;
|
||||
schema = null;
|
||||
validator = null;
|
||||
}
|
||||
|
||||
protected Validator getValidator() {
|
||||
return validator;
|
||||
}
|
||||
|
||||
protected boolean isNoValidation() {
|
||||
return noValidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextAction processRequest(Packet request) {
|
||||
if (isNoValidation() || !feature.isInbound() || !request.getMessage().hasPayload() || request.getMessage().isFault()) {
|
||||
return super.processRequest(request);
|
||||
}
|
||||
try {
|
||||
doProcess(request);
|
||||
} catch(SAXException se) {
|
||||
LOGGER.log(Level.WARNING, "Client Request doesn't pass Service's Schema Validation", se);
|
||||
// Client request is invalid. So sending specific fault code
|
||||
// Also converting this to fault message so that handlers may get
|
||||
// to see the message.
|
||||
SOAPVersion soapVersion = binding.getSOAPVersion();
|
||||
Message faultMsg = SOAPFaultBuilder.createSOAPFaultMessage(
|
||||
soapVersion, null, se, soapVersion.faultCodeClient);
|
||||
return doReturnWith(request.createServerResponse(faultMsg,
|
||||
wsdlPort, seiModel, binding));
|
||||
}
|
||||
return super.processRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextAction processResponse(Packet response) {
|
||||
if (isNoValidation() || !feature.isOutbound() || response.getMessage() == null || !response.getMessage().hasPayload() || response.getMessage().isFault()) {
|
||||
return super.processResponse(response);
|
||||
}
|
||||
try {
|
||||
doProcess(response);
|
||||
} catch(SAXException se) {
|
||||
// TODO: Should we convert this to fault Message ??
|
||||
throw new WebServiceException(se);
|
||||
}
|
||||
return super.processResponse(response);
|
||||
}
|
||||
|
||||
protected ServerSchemaValidationTube(ServerSchemaValidationTube that, TubeCloner cloner) {
|
||||
super(that,cloner);
|
||||
//this.docs = that.docs;
|
||||
this.schema = that.schema; // Schema is thread-safe
|
||||
this.validator = schema.newValidator();
|
||||
this.noValidation = that.noValidation;
|
||||
this.seiModel = that.seiModel;
|
||||
this.wsdlPort = that.wsdlPort;
|
||||
}
|
||||
|
||||
public AbstractTubeImpl copy(TubeCloner cloner) {
|
||||
return new ServerSchemaValidationTube(this,cloner);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.server.SDDocument;
|
||||
import com.sun.xml.internal.ws.api.server.SDDocumentFilter;
|
||||
import com.sun.xml.internal.ws.api.server.ServiceDefinition;
|
||||
import com.sun.xml.internal.ws.wsdl.SDDocumentResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link ServiceDefinition} implementation.
|
||||
*
|
||||
* <p>
|
||||
* You construct a {@link ServiceDefinitionImpl} by first constructing
|
||||
* a list of {@link SDDocumentImpl}s.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class ServiceDefinitionImpl implements ServiceDefinition, SDDocumentResolver {
|
||||
private final List<SDDocumentImpl> docs;
|
||||
|
||||
private final Map<String,SDDocumentImpl> bySystemId;
|
||||
private final @NotNull SDDocumentImpl primaryWsdl;
|
||||
|
||||
/**
|
||||
* Set when {@link WSEndpointImpl} is created.
|
||||
*/
|
||||
/*package*/ WSEndpointImpl<?> owner;
|
||||
|
||||
/*package*/ final List<SDDocumentFilter> filters = new ArrayList<SDDocumentFilter>();
|
||||
|
||||
/**
|
||||
* @param docs
|
||||
* List of {@link SDDocumentImpl}s to form the description.
|
||||
* There must be at least one entry.
|
||||
* The first document is considered {@link #getPrimary() primary}.
|
||||
*/
|
||||
public ServiceDefinitionImpl(List<SDDocumentImpl> docs, @NotNull SDDocumentImpl primaryWsdl) {
|
||||
assert docs.contains(primaryWsdl);
|
||||
this.docs = docs;
|
||||
this.primaryWsdl = primaryWsdl;
|
||||
|
||||
this.bySystemId = new HashMap<String, SDDocumentImpl>(docs.size());
|
||||
for (SDDocumentImpl doc : docs) {
|
||||
bySystemId.put(doc.getURL().toExternalForm(),doc);
|
||||
doc.setFilters(filters);
|
||||
doc.setResolver(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The owner is set when {@link WSEndpointImpl} is created.
|
||||
*/
|
||||
/*package*/ void setOwner(WSEndpointImpl<?> owner) {
|
||||
assert owner!=null && this.owner==null;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public @NotNull SDDocument getPrimary() {
|
||||
return primaryWsdl;
|
||||
}
|
||||
|
||||
public void addFilter(SDDocumentFilter filter) {
|
||||
filters.add(filter);
|
||||
}
|
||||
|
||||
public Iterator<SDDocument> iterator() {
|
||||
return (Iterator)docs.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link SDDocumentImpl} whose {@link SDDocumentImpl#getURL()}
|
||||
* returns the specified value.
|
||||
*
|
||||
* @return
|
||||
* null if none is found.
|
||||
*/
|
||||
public SDDocument resolve(String systemId) {
|
||||
return bySystemId.get(systemId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.server.AbstractInstanceResolver;
|
||||
import com.sun.xml.internal.ws.api.server.InstanceResolver;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.api.server.WSWebServiceContext;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
/**
|
||||
* {@link InstanceResolver} that always returns a single instance.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class SingletonResolver<T> extends AbstractInstanceResolver<T> {
|
||||
private final @NotNull T singleton;
|
||||
|
||||
public SingletonResolver(@NotNull T singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
public @NotNull T resolve(Packet request) {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public void start(WSWebServiceContext wsc, WSEndpoint endpoint) {
|
||||
getResourceInjector(endpoint).inject(wsc,singleton);
|
||||
// notify that we are ready to serve
|
||||
invokeMethod(findAnnotatedMethod(singleton.getClass(),PostConstruct.class),singleton);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
invokeMethod(findAnnotatedMethod(singleton.getClass(),PreDestroy.class),singleton);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.ws.util.exception.JAXWSExceptionBase;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link Codec} throws this exception when it doesn't understand request message's
|
||||
* Content-Type
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class UnsupportedMediaException extends JAXWSExceptionBase {
|
||||
|
||||
public UnsupportedMediaException( @NotNull String contentType, List<String> expectedContentTypes) {
|
||||
super(ServerMessages.localizableUNSUPPORTED_CONTENT_TYPE(contentType, expectedContentTypes));
|
||||
}
|
||||
|
||||
public UnsupportedMediaException() {
|
||||
super(ServerMessages.localizableNO_CONTENT_TYPE());
|
||||
}
|
||||
|
||||
public UnsupportedMediaException(String charset) {
|
||||
super(ServerMessages.localizableUNSUPPORTED_CHARSET(charset));
|
||||
}
|
||||
|
||||
public String getDefaultResourceBundleName() {
|
||||
return "com.sun.xml.internal.ws.resources.server";
|
||||
}
|
||||
|
||||
}
|
||||
196
jdkSrc/jdk8/com/sun/xml/internal/ws/server/WSDLGenResolver.java
Normal file
196
jdkSrc/jdk8/com/sun/xml/internal/ws/server/WSDLGenResolver.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.xml.internal.stream.buffer.MutableXMLStreamBuffer;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult;
|
||||
import com.sun.xml.internal.ws.api.server.SDDocument;
|
||||
import com.sun.xml.internal.ws.api.server.SDDocumentSource;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* WSDLGenerator uses WSDLResolver while creating WSDL artifacts. WSDLResolver
|
||||
* is used to control the file names and which artifact to be generated or not.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
final class WSDLGenResolver implements com.oracle.webservices.internal.api.databinding.WSDLResolver {
|
||||
|
||||
private final List<SDDocumentImpl> docs;
|
||||
private final List<SDDocumentSource> newDocs = new ArrayList<SDDocumentSource>();
|
||||
private SDDocumentSource concreteWsdlSource;
|
||||
|
||||
private SDDocumentImpl abstractWsdl;
|
||||
private SDDocumentImpl concreteWsdl;
|
||||
|
||||
/**
|
||||
* targetNS -> schema documents.
|
||||
*/
|
||||
private final Map<String, List<SDDocumentImpl>> nsMapping = new HashMap<String,List<SDDocumentImpl>>();
|
||||
|
||||
private final QName serviceName;
|
||||
private final QName portTypeName;
|
||||
|
||||
public WSDLGenResolver(@NotNull List<SDDocumentImpl> docs,QName serviceName,QName portTypeName) {
|
||||
this.docs = docs;
|
||||
this.serviceName = serviceName;
|
||||
this.portTypeName = portTypeName;
|
||||
|
||||
for (SDDocumentImpl doc : docs) {
|
||||
if(doc.isWSDL()) {
|
||||
SDDocument.WSDL wsdl = (SDDocument.WSDL) doc;
|
||||
if(wsdl.hasPortType())
|
||||
abstractWsdl = doc;
|
||||
}
|
||||
if(doc.isSchema()) {
|
||||
SDDocument.Schema schema = (SDDocument.Schema) doc;
|
||||
List<SDDocumentImpl> sysIds = nsMapping.get(schema.getTargetNamespace());
|
||||
if (sysIds == null) {
|
||||
sysIds = new ArrayList<SDDocumentImpl>();
|
||||
nsMapping.put(schema.getTargetNamespace(), sysIds);
|
||||
}
|
||||
sysIds.add(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the concrete WSDL that contains service element.
|
||||
*
|
||||
* @return Result the generated concrete WSDL
|
||||
*/
|
||||
public Result getWSDL(String filename) {
|
||||
URL url = createURL(filename);
|
||||
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
|
||||
xsb.setSystemId(url.toExternalForm());
|
||||
concreteWsdlSource = SDDocumentSource.create(url,xsb);
|
||||
newDocs.add(concreteWsdlSource);
|
||||
XMLStreamBufferResult r = new XMLStreamBufferResult(xsb);
|
||||
r.setSystemId(filename);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* At present, it returns file URL scheme eventhough there is no resource
|
||||
* in the filesystem.
|
||||
*
|
||||
* @return URL of the generated document
|
||||
*
|
||||
*/
|
||||
private URL createURL(String filename) {
|
||||
try {
|
||||
return new URL("file:///"+filename);
|
||||
} catch (MalformedURLException e) {
|
||||
// TODO: I really don't think this is the right way to handle this error,
|
||||
// WSDLResolver needs to be documented carefully.
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates filename if the suggested filename need to be changed in
|
||||
* wsdl:import. If the metadata already contains abstract wsdl(i.e. a WSDL
|
||||
* which has the porttype), then the abstract wsdl shouldn't be generated
|
||||
*
|
||||
* return null if abstract WSDL need not be generated
|
||||
* Result the abstract WSDL
|
||||
*/
|
||||
public Result getAbstractWSDL(Holder<String> filename) {
|
||||
if (abstractWsdl != null) {
|
||||
filename.value = abstractWsdl.getURL().toString();
|
||||
return null; // Don't generate abstract WSDL
|
||||
}
|
||||
URL url = createURL(filename.value);
|
||||
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
|
||||
xsb.setSystemId(url.toExternalForm());
|
||||
SDDocumentSource abstractWsdlSource = SDDocumentSource.create(url,xsb);
|
||||
newDocs.add(abstractWsdlSource);
|
||||
XMLStreamBufferResult r = new XMLStreamBufferResult(xsb);
|
||||
r.setSystemId(filename.value);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates filename if the suggested filename need to be changed in
|
||||
* xsd:import. If there is already a schema document for the namespace
|
||||
* in the metadata, then it is not generated.
|
||||
*
|
||||
* return null if schema need not be generated
|
||||
* Result the generated schema document
|
||||
*/
|
||||
public Result getSchemaOutput(String namespace, Holder<String> filename) {
|
||||
List<SDDocumentImpl> schemas = nsMapping.get(namespace);
|
||||
if (schemas != null) {
|
||||
if (schemas.size() > 1) {
|
||||
throw new ServerRtException("server.rt.err",
|
||||
"More than one schema for the target namespace "+namespace);
|
||||
}
|
||||
filename.value = schemas.get(0).getURL().toExternalForm();
|
||||
return null; // Don't generate schema
|
||||
}
|
||||
|
||||
URL url = createURL(filename.value);
|
||||
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
|
||||
xsb.setSystemId(url.toExternalForm());
|
||||
SDDocumentSource sd = SDDocumentSource.create(url,xsb);
|
||||
newDocs.add(sd);
|
||||
|
||||
XMLStreamBufferResult r = new XMLStreamBufferResult(xsb);
|
||||
r.setSystemId(filename.value);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts SDDocumentSource to SDDocumentImpl and updates original docs. It
|
||||
* categories the generated documents into WSDL, Schema types.
|
||||
*
|
||||
* @return the primary WSDL
|
||||
* null if it is not there in the generated documents
|
||||
*
|
||||
*/
|
||||
public SDDocumentImpl updateDocs() {
|
||||
for (SDDocumentSource doc : newDocs) {
|
||||
SDDocumentImpl docImpl = SDDocumentImpl.create(doc,serviceName,portTypeName);
|
||||
if (doc == concreteWsdlSource) {
|
||||
concreteWsdl = docImpl;
|
||||
}
|
||||
docs.add(docImpl);
|
||||
}
|
||||
return concreteWsdl;
|
||||
}
|
||||
|
||||
}
|
||||
698
jdkSrc/jdk8/com/sun/xml/internal/ws/server/WSEndpointImpl.java
Normal file
698
jdkSrc/jdk8/com/sun/xml/internal/ws/server/WSEndpointImpl.java
Normal file
@@ -0,0 +1,698 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.ws.addressing.EPRSDDocumentFilter;
|
||||
import com.sun.xml.internal.ws.addressing.WSEPRExtension;
|
||||
import com.sun.xml.internal.ws.api.Component;
|
||||
import com.sun.xml.internal.ws.api.ComponentFeature;
|
||||
import com.sun.xml.internal.ws.api.ComponentsFeature;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
|
||||
import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.SEIModel;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.*;
|
||||
import com.sun.xml.internal.ws.api.server.*;
|
||||
import com.sun.xml.internal.ws.binding.BindingImpl;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties;
|
||||
import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties;
|
||||
import com.sun.xml.internal.ws.model.wsdl.WSDLProperties;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.resources.HandlerMessages;
|
||||
import com.sun.xml.internal.ws.util.Pool;
|
||||
import com.sun.xml.internal.ws.util.Pool.TubePool;
|
||||
import com.sun.xml.internal.ws.util.ServiceFinder;
|
||||
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
|
||||
import com.sun.org.glassfish.gmbal.ManagedObjectManager;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.ws.EndpointReference;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.handler.Handler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
/**
|
||||
* {@link WSEndpoint} implementation.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public /*final*/ class WSEndpointImpl<T> extends WSEndpoint<T> implements LazyMOMProvider.WSEndpointScopeChangeListener {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
|
||||
|
||||
private final @NotNull QName serviceName;
|
||||
private final @NotNull QName portName;
|
||||
protected final WSBinding binding;
|
||||
private final SEIModel seiModel;
|
||||
private final @NotNull Container container;
|
||||
private final WSDLPort port;
|
||||
|
||||
protected final Tube masterTubeline;
|
||||
private final ServiceDefinitionImpl serviceDef;
|
||||
private final SOAPVersion soapVersion;
|
||||
private final Engine engine;
|
||||
private final @NotNull Codec masterCodec;
|
||||
private final @NotNull PolicyMap endpointPolicy;
|
||||
private final Pool<Tube> tubePool;
|
||||
private final OperationDispatcher operationDispatcher;
|
||||
private @NotNull ManagedObjectManager managedObjectManager;
|
||||
private boolean managedObjectManagerClosed = false;
|
||||
private final Object managedObjectManagerLock = new Object();
|
||||
private LazyMOMProvider.Scope lazyMOMProviderScope = LazyMOMProvider.Scope.STANDALONE;
|
||||
private final @NotNull ServerTubeAssemblerContext context;
|
||||
|
||||
private Map<QName, WSEndpointReference.EPRExtension> endpointReferenceExtensions = new HashMap<QName, WSEndpointReference.EPRExtension>();
|
||||
/**
|
||||
* Set to true once we start shutting down this endpoint. Used to avoid
|
||||
* running the clean up processing twice.
|
||||
*
|
||||
* @see #dispose()
|
||||
*/
|
||||
private boolean disposed;
|
||||
private final Class<T> implementationClass;
|
||||
private final @NotNull
|
||||
WSDLProperties wsdlProperties;
|
||||
private final Set<Component> componentRegistry = new CopyOnWriteArraySet<Component>();
|
||||
|
||||
protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding,
|
||||
Container container, SEIModel seiModel, WSDLPort port,
|
||||
Class<T> implementationClass,
|
||||
@Nullable ServiceDefinitionImpl serviceDef,
|
||||
EndpointAwareTube terminalTube, boolean isSynchronous,
|
||||
PolicyMap endpointPolicy) {
|
||||
this.serviceName = serviceName;
|
||||
this.portName = portName;
|
||||
this.binding = binding;
|
||||
this.soapVersion = binding.getSOAPVersion();
|
||||
this.container = container;
|
||||
this.port = port;
|
||||
this.implementationClass = implementationClass;
|
||||
this.serviceDef = serviceDef;
|
||||
this.seiModel = seiModel;
|
||||
this.endpointPolicy = endpointPolicy;
|
||||
|
||||
LazyMOMProvider.INSTANCE.registerEndpoint(this);
|
||||
initManagedObjectManager();
|
||||
|
||||
if (serviceDef != null) {
|
||||
serviceDef.setOwner(this);
|
||||
}
|
||||
|
||||
ComponentFeature cf = binding.getFeature(ComponentFeature.class);
|
||||
if (cf != null) {
|
||||
switch (cf.getTarget()) {
|
||||
case ENDPOINT:
|
||||
componentRegistry.add(cf.getComponent());
|
||||
break;
|
||||
case CONTAINER:
|
||||
container.getComponents().add(cf.getComponent());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
ComponentsFeature csf = binding.getFeature(ComponentsFeature.class);
|
||||
if (csf != null) {
|
||||
for (ComponentFeature cfi : csf.getComponentFeatures()) {
|
||||
switch (cfi.getTarget()) {
|
||||
case ENDPOINT:
|
||||
componentRegistry.add(cfi.getComponent());
|
||||
break;
|
||||
case CONTAINER:
|
||||
container.getComponents().add(cfi.getComponent());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TubelineAssembler assembler = TubelineAssemblerFactory.create(
|
||||
Thread.currentThread().getContextClassLoader(), binding.getBindingId(), container);
|
||||
assert assembler != null;
|
||||
|
||||
this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel);
|
||||
|
||||
context = createServerTubeAssemblerContext(terminalTube, isSynchronous);
|
||||
this.masterTubeline = assembler.createServer(context);
|
||||
|
||||
Codec c = context.getCodec();
|
||||
if (c instanceof EndpointAwareCodec) {
|
||||
// create a copy to avoid sharing the codec between multiple endpoints
|
||||
c = c.copy();
|
||||
((EndpointAwareCodec) c).setEndpoint(this);
|
||||
}
|
||||
this.masterCodec = c;
|
||||
|
||||
tubePool = new TubePool(masterTubeline);
|
||||
terminalTube.setEndpoint(this);
|
||||
engine = new Engine(toString(), container);
|
||||
wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel);
|
||||
|
||||
Map<QName, WSEndpointReference.EPRExtension> eprExtensions = new HashMap<QName, WSEndpointReference.EPRExtension>();
|
||||
try {
|
||||
if (port != null) {
|
||||
//gather EPR extrensions from WSDL Model
|
||||
WSEndpointReference wsdlEpr = port.getEPR();
|
||||
if (wsdlEpr != null) {
|
||||
for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) {
|
||||
eprExtensions.put(extnEl.getQName(), extnEl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EndpointReferenceExtensionContributor[] eprExtnContributors = ServiceFinder.find(EndpointReferenceExtensionContributor.class).toArray();
|
||||
for(EndpointReferenceExtensionContributor eprExtnContributor :eprExtnContributors) {
|
||||
WSEndpointReference.EPRExtension wsdlEPRExtn = eprExtensions.remove(eprExtnContributor.getQName());
|
||||
WSEndpointReference.EPRExtension endpointEprExtn = eprExtnContributor.getEPRExtension(this,wsdlEPRExtn);
|
||||
if (endpointEprExtn != null) {
|
||||
eprExtensions.put(endpointEprExtn.getQName(), endpointEprExtn);
|
||||
}
|
||||
}
|
||||
for (WSEndpointReference.EPRExtension extn : eprExtensions.values()) {
|
||||
endpointReferenceExtensions.put(extn.getQName(), new WSEPRExtension(
|
||||
XMLStreamBuffer.createNewBufferFromXMLStreamReader(extn.readAsXMLStreamReader()),extn.getQName()));
|
||||
}
|
||||
} catch (XMLStreamException ex) {
|
||||
throw new WebServiceException(ex);
|
||||
}
|
||||
if(!eprExtensions.isEmpty()) {
|
||||
serviceDef.addFilter(new EPRSDDocumentFilter(this));
|
||||
}
|
||||
}
|
||||
|
||||
protected ServerTubeAssemblerContext createServerTubeAssemblerContext(
|
||||
EndpointAwareTube terminalTube, boolean isSynchronous) {
|
||||
ServerTubeAssemblerContext ctx = new ServerPipeAssemblerContext(
|
||||
seiModel, port, this, terminalTube, isSynchronous);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding, Container container,
|
||||
SEIModel seiModel, WSDLPort port,
|
||||
Tube masterTubeline) {
|
||||
this.serviceName = serviceName;
|
||||
this.portName = portName;
|
||||
this.binding = binding;
|
||||
this.soapVersion = binding.getSOAPVersion();
|
||||
this.container = container;
|
||||
this.endpointPolicy = null;
|
||||
this.port = port;
|
||||
this.seiModel = seiModel;
|
||||
this.serviceDef = null;
|
||||
this.implementationClass = null;
|
||||
this.masterTubeline = masterTubeline;
|
||||
this.masterCodec = ((BindingImpl) this.binding).createCodec();
|
||||
|
||||
LazyMOMProvider.INSTANCE.registerEndpoint(this);
|
||||
initManagedObjectManager();
|
||||
|
||||
this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel);
|
||||
this.context = new ServerPipeAssemblerContext(
|
||||
seiModel, port, this, null /* not known */, false);
|
||||
|
||||
tubePool = new TubePool(masterTubeline);
|
||||
engine = new Engine(toString(), container);
|
||||
wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel);
|
||||
}
|
||||
|
||||
public Collection<WSEndpointReference.EPRExtension> getEndpointReferenceExtensions() {
|
||||
return endpointReferenceExtensions.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Nullable when there is no associated WSDL Model
|
||||
* @return
|
||||
*/
|
||||
public @Nullable OperationDispatcher getOperationDispatcher() {
|
||||
return operationDispatcher;
|
||||
}
|
||||
|
||||
public PolicyMap getPolicyMap() {
|
||||
return endpointPolicy;
|
||||
}
|
||||
|
||||
public @NotNull Class<T> getImplementationClass() {
|
||||
return implementationClass;
|
||||
}
|
||||
|
||||
public @NotNull WSBinding getBinding() {
|
||||
return binding;
|
||||
}
|
||||
|
||||
public @NotNull Container getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public WSDLPort getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable SEIModel getSEIModel() {
|
||||
return seiModel;
|
||||
}
|
||||
|
||||
public void setExecutor(Executor exec) {
|
||||
engine.setExecutor(exec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Engine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void schedule(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
|
||||
processAsync(request, callback, interceptor, true);
|
||||
}
|
||||
|
||||
private void processAsync(final Packet request,
|
||||
final CompletionCallback callback,
|
||||
FiberContextSwitchInterceptor interceptor, boolean schedule) {
|
||||
Container old = ContainerResolver.getDefault().enterContainer(container);
|
||||
try {
|
||||
request.endpoint = WSEndpointImpl.this;
|
||||
request.addSatellite(wsdlProperties);
|
||||
|
||||
Fiber fiber = engine.createFiber();
|
||||
fiber.setDeliverThrowableInPacket(true);
|
||||
if (interceptor != null) {
|
||||
fiber.addInterceptor(interceptor);
|
||||
}
|
||||
final Tube tube = tubePool.take();
|
||||
Fiber.CompletionCallback cbak = new Fiber.CompletionCallback() {
|
||||
public void onCompletion(@NotNull Packet response) {
|
||||
ThrowableContainerPropertySet tc = response.getSatellite(ThrowableContainerPropertySet.class);
|
||||
if (tc == null) {
|
||||
// Only recycle tubes in non-exception path as some Tubes may be
|
||||
// in invalid state following exception
|
||||
tubePool.recycle(tube);
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
if (tc != null) {
|
||||
response = createServiceResponseForException(tc,
|
||||
response,
|
||||
soapVersion,
|
||||
request.endpoint.getPort(),
|
||||
null,
|
||||
request.endpoint.getBinding());
|
||||
}
|
||||
callback.onCompletion(response);
|
||||
}
|
||||
}
|
||||
|
||||
public void onCompletion(@NotNull Throwable error) {
|
||||
// will never be called now that we are using
|
||||
// fiber.setDeliverThrowableInPacket(true);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
};
|
||||
|
||||
fiber.start(tube, request, cbak,
|
||||
binding.isFeatureEnabled(SyncStartForAsyncFeature.class)
|
||||
|| !schedule);
|
||||
} finally {
|
||||
ContainerResolver.getDefault().exitContainer(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet createServiceResponseForException(final ThrowableContainerPropertySet tc,
|
||||
final Packet responsePacket,
|
||||
final SOAPVersion soapVersion,
|
||||
final WSDLPort wsdlPort,
|
||||
final SEIModel seiModel,
|
||||
final WSBinding binding)
|
||||
{
|
||||
// This will happen in addressing if it is enabled.
|
||||
if (tc.isFaultCreated()) return responsePacket;
|
||||
|
||||
final Message faultMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, tc.getThrowable());
|
||||
final Packet result = responsePacket.createServerResponse(faultMessage, wsdlPort, seiModel, binding);
|
||||
// Pass info to upper layers
|
||||
tc.setFaultMessage(faultMessage);
|
||||
tc.setResponsePacket(responsePacket);
|
||||
tc.setFaultCreated(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
|
||||
processAsync(request, callback, interceptor, false);
|
||||
}
|
||||
|
||||
public @NotNull
|
||||
PipeHead createPipeHead() {
|
||||
return new PipeHead() {
|
||||
private final Tube tube = TubeCloner.clone(masterTubeline);
|
||||
|
||||
public @NotNull
|
||||
Packet process(Packet request, WebServiceContextDelegate wscd,
|
||||
TransportBackChannel tbc) {
|
||||
Container old = ContainerResolver.getDefault().enterContainer(container);
|
||||
try {
|
||||
request.webServiceContextDelegate = wscd;
|
||||
request.transportBackChannel = tbc;
|
||||
request.endpoint = WSEndpointImpl.this;
|
||||
request.addSatellite(wsdlProperties);
|
||||
|
||||
Fiber fiber = engine.createFiber();
|
||||
Packet response;
|
||||
try {
|
||||
response = fiber.runSync(tube, request);
|
||||
} catch (RuntimeException re) {
|
||||
// Catch all runtime exceptions so that transport
|
||||
// doesn't
|
||||
// have to worry about converting to wire message
|
||||
// TODO XML/HTTP binding
|
||||
Message faultMsg = SOAPFaultBuilder
|
||||
.createSOAPFaultMessage(soapVersion, null, re);
|
||||
response = request.createServerResponse(faultMsg,
|
||||
request.endpoint.getPort(), null,
|
||||
request.endpoint.getBinding());
|
||||
}
|
||||
return response;
|
||||
} finally {
|
||||
ContainerResolver.getDefault().exitContainer(old);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
disposed = true;
|
||||
|
||||
masterTubeline.preDestroy();
|
||||
|
||||
for (Handler handler : binding.getHandlerChain()) {
|
||||
for (Method method : handler.getClass().getMethods()) {
|
||||
if (method.getAnnotation(PreDestroy.class) == null) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
method.invoke(handler);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, HandlerMessages.HANDLER_PREDESTROY_IGNORE(e.getMessage()), e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
closeManagedObjectManager();
|
||||
LazyMOMProvider.INSTANCE.unregisterEndpoint(this);
|
||||
}
|
||||
|
||||
public ServiceDefinitionImpl getServiceDefinition() {
|
||||
return serviceDef;
|
||||
}
|
||||
|
||||
public Set<EndpointComponent> getComponentRegistry() {
|
||||
Set<EndpointComponent> sec = new EndpointComponentSet();
|
||||
for (Component c : componentRegistry) {
|
||||
sec.add(c instanceof EndpointComponentWrapper ?
|
||||
((EndpointComponentWrapper) c).component :
|
||||
new ComponentWrapper(c));
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
private class EndpointComponentSet extends HashSet<EndpointComponent> {
|
||||
|
||||
@Override
|
||||
public Iterator<EndpointComponent> iterator() {
|
||||
final Iterator<EndpointComponent> it = super.iterator();
|
||||
return new Iterator<EndpointComponent>() {
|
||||
private EndpointComponent last = null;
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
public EndpointComponent next() {
|
||||
last = it.next();
|
||||
return last;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
it.remove();
|
||||
if (last != null) {
|
||||
componentRegistry.remove(last instanceof ComponentWrapper ?
|
||||
((ComponentWrapper) last).component :
|
||||
new EndpointComponentWrapper(last));
|
||||
}
|
||||
last = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(EndpointComponent e) {
|
||||
boolean result = super.add(e);
|
||||
if (result) {
|
||||
componentRegistry.add(new EndpointComponentWrapper(e));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
boolean result = super.remove(o);
|
||||
if (result) {
|
||||
componentRegistry.remove(o instanceof ComponentWrapper ?
|
||||
((ComponentWrapper) o).component :
|
||||
new EndpointComponentWrapper((EndpointComponent)o));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ComponentWrapper implements EndpointComponent {
|
||||
private final Component component;
|
||||
|
||||
public ComponentWrapper(Component component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public <S> S getSPI(Class<S> spiType) {
|
||||
return component.getSPI(spiType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return component.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return component.equals(obj);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EndpointComponentWrapper implements Component {
|
||||
private final EndpointComponent component;
|
||||
|
||||
public EndpointComponentWrapper(EndpointComponent component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public <S> S getSPI(Class<S> spiType) {
|
||||
return component.getSPI(spiType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return component.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return component.equals(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<Component> getComponents() {
|
||||
return componentRegistry;
|
||||
}
|
||||
|
||||
public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, String address, String wsdlAddress, Element... referenceParameters) {
|
||||
List<Element> refParams = null;
|
||||
if (referenceParameters != null) {
|
||||
refParams = Arrays.asList(referenceParameters);
|
||||
}
|
||||
return getEndpointReference(clazz, address, wsdlAddress, null, refParams);
|
||||
}
|
||||
|
||||
public <T extends EndpointReference> T getEndpointReference(Class<T> clazz,
|
||||
String address, String wsdlAddress, List<Element> metadata,
|
||||
List<Element> referenceParameters) {
|
||||
QName portType = null;
|
||||
if (port != null) {
|
||||
portType = port.getBinding().getPortTypeName();
|
||||
}
|
||||
|
||||
AddressingVersion av = AddressingVersion.fromSpecClass(clazz);
|
||||
return new WSEndpointReference(
|
||||
av, address, serviceName, portName, portType, metadata, wsdlAddress, referenceParameters, endpointReferenceExtensions.values(), null).toSpec(clazz);
|
||||
|
||||
}
|
||||
|
||||
public @NotNull QName getPortName() {
|
||||
return portName;
|
||||
}
|
||||
|
||||
|
||||
public @NotNull Codec createCodec() {
|
||||
return masterCodec.copy();
|
||||
}
|
||||
|
||||
public @NotNull QName getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
private void initManagedObjectManager() {
|
||||
synchronized (managedObjectManagerLock) {
|
||||
if (managedObjectManager == null) {
|
||||
switch (this.lazyMOMProviderScope) {
|
||||
case GLASSFISH_NO_JMX:
|
||||
managedObjectManager = new WSEndpointMOMProxy(this);
|
||||
break;
|
||||
default:
|
||||
managedObjectManager = obtainManagedObjectManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull ManagedObjectManager getManagedObjectManager() {
|
||||
return managedObjectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a real instance of {@code ManagedObjectManager} class no matter what lazyMOMProviderScope is this endpoint in (or if the
|
||||
* Gmbal API calls should be deferred).
|
||||
*
|
||||
* @see com.sun.xml.internal.ws.api.server.LazyMOMProvider.Scope
|
||||
* @return an instance of {@code ManagedObjectManager}
|
||||
*/
|
||||
@NotNull ManagedObjectManager obtainManagedObjectManager() {
|
||||
final MonitorRootService monitorRootService = new MonitorRootService(this);
|
||||
final ManagedObjectManager mOM = monitorRootService.createManagedObjectManager(this);
|
||||
|
||||
// ManagedObjectManager was suspended due to root creation (see MonitorBase#initMOM)
|
||||
mOM.resumeJMXRegistration();
|
||||
|
||||
return mOM;
|
||||
}
|
||||
|
||||
public void scopeChanged(LazyMOMProvider.Scope scope) {
|
||||
synchronized (managedObjectManagerLock) {
|
||||
if (managedObjectManagerClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lazyMOMProviderScope = scope;
|
||||
|
||||
// possible lazyMOMProviderScope change can be LazyMOMProvider.Scope.GLASSFISH_NO_JMX or LazyMOMProvider.Scope.GLASSFISH_JMX
|
||||
if (managedObjectManager == null) {
|
||||
if (scope != LazyMOMProvider.Scope.GLASSFISH_NO_JMX) {
|
||||
managedObjectManager = obtainManagedObjectManager();
|
||||
} else {
|
||||
managedObjectManager = new WSEndpointMOMProxy(this);
|
||||
}
|
||||
} else {
|
||||
// if ManagedObjectManager for this endpoint has already been created and is uninitialized proxy then
|
||||
// fill it with a real instance
|
||||
if (managedObjectManager instanceof WSEndpointMOMProxy
|
||||
&& !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) {
|
||||
((WSEndpointMOMProxy)managedObjectManager).setManagedObjectManager(obtainManagedObjectManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
|
||||
|
||||
// This can be called independently of WSEndpoint.dispose.
|
||||
// Example: the WSCM framework calls this before dispose.
|
||||
@Override
|
||||
public void closeManagedObjectManager() {
|
||||
synchronized (managedObjectManagerLock) {
|
||||
if (managedObjectManagerClosed == true) {
|
||||
return;
|
||||
}
|
||||
if (managedObjectManager != null) {
|
||||
boolean close = true;
|
||||
|
||||
// ManagedObjectManager doesn't need to be closed because it exists only as a proxy
|
||||
if (managedObjectManager instanceof WSEndpointMOMProxy
|
||||
&& !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) {
|
||||
close = false;
|
||||
}
|
||||
|
||||
if (close) {
|
||||
try {
|
||||
final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot());
|
||||
// The name is null when the MOM is a NOOP.
|
||||
if (name != null) {
|
||||
monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name);
|
||||
}
|
||||
managedObjectManager.close();
|
||||
} catch (java.io.IOException e) {
|
||||
monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
managedObjectManagerClosed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull @Override ServerTubeAssemblerContext getAssemblerContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.SEIModel;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor;
|
||||
import com.sun.xml.internal.ws.api.pipe.ServerTubeAssemblerContext;
|
||||
import com.sun.xml.internal.ws.api.pipe.ThrowableContainerPropertySet;
|
||||
import com.sun.xml.internal.ws.api.server.Container;
|
||||
import com.sun.xml.internal.ws.api.server.ServiceDefinition;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.wsdl.OperationDispatcher;
|
||||
import com.sun.org.glassfish.gmbal.AMXClient;
|
||||
import com.sun.org.glassfish.gmbal.GmbalMBean;
|
||||
import com.sun.org.glassfish.gmbal.ManagedObjectManager;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.EndpointReference;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link ManagedObjectManager} proxy class for {@link WSEndpointImpl} instances that could be used when Gmbal API calls
|
||||
* need to be deferred. The proxy tries to defer a need of a real ManagedObjectManager instance to the time when any
|
||||
* method from {@link ManagedObjectManager} is invoked on it. In this case a real instance of ManagedObjectManager is
|
||||
* obtained from WSEndpointImpl and the method is rather invoked on this object.
|
||||
*/
|
||||
public class WSEndpointMOMProxy extends WSEndpoint implements ManagedObjectManager {
|
||||
|
||||
private final @NotNull
|
||||
WSEndpointImpl wsEndpoint;
|
||||
private ManagedObjectManager managedObjectManager;
|
||||
|
||||
WSEndpointMOMProxy(@NotNull WSEndpointImpl wsEndpoint) {
|
||||
this.wsEndpoint = wsEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a real instance of {@link ManagedObjectManager}
|
||||
*
|
||||
* @return an ManagedObjectManager instance
|
||||
*/
|
||||
@Override
|
||||
public ManagedObjectManager getManagedObjectManager() {
|
||||
if (managedObjectManager == null) {
|
||||
managedObjectManager = wsEndpoint.obtainManagedObjectManager();
|
||||
}
|
||||
return managedObjectManager;
|
||||
}
|
||||
|
||||
void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
|
||||
this.managedObjectManager = managedObjectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this proxy contains a reference to real ManagedObjectManager instance, {@code false}
|
||||
* otherwise.
|
||||
*
|
||||
* @return {@code true} if ManagedObjectManager has been created, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return this.managedObjectManager != null;
|
||||
}
|
||||
|
||||
public WSEndpointImpl getWsEndpoint() {
|
||||
return wsEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspendJMXRegistration() {
|
||||
getManagedObjectManager().suspendJMXRegistration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeJMXRegistration() {
|
||||
getManagedObjectManager().resumeJMXRegistration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isManagedObject(Object obj) {
|
||||
return getManagedObjectManager().isManagedObject(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean createRoot() {
|
||||
return getManagedObjectManager().createRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean createRoot(Object root) {
|
||||
return getManagedObjectManager().createRoot(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean createRoot(Object root, String name) {
|
||||
return getManagedObjectManager().createRoot(root, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return getManagedObjectManager().getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean register(Object parent, Object obj, String name) {
|
||||
return getManagedObjectManager().register(parent, obj, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean register(Object parent, Object obj) {
|
||||
return getManagedObjectManager().register(parent, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean registerAtRoot(Object obj, String name) {
|
||||
return getManagedObjectManager().registerAtRoot(obj, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GmbalMBean registerAtRoot(Object obj) {
|
||||
return getManagedObjectManager().registerAtRoot(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(Object obj) {
|
||||
getManagedObjectManager().unregister(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getObjectName(Object obj) {
|
||||
return getManagedObjectManager().getObjectName(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AMXClient getAMXClient(Object obj) {
|
||||
return getManagedObjectManager().getAMXClient(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(ObjectName oname) {
|
||||
return getManagedObjectManager().getObject(oname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stripPrefix(String... str) {
|
||||
getManagedObjectManager().stripPrefix(str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stripPackagePrefix() {
|
||||
getManagedObjectManager().stripPackagePrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return getManagedObjectManager().getDomain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMBeanServer(MBeanServer server) {
|
||||
getManagedObjectManager().setMBeanServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MBeanServer getMBeanServer() {
|
||||
return getManagedObjectManager().getMBeanServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceBundle(ResourceBundle rb) {
|
||||
getManagedObjectManager().setResourceBundle(rb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return getManagedObjectManager().getResourceBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAnnotation(AnnotatedElement element, Annotation annotation) {
|
||||
getManagedObjectManager().addAnnotation(element, annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationDebug(RegistrationDebugLevel level) {
|
||||
getManagedObjectManager().setRegistrationDebug(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRuntimeDebug(boolean flag) {
|
||||
getManagedObjectManager().setRuntimeDebug(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypelibDebug(int level) {
|
||||
getManagedObjectManager().setTypelibDebug(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJMXRegistrationDebug(boolean flag) {
|
||||
getManagedObjectManager().setJMXRegistrationDebug(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dumpSkeleton(Object obj) {
|
||||
return getManagedObjectManager().dumpSkeleton(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressDuplicateRootReport(boolean suppressReport) {
|
||||
getManagedObjectManager().suppressDuplicateRootReport(suppressReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
getManagedObjectManager().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalsProxiedInstance(WSEndpoint endpoint) {
|
||||
if (wsEndpoint == null) {
|
||||
return (endpoint == null);
|
||||
}
|
||||
return wsEndpoint.equals(endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createCodec() {
|
||||
return this.wsEndpoint.createCodec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QName getServiceName() {
|
||||
return this.wsEndpoint.getServiceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QName getPortName() {
|
||||
return this.wsEndpoint.getPortName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getImplementationClass() {
|
||||
return this.wsEndpoint.getImplementationClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WSBinding getBinding() {
|
||||
return this.wsEndpoint.getBinding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container getContainer() {
|
||||
return this.wsEndpoint.getContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WSDLPort getPort() {
|
||||
return this.wsEndpoint.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExecutor(Executor exec) {
|
||||
this.wsEndpoint.setExecutor(exec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void schedule(Packet request, CompletionCallback callback, FiberContextSwitchInterceptor interceptor) {
|
||||
this.wsEndpoint.schedule(request, callback, interceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PipeHead createPipeHead() {
|
||||
return this.wsEndpoint.createPipeHead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (this.wsEndpoint != null) {
|
||||
this.wsEndpoint.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceDefinition getServiceDefinition() {
|
||||
return this.wsEndpoint.getServiceDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set getComponentRegistry() {
|
||||
return this.wsEndpoint.getComponentRegistry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SEIModel getSEIModel() {
|
||||
return this.wsEndpoint.getSEIModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PolicyMap getPolicyMap() {
|
||||
return this.wsEndpoint.getPolicyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeManagedObjectManager() {
|
||||
this.wsEndpoint.closeManagedObjectManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerTubeAssemblerContext getAssemblerContext() {
|
||||
return this.wsEndpoint.getAssemblerContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndpointReference getEndpointReference(Class clazz, String address, String wsdlAddress, Element... referenceParameters) {
|
||||
return wsEndpoint.getEndpointReference(clazz, address, wsdlAddress, referenceParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndpointReference getEndpointReference(Class clazz, String address, String wsdlAddress, List metadata, List referenceParameters) {
|
||||
return wsEndpoint.getEndpointReference(clazz, address, wsdlAddress, metadata, referenceParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationDispatcher getOperationDispatcher() {
|
||||
return wsEndpoint.getOperationDispatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet createServiceResponseForException(final ThrowableContainerPropertySet tc,
|
||||
final Packet responsePacket,
|
||||
final SOAPVersion soapVersion,
|
||||
final WSDLPort wsdlPort,
|
||||
final SEIModel seiModel,
|
||||
final WSBinding binding)
|
||||
{
|
||||
return wsEndpoint.createServiceResponseForException(tc, responsePacket, soapVersion,
|
||||
wsdlPort, seiModel, binding);
|
||||
}
|
||||
}
|
||||
148
jdkSrc/jdk8/com/sun/xml/internal/ws/server/package-info.java
Normal file
148
jdkSrc/jdk8/com/sun/xml/internal/ws/server/package-info.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* <h1>JAX-WS 2.0.1 Server Runtime</h1>
|
||||
* <P>This document describes the architecture of server side
|
||||
* JAX-WS 2.0.1 runtime. </p>
|
||||
*
|
||||
* <h3>JAX-WS 2.0.1 Server Runtime Sequence Diagram</h3>
|
||||
|
||||
* <img src='../../../../../jaxws/basic-server.seq.png'>
|
||||
|
||||
*
|
||||
*
|
||||
* <H3>Message Flow</H3>
|
||||
* <P>A Web Service invocation starts with either the
|
||||
* {@link com.sun.xml.internal.ws.transport.http.servlet.WSServletDelegate WSServletDelegate}
|
||||
* or the {@link com.sun.xml.internal.ws.transport.http.server.ServerConnectionImpl ServerConnectionImpl}.
|
||||
* Both of these classes find the appropriate {@link com.sun.xml.internal.ws.server.RuntimeEndpointInfo RuntimeEndpointInfo}
|
||||
* and invokes the {@link com.sun.xml.internal.ws.server.Tie#handle(com.sun.xml.internal.ws.api.server.WSConnection,
|
||||
* com.sun.xml.internal.ws.spi.runtime.RuntimeEndpointInfo) Tie.handle}
|
||||
* method. This method first creates a {@link com.sun.pept.ept.MessageInfo MessageInfo}
|
||||
* used to gather inforrmation about the message to be received. A
|
||||
* {@link com.sun.xml.internal.ws.server.RuntimeContext RuntimeContext}
|
||||
* is then created with the MessageInfo and the {@link com.sun.xml.internal.ws.api.model.SEIModel RuntimeModel}
|
||||
* retrieved from the RuntimeEndpointInfo. The RuntimeContext is then
|
||||
* stored in the MessageInfo. The {@link com.sun.pept.ept.EPTFactory EPTFactory}
|
||||
* is retrieved from the {@link com.sun.xml.internal.ws.server.EPTFactoryFactoryBase EPTFactoryFactoryBase}
|
||||
* and also placed in the MessagInfo. A {@link com.sun.pept.protocol.MessageDispatcher MessageDispatcher}
|
||||
* is then created and the receive method is invoked. There will be two
|
||||
* types of MessageDispatchers for JAX-WS 2.0.1, SOAPMessageDispatcher
|
||||
* (one for client and one for the server) and an XMLMessageDispatcher
|
||||
* (one for the client and one for the server).</P>
|
||||
* <P>The MessageDispatcher.receive method orchestrates the receiving of
|
||||
* a Message. The SOAPMessageDispatcher first converts the MessageInfo
|
||||
* to a SOAPMessage. The SOAPMessageDispatcher then does mustUnderstand
|
||||
* processing followed by an invocation of any handlers. The SOAPMessage
|
||||
* is then converted to an InternalMessage and stored in the
|
||||
* MessageInfo. The converting of the SOAPMessage to an InternalMessage
|
||||
* is done using the decoder retrieved from the EPTFactory that is
|
||||
* contained in the MessageInfo. Once the SOAPMessage has been converted
|
||||
* to an InternalMessage the endpoint implementation is invoked via
|
||||
* reflection from the Method stored in the MessageInfo. The return
|
||||
* value of the method call is then stored in the InternalMessage. An
|
||||
* internalMessage is then created from the MessageInfo. The SOAPEncoder
|
||||
* is retrieved from the EPTFactory stored in the MessageInfo. The
|
||||
* SOAPEncoder.toSOAPMessage is then invoked to create a SOAPMessage
|
||||
* from the InternalMessage. A WSConnection is then retrieved from the
|
||||
* MessageInfo and the SOAPMessage is returned over that WSConnection.</P>
|
||||
* <P><BR>
|
||||
* </P>
|
||||
* <H3>External Interactions</H3>
|
||||
* <H4>SAAJ API</H4>
|
||||
* <UL>
|
||||
* <LI><P>JAX-WS creates SAAJ javax.xml.soap.SOAPMessage
|
||||
* from the HttpServletRequest.
|
||||
* At present, JAX-WS reads all the bytes from the request stream and
|
||||
* then creates SOAPMessage along with the HTTP headers.</P>
|
||||
* </UL>
|
||||
* <P>javax.xml.soap.MessageFactory(binding).createMessage(MimeHeaders, InputStream)</P>
|
||||
* <UL>
|
||||
* <LI><P>SOAPMessage parses the content from the stream including MIME
|
||||
* data</P>
|
||||
* <LI><P>com.sun.xml.internal.ws.server.SOAPMessageDispatcher::checkHeadersPeekBody()</P>
|
||||
* <P>SOAPMessage.getSOAPHeader() is used for mustUnderstand processing
|
||||
* of headers. It further uses
|
||||
* javax.xml.soap.SOAPHeader.examineMustUnderstandHeaderElements(role)</P>
|
||||
* <P>SOAPMessage.getSOAPBody().getFistChild() is used for guessing the
|
||||
* MEP of the request</P>
|
||||
* <LI><P>com.sun.xml.internal.ws.handler.HandlerChainCaller:insertFaultMessage()</P>
|
||||
* <P>SOAPMessage.getSOAPPart().getEnvelope() and some other SAAJ calls
|
||||
* are made to create a fault in the SOAPMessage</P>
|
||||
* <LI><P>com.sun.xml.internal.ws.handler.LogicalMessageImpl::getPayload()
|
||||
* interacts with SAAJ to get body from SOAPMessage</P>
|
||||
* <LI><P>com.sun.xml.internal.ws.encoding.soap.SOAPEncoder.toSOAPMessage(com.sun.xml.internal.ws.encoding.soap.internal.InternalMessage,
|
||||
* SOAPMessage). There is a scenario where there is SOAPMessage and a
|
||||
* logical handler sets payload as Source. To write to the stream,
|
||||
* SOAPMessage.writeTo() is used but before that the body needs to be
|
||||
* updated with logical handler' Source. Need to verify if this
|
||||
* scenario is still happening since Handler.close() is changed to take
|
||||
* MessageContext.</P>
|
||||
* <LI><P>com.sun.xml.internal.ws.handlerSOAPMessageContextImpl.getHeaders()
|
||||
* uses SAAJ API to get headers.</P>
|
||||
* <LI><P>SOAPMessage.writeTo() is used to write response. At present,
|
||||
* it writes into byte[] and this byte[] is written to
|
||||
* HttpServletResponse.</P>
|
||||
* </UL>
|
||||
* <H4>JAXB API</H4>
|
||||
* <P>JAX-WS RI uses the JAXB API to marshall/unmarshall user created
|
||||
* JAXB objects with user created {@link javax.xml.bind.JAXBContext JAXBContext}.
|
||||
* Handler, Dispatch in JAX-WS API provide ways for the user to specify his/her own
|
||||
* JAXBContext. {@link com.sun.xml.internal.ws.encoding.jaxb.JAXBTypeSerializer JAXBTypeSerializer} class uses all these methods.</P>
|
||||
* <UL>
|
||||
* <LI><p>{@link javax.xml.bind.Marshaller#marshal(Object,XMLStreamWriter) Marshaller.marshal(Object,XMLStreamWriter)}</p>
|
||||
* <LI><P>{@link javax.xml.bind.Marshaller#marshal(Object,Result) Marshaller.marshal(Object, DomResult)}</P>
|
||||
* <LI><P>{@link javax.xml.bind.Unmarshaller#unmarshal(XMLStreamReader) Object Unmarshaller.unmarshal(XMLStreamReader)}</P>
|
||||
* <LI><P>{@link javax.xml.bind.Unmarshaller#unmarshal(Source) Object Unmarshaller.unmarshal(Source)}</P>
|
||||
* </UL>
|
||||
* The following two JAXB classes are implemented by JAX-WS to enable/implement MTOM and XOP
|
||||
* <UL>
|
||||
* <LI><P>{@link javax.xml.bind.attachment.AttachmentMarshaller AttachmentMarshaller}</P>
|
||||
* <LI><P>{@link javax.xml.bind.attachment.AttachmentUnmarshaller AttachmentUnmarshaller}</P>
|
||||
* </UL>
|
||||
* <H4>JAXB Runtime-API (private contract)</H4>
|
||||
* <P>JAX-WS RI uses these private API for serialization/deserialization
|
||||
* purposes. This private API is used to serialize/deserialize method
|
||||
* parameters at the time of JAXBTypeSerializer class uses all
|
||||
* these methods.</P>
|
||||
* <UL>
|
||||
* <LI><P>{@link com.sun.xml.internal.bind.api.Bridge#marshal(BridgeContext, Object, XMLStreamWriter) Bridge.marshal(BridgeContext, Object, XMLStreamWriter)}</P>
|
||||
* <LI><P>{@link com.sun.xml.internal.bind.api.Bridge#marshal(BridgeContext, Object, Node) Bridge.marshal(BridgeContext, Object, Node)}</P>
|
||||
* <LI><P>{@link com.sun.xml.internal.bind.api.Bridge#unmarshal(BridgeContext, XMLStreamReader) Object Bridge.unmarshal(BridgeContext, XMLStreamReader)}</P>
|
||||
* </UL>
|
||||
*
|
||||
* @ArchitectureDocument
|
||||
**/
|
||||
package com.sun.xml.internal.ws.server;
|
||||
|
||||
import com.sun.xml.internal.bind.api.BridgeContext;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Result;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Fiber;
|
||||
import com.sun.xml.internal.ws.api.pipe.NextAction;
|
||||
import com.sun.xml.internal.ws.api.pipe.ThrowableContainerPropertySet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Tube;
|
||||
import com.sun.xml.internal.ws.api.server.AsyncProvider;
|
||||
import com.sun.xml.internal.ws.api.server.AsyncProviderCallback;
|
||||
import com.sun.xml.internal.ws.api.server.Invoker;
|
||||
import com.sun.xml.internal.ws.api.server.WSEndpoint;
|
||||
import com.sun.xml.internal.ws.server.AbstractWebServiceContext;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This {@link Tube} is used to invoke the {@link AsyncProvider} endpoints.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public // TODO needed by factory
|
||||
class AsyncProviderInvokerTube<T> extends ProviderInvokerTube<T> {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(
|
||||
com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.AsyncProviderInvokerTube");
|
||||
|
||||
public AsyncProviderInvokerTube(Invoker invoker, ProviderArgumentsBuilder<T> argsBuilder) {
|
||||
super(invoker, argsBuilder);
|
||||
}
|
||||
|
||||
/*
|
||||
* This binds the parameter for Provider endpoints and invokes the
|
||||
* invoke() method of {@linke Provider} endpoint. The return value from
|
||||
* invoke() is used to create a new {@link Message} that traverses
|
||||
* through the Pipeline to transport.
|
||||
*/
|
||||
public @NotNull NextAction processRequest(@NotNull Packet request) {
|
||||
T param = argsBuilder.getParameter(request);
|
||||
NoSuspendResumer resumer = new NoSuspendResumer();
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
AsyncProviderCallbackImpl callback = new AsyncProviderInvokerTube.AsyncProviderCallbackImpl(request, resumer);
|
||||
AsyncWebServiceContext ctxt = new AsyncWebServiceContext(getEndpoint(),request);
|
||||
|
||||
AsyncProviderInvokerTube.LOGGER.fine("Invoking AsyncProvider Endpoint");
|
||||
try {
|
||||
getInvoker(request).invokeAsyncProvider(request, param, callback, ctxt);
|
||||
} catch(Throwable e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
return doThrow(e);
|
||||
}
|
||||
|
||||
synchronized(callback) {
|
||||
if (resumer.response != null) {
|
||||
// Only used by AsyncProvider<Packet>
|
||||
// Implementation may pass Packet containing throwable; use both
|
||||
ThrowableContainerPropertySet tc = resumer.response.getSatellite(ThrowableContainerPropertySet.class);
|
||||
Throwable t = (tc != null) ? tc.getThrowable() : null;
|
||||
|
||||
return t != null ? doThrow(resumer.response, t) : doReturnWith(resumer.response);
|
||||
}
|
||||
|
||||
// Suspend the Fiber. AsyncProviderCallback will resume the Fiber after
|
||||
// it receives response.
|
||||
callback.resumer = new FiberResumer();
|
||||
return doSuspend();
|
||||
}
|
||||
}
|
||||
|
||||
private interface Resumer {
|
||||
public void onResume(Packet response);
|
||||
}
|
||||
|
||||
/*private*/ public class FiberResumer implements Resumer { // TODO public for DISI
|
||||
private final Fiber fiber;
|
||||
|
||||
public FiberResumer() {
|
||||
this.fiber = Fiber.current();
|
||||
}
|
||||
|
||||
public void onResume(Packet response) {
|
||||
// Only used by AsyncProvider<Packet>
|
||||
// Implementation may pass Packet containing throwable; use both
|
||||
ThrowableContainerPropertySet tc = response.getSatellite(ThrowableContainerPropertySet.class);
|
||||
Throwable t = (tc != null) ? tc.getThrowable() : null;
|
||||
fiber.resume(t, response);
|
||||
}
|
||||
}
|
||||
|
||||
private class NoSuspendResumer implements Resumer {
|
||||
protected Packet response = null;
|
||||
|
||||
public void onResume(Packet response) {
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
/*private*/ public class AsyncProviderCallbackImpl implements AsyncProviderCallback<T> { // TODO public for DISI
|
||||
private final Packet request;
|
||||
private Resumer resumer;
|
||||
|
||||
public AsyncProviderCallbackImpl(Packet request, Resumer resumer) {
|
||||
this.request = request;
|
||||
this.resumer = resumer;
|
||||
}
|
||||
|
||||
public void send(@Nullable T param) {
|
||||
if (param == null) {
|
||||
if (request.transportBackChannel != null) {
|
||||
request.transportBackChannel.close();
|
||||
}
|
||||
}
|
||||
Packet packet = argsBuilder.getResponse(request, param, getEndpoint().getPort(), getEndpoint().getBinding());
|
||||
synchronized(this) {
|
||||
resumer.onResume(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendError(@NotNull Throwable t) {
|
||||
Exception e;
|
||||
if (t instanceof Exception) {
|
||||
e = (Exception) t;
|
||||
} else {
|
||||
e = new RuntimeException(t);
|
||||
}
|
||||
Packet packet = argsBuilder.getResponse(request, e, getEndpoint().getPort(), getEndpoint().getBinding());
|
||||
synchronized(this) {
|
||||
resumer.onResume(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The single {@link javax.xml.ws.WebServiceContext} instance injected into application.
|
||||
*/
|
||||
/*private static final*/ public class AsyncWebServiceContext extends AbstractWebServiceContext { // TODO public for DISI
|
||||
final Packet packet;
|
||||
|
||||
public AsyncWebServiceContext(WSEndpoint endpoint, Packet packet) { // TODO public for DISI
|
||||
super(endpoint);
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public @NotNull Packet getRequestPacket() {
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull NextAction processResponse(@NotNull Packet response) {
|
||||
return doReturnWith(response);
|
||||
}
|
||||
|
||||
public @NotNull NextAction processException(@NotNull Throwable t) {
|
||||
return doThrow(t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class MessageProviderArgumentBuilder extends ProviderArgumentsBuilder<Message> {
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
public MessageProviderArgumentBuilder(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
/*protected*/ public Message getParameter(Packet packet) {
|
||||
return packet.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message getResponseMessage(Message returnValue) {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
|
||||
import javax.xml.ws.soap.SOAPBinding;
|
||||
|
||||
/**
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
|
||||
public // TODO need this in the factory
|
||||
abstract class ProviderArgumentsBuilder<T> {
|
||||
|
||||
/**
|
||||
* Creates a fault {@link Message} from method invocation's exception
|
||||
*/
|
||||
protected abstract Message getResponseMessage(Exception e);
|
||||
|
||||
/**
|
||||
* Creates {@link Message} from method invocation's return value
|
||||
*/
|
||||
protected Packet getResponse(Packet request, Exception e, WSDLPort port, WSBinding binding) {
|
||||
Message message = getResponseMessage(e);
|
||||
Packet response = request.createServerResponse(message,port,null,binding);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds {@link com.sun.xml.internal.ws.api.message.Message} to method invocation parameter
|
||||
* @param packet
|
||||
*/
|
||||
/*protected*/ public abstract T getParameter(Packet packet); // TODO public for DISI pluggable Provider
|
||||
|
||||
protected abstract Message getResponseMessage(T returnValue);
|
||||
|
||||
/**
|
||||
* Creates {@link Packet} from method invocation's return value
|
||||
*/
|
||||
protected Packet getResponse(Packet request, @Nullable T returnValue, WSDLPort port, WSBinding binding) {
|
||||
Message message = null;
|
||||
if (returnValue != null) {
|
||||
message = getResponseMessage(returnValue);
|
||||
}
|
||||
Packet response = request.createServerResponse(message,port,null,binding);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static ProviderArgumentsBuilder<?> create(ProviderEndpointModel model, WSBinding binding) {
|
||||
if (model.datatype == Packet.class)
|
||||
return new PacketProviderArgumentsBuilder(binding.getSOAPVersion());
|
||||
return (binding instanceof SOAPBinding) ? SOAPProviderArgumentBuilder.create(model, binding.getSOAPVersion())
|
||||
: XMLProviderArgumentBuilder.createBuilder(model, binding);
|
||||
}
|
||||
|
||||
private static class PacketProviderArgumentsBuilder extends ProviderArgumentsBuilder<Packet> {
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
public PacketProviderArgumentsBuilder(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
// Will be called by AsyncProviderCallbackImpl.sendError
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
/*protected*/ public Packet getParameter(Packet packet) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message getResponseMessage(Packet returnValue) {
|
||||
// Should never be called
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Packet getResponse(Packet request, @Nullable Packet returnValue, WSDLPort port, WSBinding binding) {
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.server.AsyncProvider;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingHelper;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Provider;
|
||||
import javax.xml.ws.Service;
|
||||
import javax.xml.ws.ServiceMode;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.soap.SOAPBinding;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
/**
|
||||
* Keeps the runtime information like Service.Mode and erasure of Provider class
|
||||
* about Provider endpoint. It proccess annotations to find about Service.Mode
|
||||
* It also finds about parameterized type(e.g. Source, SOAPMessage, DataSource)
|
||||
* of endpoint class.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class ProviderEndpointModel<T> {
|
||||
/**
|
||||
* True if this is {@link AsyncProvider}.
|
||||
*/
|
||||
final boolean isAsync;
|
||||
|
||||
/**
|
||||
* In which mode does this provider operate?
|
||||
*/
|
||||
@NotNull final Service.Mode mode;
|
||||
/**
|
||||
* T of {@link Provider}<T>.
|
||||
*/
|
||||
@NotNull final Class datatype;
|
||||
/**
|
||||
* User class that extends {@link Provider}.
|
||||
*/
|
||||
@NotNull final Class implClass;
|
||||
|
||||
ProviderEndpointModel(Class<T> implementorClass, WSBinding binding) {
|
||||
assert implementorClass != null;
|
||||
assert binding != null;
|
||||
|
||||
implClass = implementorClass;
|
||||
mode = getServiceMode(implementorClass);
|
||||
Class otherClass = (binding instanceof SOAPBinding)
|
||||
? SOAPMessage.class : DataSource.class;
|
||||
isAsync = AsyncProvider.class.isAssignableFrom(implementorClass);
|
||||
|
||||
|
||||
Class<? extends Object> baseType = isAsync ? AsyncProvider.class : Provider.class;
|
||||
Type baseParam = BindingHelper.getBaseType(implementorClass, baseType);
|
||||
if (baseParam==null)
|
||||
throw new WebServiceException(ServerMessages.NOT_IMPLEMENT_PROVIDER(implementorClass.getName()));
|
||||
if (!(baseParam instanceof ParameterizedType))
|
||||
throw new WebServiceException(ServerMessages.PROVIDER_NOT_PARAMETERIZED(implementorClass.getName()));
|
||||
|
||||
ParameterizedType pt = (ParameterizedType)baseParam;
|
||||
Type[] types = pt.getActualTypeArguments();
|
||||
if(!(types[0] instanceof Class))
|
||||
throw new WebServiceException(ServerMessages.PROVIDER_INVALID_PARAMETER_TYPE(implementorClass.getName(),types[0]));
|
||||
datatype = (Class)types[0];
|
||||
|
||||
if (mode == Service.Mode.PAYLOAD && datatype!=Source.class) {
|
||||
// Illegal to have PAYLOAD && SOAPMessage
|
||||
// Illegal to have PAYLOAD && DataSource
|
||||
throw new IllegalArgumentException(
|
||||
"Illeagal combination - Mode.PAYLOAD and Provider<"+otherClass.getName()+">");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it PAYLOAD or MESSAGE ??
|
||||
*
|
||||
* @param c endpoint class
|
||||
* @return Service.Mode.PAYLOAD or Service.Mode.MESSAGE
|
||||
*/
|
||||
private static Service.Mode getServiceMode(Class<?> c) {
|
||||
ServiceMode mode = c.getAnnotation(ServiceMode.class);
|
||||
return (mode == null) ? Service.Mode.PAYLOAD : mode.value();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.pipe.Tube;
|
||||
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.Invoker;
|
||||
import com.sun.xml.internal.ws.api.server.ProviderInvokerTubeFactory;
|
||||
import com.sun.xml.internal.ws.binding.SOAPBindingImpl;
|
||||
import com.sun.xml.internal.ws.server.InvokerTube;
|
||||
|
||||
import javax.xml.ws.Provider;
|
||||
|
||||
/**
|
||||
* This {@link Tube} is used to invoke the {@link Provider} and {@link AsyncProvider} endpoints.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class ProviderInvokerTube<T> extends InvokerTube<Provider<T>> {
|
||||
|
||||
protected ProviderArgumentsBuilder<T> argsBuilder;
|
||||
|
||||
/*package*/ ProviderInvokerTube(Invoker invoker, ProviderArgumentsBuilder<T> argsBuilder) {
|
||||
super(invoker);
|
||||
this.argsBuilder = argsBuilder;
|
||||
}
|
||||
|
||||
public static <T> ProviderInvokerTube<T>
|
||||
create(final Class<T> implType, final WSBinding binding, final Invoker invoker, final Container container) {
|
||||
|
||||
final ProviderEndpointModel<T> model = new ProviderEndpointModel<T>(implType, binding);
|
||||
final ProviderArgumentsBuilder<?> argsBuilder = ProviderArgumentsBuilder.create(model, binding);
|
||||
if (binding instanceof SOAPBindingImpl) {
|
||||
//set portKnownHeaders on Binding, so that they can be used for MU processing
|
||||
((SOAPBindingImpl) binding).setMode(model.mode);
|
||||
}
|
||||
|
||||
return ProviderInvokerTubeFactory.create(null, container, implType, invoker, argsBuilder, model.isAsync);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Messages;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
|
||||
import javax.xml.soap.MimeHeader;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Service;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class SOAPProviderArgumentBuilder<T> extends ProviderArgumentsBuilder<T> {
|
||||
protected final SOAPVersion soapVersion;
|
||||
|
||||
private SOAPProviderArgumentBuilder(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
static ProviderArgumentsBuilder create(ProviderEndpointModel model, SOAPVersion soapVersion) {
|
||||
if (model.mode == Service.Mode.PAYLOAD) {
|
||||
return new PayloadSource(soapVersion);
|
||||
} else {
|
||||
if(model.datatype==Source.class)
|
||||
return new MessageSource(soapVersion);
|
||||
if(model.datatype==SOAPMessage.class)
|
||||
return new SOAPMessageParameter(soapVersion);
|
||||
if(model.datatype==Message.class)
|
||||
return new MessageProviderArgumentBuilder(soapVersion);
|
||||
throw new WebServiceException(ServerMessages.PROVIDER_INVALID_PARAMETER_TYPE(model.implClass,model.datatype));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PayloadSource extends SOAPProviderArgumentBuilder<Source> {
|
||||
PayloadSource(SOAPVersion soapVersion) {
|
||||
super(soapVersion);
|
||||
}
|
||||
|
||||
/*protected*/ public Source getParameter(Packet packet) {
|
||||
return packet.getMessage().readPayloadAsSource();
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Source source) {
|
||||
return Messages.createUsingPayload(source, soapVersion);
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class MessageSource extends SOAPProviderArgumentBuilder<Source> {
|
||||
MessageSource(SOAPVersion soapVersion) {
|
||||
super(soapVersion);
|
||||
}
|
||||
|
||||
/*protected*/ public Source getParameter(Packet packet) {
|
||||
return packet.getMessage().readEnvelopeAsSource();
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Source source) {
|
||||
return Messages.create(source, soapVersion);
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SOAPMessageParameter extends SOAPProviderArgumentBuilder<SOAPMessage> {
|
||||
SOAPMessageParameter(SOAPVersion soapVersion) {
|
||||
super(soapVersion);
|
||||
}
|
||||
|
||||
/*protected*/ public SOAPMessage getParameter(Packet packet) {
|
||||
try {
|
||||
return packet.getMessage().readAsSOAPMessage(packet, true);
|
||||
} catch (SOAPException se) {
|
||||
throw new WebServiceException(se);
|
||||
}
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(SOAPMessage soapMsg) {
|
||||
return Messages.create(soapMsg);
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Packet getResponse(Packet request, @Nullable SOAPMessage returnValue, WSDLPort port, WSBinding binding) {
|
||||
Packet response = super.getResponse(request, returnValue, port, binding);
|
||||
// Populate SOAPMessage's transport headers
|
||||
if (returnValue != null && response.supports(Packet.OUTBOUND_TRANSPORT_HEADERS)) {
|
||||
MimeHeaders hdrs = returnValue.getMimeHeaders();
|
||||
Map<String, List<String>> headers = new HashMap<String, List<String>>();
|
||||
Iterator i = hdrs.getAllHeaders();
|
||||
while(i.hasNext()) {
|
||||
MimeHeader header = (MimeHeader)i.next();
|
||||
if(header.getName().equalsIgnoreCase("SOAPAction"))
|
||||
// SAAJ sets this header automatically, but it interferes with the correct operation of JAX-WS.
|
||||
// so ignore this header.
|
||||
continue;
|
||||
|
||||
List<String> list = headers.get(header.getName());
|
||||
if (list == null) {
|
||||
list = new ArrayList<String>();
|
||||
headers.put(header.getName(), list);
|
||||
}
|
||||
list.add(header.getValue());
|
||||
}
|
||||
response.put(Packet.OUTBOUND_TRANSPORT_HEADERS, headers);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.NextAction;
|
||||
import com.sun.xml.internal.ws.api.pipe.ThrowableContainerPropertySet;
|
||||
import com.sun.xml.internal.ws.api.server.Invoker;
|
||||
|
||||
import javax.xml.ws.Provider;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This tube is used to invoke the {@link Provider} endpoints.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public // TODO needed by factory
|
||||
class SyncProviderInvokerTube<T> extends ProviderInvokerTube<T> {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(
|
||||
com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.SyncProviderInvokerTube");
|
||||
|
||||
public SyncProviderInvokerTube(Invoker invoker, ProviderArgumentsBuilder<T> argsBuilder) {
|
||||
super(invoker, argsBuilder);
|
||||
}
|
||||
|
||||
/*
|
||||
* This binds the parameter for Provider endpoints and invokes the
|
||||
* invoke() method of {@linke Provider} endpoint. The return value from
|
||||
* invoke() is used to create a new {@link Message} that traverses
|
||||
* through the Pipeline to transport.
|
||||
*/
|
||||
public NextAction processRequest(Packet request) {
|
||||
WSDLPort port = getEndpoint().getPort();
|
||||
WSBinding binding = getEndpoint().getBinding();
|
||||
T param = argsBuilder.getParameter(request);
|
||||
|
||||
LOGGER.fine("Invoking Provider Endpoint");
|
||||
|
||||
T returnValue;
|
||||
try {
|
||||
returnValue = getInvoker(request).invokeProvider(request, param);
|
||||
} catch(Exception e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Packet response = argsBuilder.getResponse(request,e,port,binding);
|
||||
return doReturnWith(response);
|
||||
}
|
||||
if (returnValue == null) {
|
||||
// Oneway. Send response code immediately for transports(like HTTP)
|
||||
// Don't do this above, since close() may generate some exceptions
|
||||
if (request.transportBackChannel != null) {
|
||||
request.transportBackChannel.close();
|
||||
}
|
||||
}
|
||||
Packet response = argsBuilder.getResponse(request,returnValue,port,binding);
|
||||
|
||||
// Only used by Provider<Packet>
|
||||
// Implementation may pass Packet containing throwable; use both
|
||||
ThrowableContainerPropertySet tc = response.getSatellite(ThrowableContainerPropertySet.class);
|
||||
Throwable t = (tc != null) ? tc.getThrowable() : null;
|
||||
|
||||
return t != null ? doThrow(response, t) : doReturnWith(response);
|
||||
}
|
||||
|
||||
public @NotNull NextAction processResponse(@NotNull Packet response) {
|
||||
return doReturnWith(response);
|
||||
}
|
||||
|
||||
public @NotNull NextAction processException(@NotNull Throwable t) {
|
||||
return doThrow(t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.provider;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Messages;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLMessage;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Service;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.handler.MessageContext;
|
||||
import javax.xml.ws.http.HTTPException;
|
||||
|
||||
/**
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
abstract class XMLProviderArgumentBuilder<T> extends ProviderArgumentsBuilder<T> {
|
||||
|
||||
@Override
|
||||
protected Packet getResponse(Packet request, Exception e, WSDLPort port, WSBinding binding) {
|
||||
Packet response = super.getResponse(request, e, port, binding);
|
||||
if (e instanceof HTTPException) {
|
||||
if (response.supports(MessageContext.HTTP_RESPONSE_CODE)) {
|
||||
response.put(MessageContext.HTTP_RESPONSE_CODE, ((HTTPException)e).getStatusCode());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
static XMLProviderArgumentBuilder createBuilder(ProviderEndpointModel model, WSBinding binding) {
|
||||
if (model.mode == Service.Mode.PAYLOAD) {
|
||||
return new PayloadSource();
|
||||
} else {
|
||||
if(model.datatype==Source.class)
|
||||
return new PayloadSource();
|
||||
if(model.datatype== DataSource.class)
|
||||
return new DataSourceParameter(binding);
|
||||
throw new WebServiceException(ServerMessages.PROVIDER_INVALID_PARAMETER_TYPE(model.implClass,model.datatype));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PayloadSource extends XMLProviderArgumentBuilder<Source> {
|
||||
public Source getParameter(Packet packet) {
|
||||
return packet.getMessage().readPayloadAsSource();
|
||||
}
|
||||
|
||||
public Message getResponseMessage(Source source) {
|
||||
return Messages.createUsingPayload(source, SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return XMLMessage.create(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DataSourceParameter extends XMLProviderArgumentBuilder<DataSource> {
|
||||
private final WSBinding binding;
|
||||
|
||||
DataSourceParameter(WSBinding binding) {
|
||||
this.binding = binding;
|
||||
}
|
||||
public DataSource getParameter(Packet packet) {
|
||||
Message msg = packet.getInternalMessage();
|
||||
return (msg instanceof XMLMessage.MessageDataSource)
|
||||
? ((XMLMessage.MessageDataSource) msg).getDataSource()
|
||||
: XMLMessage.getDataSource(msg, binding.getFeatures());
|
||||
}
|
||||
|
||||
public Message getResponseMessage(DataSource ds) {
|
||||
return XMLMessage.create(ds, binding.getFeatures());
|
||||
}
|
||||
|
||||
protected Message getResponseMessage(Exception e) {
|
||||
return XMLMessage.create(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,692 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.model.ParameterBinding;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
import com.sun.xml.internal.ws.resources.ServerMessages;
|
||||
import com.sun.xml.internal.ws.spi.db.RepeatedElementBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.DatabindingException;
|
||||
import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
|
||||
import com.sun.xml.internal.ws.spi.db.WrapperComposite;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.encoding.StringDataContentHandler;
|
||||
import com.sun.xml.internal.ws.encoding.DataHandlerDataSource;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.jws.WebParam.Mode;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPFault;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.soap.SOAPFaultException;
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads a request {@link Message}, disassembles it, and moves obtained Java values
|
||||
* to the expected places.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class EndpointArgumentsBuilder {
|
||||
/**
|
||||
* Reads a request {@link Message}, disassembles it, and moves obtained
|
||||
* Java values to the expected places.
|
||||
*
|
||||
* @param request
|
||||
* The request {@link Message} to be de-composed.
|
||||
* @param args
|
||||
* The Java arguments given to the SEI method invocation.
|
||||
* Some parts of the reply message may be set to {@link Holder}s in the arguments.
|
||||
* @throws JAXBException
|
||||
* if there's an error during unmarshalling the request message.
|
||||
* @throws XMLStreamException
|
||||
* if there's an error during unmarshalling the request message.
|
||||
*/
|
||||
public abstract void readRequest(Message request, Object[] args)
|
||||
throws JAXBException, XMLStreamException;
|
||||
|
||||
static final class None extends EndpointArgumentsBuilder {
|
||||
private None(){
|
||||
}
|
||||
@Override
|
||||
public void readRequest(Message msg, Object[] args) {
|
||||
msg.consume();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The singleton instance that produces null return value.
|
||||
* Used for operations that doesn't have any output.
|
||||
*/
|
||||
public final static EndpointArgumentsBuilder NONE = new None();
|
||||
|
||||
/**
|
||||
* Returns the 'uninitialized' value for the given type.
|
||||
*
|
||||
* <p>
|
||||
* For primitive types, it's '0', and for reference types, it's null.
|
||||
*/
|
||||
@SuppressWarnings("element-type-mismatch")
|
||||
public static Object getVMUninitializedValue(Type type) {
|
||||
// if this map returns null, that means the 'type' is a reference type,
|
||||
// in which case 'null' is the correct null value, so this code is correct.
|
||||
return primitiveUninitializedValues.get(type);
|
||||
}
|
||||
|
||||
private static final Map<Class,Object> primitiveUninitializedValues = new HashMap<Class, Object>();
|
||||
|
||||
static {
|
||||
Map<Class, Object> m = primitiveUninitializedValues;
|
||||
m.put(int.class,(int)0);
|
||||
m.put(char.class,(char)0);
|
||||
m.put(byte.class,(byte)0);
|
||||
m.put(short.class,(short)0);
|
||||
m.put(long.class,(long)0);
|
||||
m.put(float.class,(float)0);
|
||||
m.put(double.class,(double)0);
|
||||
}
|
||||
|
||||
protected QName wrapperName;
|
||||
|
||||
static final class WrappedPartBuilder {
|
||||
private final XMLBridge bridge;
|
||||
private final EndpointValueSetter setter;
|
||||
|
||||
/**
|
||||
* @param bridge
|
||||
* specifies how the part is unmarshalled.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the endpoint.
|
||||
*/
|
||||
public WrappedPartBuilder(XMLBridge bridge, EndpointValueSetter setter) {
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
void readRequest( Object[] args, XMLStreamReader r, AttachmentSet att) throws JAXBException {
|
||||
Object obj = null;
|
||||
AttachmentUnmarshallerImpl au = (att != null)?new AttachmentUnmarshallerImpl(att):null;
|
||||
if (bridge instanceof RepeatedElementBridge) {
|
||||
RepeatedElementBridge rbridge = (RepeatedElementBridge)bridge;
|
||||
ArrayList list = new ArrayList();
|
||||
QName name = r.getName();
|
||||
while (r.getEventType()==XMLStreamReader.START_ELEMENT && name.equals(r.getName())) {
|
||||
list.add(rbridge.unmarshal(r, au));
|
||||
XMLStreamReaderUtil.toNextTag(r, name);
|
||||
}
|
||||
obj = rbridge.collectionHandler().convert(list);
|
||||
} else {
|
||||
obj = bridge.unmarshal(r, au);
|
||||
}
|
||||
setter.put(obj,args);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<QName,WrappedPartBuilder> wrappedParts = null;
|
||||
|
||||
protected void readWrappedRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
if (!msg.hasPayload()) {
|
||||
throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
|
||||
}
|
||||
XMLStreamReader reader = msg.readPayload();
|
||||
XMLStreamReaderUtil.verifyTag(reader,wrapperName);
|
||||
reader.nextTag();
|
||||
while(reader.getEventType()==XMLStreamReader.START_ELEMENT) {
|
||||
// TODO: QName has a performance issue
|
||||
QName name = reader.getName();
|
||||
WrappedPartBuilder part = wrappedParts.get(name);
|
||||
if(part==null) {
|
||||
// no corresponding part found. ignore
|
||||
XMLStreamReaderUtil.skipElement(reader);
|
||||
reader.nextTag();
|
||||
} else {
|
||||
part.readRequest(args,reader, msg.getAttachments());
|
||||
}
|
||||
XMLStreamReaderUtil.toNextTag(reader, name);
|
||||
}
|
||||
|
||||
// we are done with the body
|
||||
reader.close();
|
||||
XMLStreamReaderFactory.recycle(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link EndpointArgumentsBuilder} that sets the VM uninitialized value to the type.
|
||||
*/
|
||||
public static final class NullSetter extends EndpointArgumentsBuilder {
|
||||
private final EndpointValueSetter setter;
|
||||
private final Object nullValue;
|
||||
|
||||
public NullSetter(EndpointValueSetter setter, Object nullValue){
|
||||
assert setter!=null;
|
||||
this.nullValue = nullValue;
|
||||
this.setter = setter;
|
||||
}
|
||||
public void readRequest(Message msg, Object[] args) {
|
||||
setter.put(nullValue, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link EndpointArgumentsBuilder} that is a composition of multiple
|
||||
* {@link EndpointArgumentsBuilder}s.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes we need to look at multiple parts of the reply message
|
||||
* (say, two header params, one body param, and three attachments, etc.)
|
||||
* and that's when this object is used to combine multiple {@link EndpointArgumentsBuilder}s
|
||||
* (that each responsible for handling one part).
|
||||
*
|
||||
* <p>
|
||||
* The model guarantees that only at most one {@link EndpointArgumentsBuilder} will
|
||||
* return a value as a return value (and everything else has to go to
|
||||
* {@link Holder}s.)
|
||||
*/
|
||||
public static final class Composite extends EndpointArgumentsBuilder {
|
||||
private final EndpointArgumentsBuilder[] builders;
|
||||
|
||||
public Composite(EndpointArgumentsBuilder... builders) {
|
||||
this.builders = builders;
|
||||
}
|
||||
|
||||
public Composite(Collection<? extends EndpointArgumentsBuilder> builders) {
|
||||
this(builders.toArray(new EndpointArgumentsBuilder[builders.size()]));
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
for (EndpointArgumentsBuilder builder : builders) {
|
||||
builder.readRequest(msg,args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads an Attachment into a Java parameter.
|
||||
*/
|
||||
public static abstract class AttachmentBuilder extends EndpointArgumentsBuilder {
|
||||
protected final EndpointValueSetter setter;
|
||||
protected final ParameterImpl param;
|
||||
protected final String pname;
|
||||
protected final String pname1;
|
||||
|
||||
AttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
this.setter = setter;
|
||||
this.param = param;
|
||||
this.pname = param.getPartName();
|
||||
this.pname1 = "<"+pname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AttachmentBuilder based on the parameter type
|
||||
*
|
||||
* @param param
|
||||
* runtime Parameter that abstracts the annotated java parameter
|
||||
* @param setter
|
||||
* specifies how the obtained value is set into the argument. Takes
|
||||
* care of Holder arguments.
|
||||
*/
|
||||
public static EndpointArgumentsBuilder createAttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
Class type = (Class)param.getTypeInfo().type;
|
||||
if (DataHandler.class.isAssignableFrom(type)) {
|
||||
return new DataHandlerBuilder(param, setter);
|
||||
} else if (byte[].class==type) {
|
||||
return new ByteArrayBuilder(param, setter);
|
||||
} else if(Source.class.isAssignableFrom(type)) {
|
||||
return new SourceBuilder(param, setter);
|
||||
} else if(Image.class.isAssignableFrom(type)) {
|
||||
return new ImageBuilder(param, setter);
|
||||
} else if(InputStream.class==type) {
|
||||
return new InputStreamBuilder(param, setter);
|
||||
} else if(isXMLMimeType(param.getBinding().getMimeType())) {
|
||||
return new JAXBBuilder(param, setter);
|
||||
} else if(String.class.isAssignableFrom(type)) {
|
||||
return new StringBuilder(param, setter);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unknown Type="+type+" Attachment is not mapped.");
|
||||
}
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
boolean foundAttachment = false;
|
||||
// TODO not to loop
|
||||
for (Attachment att : msg.getAttachments()) {
|
||||
String part = getWSDLPartName(att);
|
||||
if (part == null) {
|
||||
continue;
|
||||
}
|
||||
if(part.equals(pname) || part.equals(pname1)){
|
||||
foundAttachment = true;
|
||||
mapAttachment(att, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundAttachment) {
|
||||
throw new WebServiceException("Missing Attachment for "+pname);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void mapAttachment(Attachment att, Object[] args) throws JAXBException;
|
||||
}
|
||||
|
||||
private static final class DataHandlerBuilder extends AttachmentBuilder {
|
||||
DataHandlerBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
setter.put(att.asDataHandler(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ByteArrayBuilder extends AttachmentBuilder {
|
||||
ByteArrayBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
setter.put(att.asByteArray(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SourceBuilder extends AttachmentBuilder {
|
||||
SourceBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
setter.put(att.asSource(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ImageBuilder extends AttachmentBuilder {
|
||||
ImageBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
Image image;
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = att.asInputStream();
|
||||
image = ImageIO.read(is);
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
setter.put(image, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class InputStreamBuilder extends AttachmentBuilder {
|
||||
InputStreamBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
setter.put(att.asInputStream(), args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class JAXBBuilder extends AttachmentBuilder {
|
||||
JAXBBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) throws JAXBException {
|
||||
Object obj = param.getXMLBridge().unmarshal(att.asInputStream());
|
||||
setter.put(obj, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class StringBuilder extends AttachmentBuilder {
|
||||
StringBuilder(ParameterImpl param, EndpointValueSetter setter) {
|
||||
super(param, setter);
|
||||
}
|
||||
|
||||
void mapAttachment(Attachment att, Object[] args) {
|
||||
att.getContentType();
|
||||
StringDataContentHandler sdh = new StringDataContentHandler();
|
||||
try {
|
||||
String str = (String)sdh.getContent(new DataHandlerDataSource(att.asDataHandler()));
|
||||
setter.put(str, args);
|
||||
} catch(Exception e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WSDL part name of this attachment.
|
||||
*
|
||||
* <p>
|
||||
* According to WSI AP 1.0
|
||||
* <PRE>
|
||||
* 3.8 Value-space of Content-Id Header
|
||||
* Definition: content-id part encoding
|
||||
* The "content-id part encoding" consists of the concatenation of:
|
||||
* The value of the name attribute of the wsdl:part element referenced by the mime:content, in which characters disallowed in content-id headers (non-ASCII characters as represented by code points above 0x7F) are escaped as follows:
|
||||
* o Each disallowed character is converted to UTF-8 as one or more bytes.
|
||||
* o Any bytes corresponding to a disallowed character are escaped with the URI escaping mechanism (that is, converted to %HH, where HH is the hexadecimal notation of the byte value).
|
||||
* o The original character is replaced by the resulting character sequence.
|
||||
* The character '=' (0x3D).
|
||||
* A globally unique value such as a UUID.
|
||||
* The character '@' (0x40).
|
||||
* A valid domain name under the authority of the entity constructing the message.
|
||||
* </PRE>
|
||||
*
|
||||
* So a wsdl:part fooPart will be encoded as:
|
||||
* <fooPart=somereallybignumberlikeauuid@example.com>
|
||||
*
|
||||
* @return null
|
||||
* if the parsing fails.
|
||||
*/
|
||||
public static final String getWSDLPartName(com.sun.xml.internal.ws.api.message.Attachment att){
|
||||
String cId = att.getContentId();
|
||||
|
||||
int index = cId.lastIndexOf('@', cId.length());
|
||||
if(index == -1){
|
||||
return null;
|
||||
}
|
||||
String localPart = cId.substring(0, index);
|
||||
index = localPart.lastIndexOf('=', localPart.length());
|
||||
if(index == -1){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return java.net.URLDecoder.decode(localPart.substring(0, index), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads a header into a JAXB object.
|
||||
*/
|
||||
public static final class Header extends EndpointArgumentsBuilder {
|
||||
private final XMLBridge<?> bridge;
|
||||
private final EndpointValueSetter setter;
|
||||
private final QName headerName;
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* The name of the header element.
|
||||
* @param bridge
|
||||
* specifies how to unmarshal a header into a JAXB object.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public Header(SOAPVersion soapVersion, QName name, XMLBridge<?> bridge, EndpointValueSetter setter) {
|
||||
this.soapVersion = soapVersion;
|
||||
this.headerName = name;
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public Header(SOAPVersion soapVersion, ParameterImpl param, EndpointValueSetter setter) {
|
||||
this(
|
||||
soapVersion,
|
||||
param.getTypeInfo().tagName,
|
||||
param.getXMLBridge(),
|
||||
setter);
|
||||
assert param.getOutBinding()== ParameterBinding.HEADER;
|
||||
}
|
||||
|
||||
private SOAPFaultException createDuplicateHeaderException() {
|
||||
try {
|
||||
SOAPFault fault = soapVersion.getSOAPFactory().createFault();
|
||||
fault.setFaultCode(soapVersion.faultCodeClient);
|
||||
fault.setFaultString(ServerMessages.DUPLICATE_PORT_KNOWN_HEADER(headerName));
|
||||
return new SOAPFaultException(fault);
|
||||
} catch(SOAPException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException {
|
||||
com.sun.xml.internal.ws.api.message.Header header = null;
|
||||
Iterator<com.sun.xml.internal.ws.api.message.Header> it =
|
||||
msg.getHeaders().getHeaders(headerName,true);
|
||||
if (it.hasNext()) {
|
||||
header = it.next();
|
||||
if (it.hasNext()) {
|
||||
throw createDuplicateHeaderException();
|
||||
}
|
||||
}
|
||||
|
||||
if(header!=null) {
|
||||
setter.put( header.readAsJAXB(bridge), args );
|
||||
} else {
|
||||
// header not found.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the whole payload into a single JAXB bean.
|
||||
*/
|
||||
public static final class Body extends EndpointArgumentsBuilder {
|
||||
private final XMLBridge<?> bridge;
|
||||
private final EndpointValueSetter setter;
|
||||
|
||||
/**
|
||||
* @param bridge
|
||||
* specifies how to unmarshal the payload into a JAXB object.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public Body(XMLBridge<?> bridge, EndpointValueSetter setter) {
|
||||
this.bridge = bridge;
|
||||
this.setter = setter;
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException {
|
||||
setter.put( msg.readPayloadAsJAXB(bridge), args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats a payload as multiple parts wrapped into one element,
|
||||
* and processes all such wrapped parts.
|
||||
*/
|
||||
public static final class DocLit extends EndpointArgumentsBuilder {
|
||||
/**
|
||||
* {@link PartBuilder} keyed by the element name (inside the wrapper element.)
|
||||
*/
|
||||
private final PartBuilder[] parts;
|
||||
|
||||
private final XMLBridge wrapper;
|
||||
private boolean dynamicWrapper;
|
||||
|
||||
public DocLit(WrapperParameter wp, Mode skipMode) {
|
||||
wrapperName = wp.getName();
|
||||
wrapper = wp.getXMLBridge();
|
||||
Class wrapperType = (Class) wrapper.getTypeInfo().type;
|
||||
dynamicWrapper = WrapperComposite.class.equals(wrapperType);
|
||||
List<PartBuilder> parts = new ArrayList<PartBuilder>();
|
||||
List<ParameterImpl> children = wp.getWrapperChildren();
|
||||
for (ParameterImpl p : children) {
|
||||
if (p.getMode() == skipMode) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if(p.isIN())
|
||||
continue;
|
||||
*/
|
||||
QName name = p.getName();
|
||||
try {
|
||||
if (dynamicWrapper) {
|
||||
if (wrappedParts == null) wrappedParts = new HashMap<QName,WrappedPartBuilder>();
|
||||
XMLBridge xmlBridge = p.getInlinedRepeatedElementBridge();
|
||||
if (xmlBridge == null) xmlBridge = p.getXMLBridge();
|
||||
wrappedParts.put( p.getName(), new WrappedPartBuilder(xmlBridge, EndpointValueSetter.get(p)));
|
||||
} else {
|
||||
parts.add( new PartBuilder(
|
||||
wp.getOwner().getBindingContext().getElementPropertyAccessor(
|
||||
wrapperType,
|
||||
name.getNamespaceURI(),
|
||||
p.getName().getLocalPart()),
|
||||
EndpointValueSetter.get(p)
|
||||
) );
|
||||
// wrapper parameter itself always bind to body, and
|
||||
// so do all its children
|
||||
assert p.getBinding()== ParameterBinding.BODY;
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException( // TODO: i18n
|
||||
wrapperType+" do not have a property of the name "+name,e);
|
||||
}
|
||||
}
|
||||
|
||||
this.parts = parts.toArray(new PartBuilder[parts.size()]);
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
if (dynamicWrapper) {
|
||||
readWrappedRequest(msg, args);
|
||||
} else {
|
||||
if (parts.length>0) {
|
||||
if (!msg.hasPayload()) {
|
||||
throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
|
||||
}
|
||||
XMLStreamReader reader = msg.readPayload();
|
||||
XMLStreamReaderUtil.verifyTag(reader, wrapperName);
|
||||
Object wrapperBean = wrapper.unmarshal(reader, (msg.getAttachments() != null) ?
|
||||
new AttachmentUnmarshallerImpl(msg.getAttachments()): null);
|
||||
|
||||
try {
|
||||
for (PartBuilder part : parts) {
|
||||
part.readRequest(args,wrapperBean);
|
||||
}
|
||||
} catch (DatabindingException e) {
|
||||
// this can happen when the set method throw a checked exception or something like that
|
||||
throw new WebServiceException(e); // TODO:i18n
|
||||
}
|
||||
|
||||
// we are done with the body
|
||||
reader.close();
|
||||
XMLStreamReaderFactory.recycle(reader);
|
||||
} else {
|
||||
msg.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals each wrapped part into a JAXB object and moves it
|
||||
* to the expected place.
|
||||
*/
|
||||
static final class PartBuilder {
|
||||
private final PropertyAccessor accessor;
|
||||
private final EndpointValueSetter setter;
|
||||
|
||||
/**
|
||||
* @param accessor
|
||||
* specifies which portion of the wrapper bean to obtain the value from.
|
||||
* @param setter
|
||||
* specifies how the obtained value is returned to the client.
|
||||
*/
|
||||
public PartBuilder(PropertyAccessor accessor, EndpointValueSetter setter) {
|
||||
this.accessor = accessor;
|
||||
this.setter = setter;
|
||||
assert accessor!=null && setter!=null;
|
||||
}
|
||||
|
||||
final void readRequest( Object[] args, Object wrapperBean ) {
|
||||
Object obj = accessor.get(wrapperBean);
|
||||
setter.put(obj,args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats a payload as multiple parts wrapped into one element,
|
||||
* and processes all such wrapped parts.
|
||||
*/
|
||||
public static final class RpcLit extends EndpointArgumentsBuilder {
|
||||
public RpcLit(WrapperParameter wp) {
|
||||
assert wp.getTypeInfo().type== WrapperComposite.class;
|
||||
|
||||
wrapperName = wp.getName();
|
||||
wrappedParts = new HashMap<QName,WrappedPartBuilder>();
|
||||
List<ParameterImpl> children = wp.getWrapperChildren();
|
||||
for (ParameterImpl p : children) {
|
||||
wrappedParts.put( p.getName(), new WrappedPartBuilder(
|
||||
p.getXMLBridge(), EndpointValueSetter.get(p)
|
||||
));
|
||||
// wrapper parameter itself always bind to body, and
|
||||
// so do all its children
|
||||
assert p.getBinding()== ParameterBinding.BODY;
|
||||
}
|
||||
}
|
||||
|
||||
public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
|
||||
readWrappedRequest(msg, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isXMLMimeType(String mimeType){
|
||||
return mimeType.equals("text/xml") || mimeType.equals("application/xml");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Messages;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
import com.sun.xml.internal.ws.spi.db.BindingContext;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
|
||||
import com.sun.xml.internal.ws.spi.db.WrapperComposite;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Builds a JAXB object that represents the payload.
|
||||
*
|
||||
* @see MessageFiller
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class EndpointResponseMessageBuilder {
|
||||
public abstract Message createMessage(Object[] methodArgs, Object returnValue);
|
||||
|
||||
public static final EndpointResponseMessageBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
|
||||
public static final EndpointResponseMessageBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
|
||||
|
||||
private static final class Empty extends EndpointResponseMessageBuilder {
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
public Empty(SOAPVersion soapVersion) {
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
public Message createMessage(Object[] methodArgs, Object returnValue) {
|
||||
return Messages.createEmpty(soapVersion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for those {@link EndpointResponseMessageBuilder}s that build a {@link Message}
|
||||
* from JAXB objects.
|
||||
*/
|
||||
private static abstract class JAXB extends EndpointResponseMessageBuilder {
|
||||
/**
|
||||
* This object determines the binding of the object returned
|
||||
* from {@link #createMessage(Object[], Object)}
|
||||
*/
|
||||
private final XMLBridge bridge;
|
||||
private final SOAPVersion soapVersion;
|
||||
|
||||
protected JAXB(XMLBridge bridge, SOAPVersion soapVersion) {
|
||||
assert bridge!=null;
|
||||
this.bridge = bridge;
|
||||
this.soapVersion = soapVersion;
|
||||
}
|
||||
|
||||
public final Message createMessage(Object[] methodArgs, Object returnValue) {
|
||||
return JAXBMessage.create( bridge, build(methodArgs, returnValue), soapVersion );
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a JAXB object that becomes the payload.
|
||||
*/
|
||||
abstract Object build(Object[] methodArgs, Object returnValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object just by taking
|
||||
* one of the parameters.
|
||||
*/
|
||||
public final static class Bare extends JAXB {
|
||||
/**
|
||||
* The index of the method invocation parameters that goes into the payload.
|
||||
*/
|
||||
private final int methodPos;
|
||||
|
||||
private final ValueGetter getter;
|
||||
|
||||
/**
|
||||
* Creates a {@link EndpointResponseMessageBuilder} from a bare parameter.
|
||||
*/
|
||||
public Bare(ParameterImpl p, SOAPVersion soapVersion) {
|
||||
super(p.getXMLBridge(), soapVersion);
|
||||
this.methodPos = p.getIndex();
|
||||
this.getter = ValueGetter.get(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks up an object from the method arguments and uses it.
|
||||
*/
|
||||
Object build(Object[] methodArgs, Object returnValue) {
|
||||
if (methodPos == -1) {
|
||||
return returnValue;
|
||||
}
|
||||
return getter.get(methodArgs[methodPos]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to handle a 'wrapper' style request.
|
||||
* Common part of rpc/lit and doc/lit.
|
||||
*/
|
||||
abstract static class Wrapped extends JAXB {
|
||||
|
||||
/**
|
||||
* Where in the method argument list do they come from?
|
||||
*/
|
||||
protected final int[] indices;
|
||||
|
||||
/**
|
||||
* Abstracts away the {@link Holder} handling when touching method arguments.
|
||||
*/
|
||||
protected final ValueGetter[] getters;
|
||||
|
||||
/**
|
||||
* How does each wrapped parameter binds to XML?
|
||||
*/
|
||||
protected XMLBridge[] parameterBridges;
|
||||
|
||||
/**
|
||||
* Used for error diagnostics.
|
||||
*/
|
||||
protected List<ParameterImpl> children;
|
||||
|
||||
protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion) {
|
||||
super(wp.getXMLBridge(), soapVersion);
|
||||
|
||||
children = wp.getWrapperChildren();
|
||||
|
||||
indices = new int[children.size()];
|
||||
getters = new ValueGetter[children.size()];
|
||||
for( int i=0; i<indices.length; i++ ) {
|
||||
ParameterImpl p = children.get(i);
|
||||
indices[i] = p.getIndex();
|
||||
getters[i] = ValueGetter.get(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bunch of arguments intoa {@link WrapperComposite}.
|
||||
*/
|
||||
WrapperComposite buildWrapperComposite(Object[] methodArgs, Object returnValue) {
|
||||
WrapperComposite cs = new WrapperComposite();
|
||||
cs.bridges = parameterBridges;
|
||||
cs.values = new Object[parameterBridges.length];
|
||||
|
||||
// fill in wrapped parameters from methodArgs
|
||||
for( int i=indices.length-1; i>=0; i-- ) {
|
||||
Object v;
|
||||
if (indices[i] == -1) {
|
||||
v = getters[i].get(returnValue);
|
||||
} else {
|
||||
v = getters[i].get(methodArgs[indices[i]]);
|
||||
}
|
||||
if(v==null) {
|
||||
throw new WebServiceException("Method Parameter: "+
|
||||
children.get(i).getName() +" cannot be null. This is BP 1.1 R2211 violation.");
|
||||
}
|
||||
cs.values[i] = v;
|
||||
}
|
||||
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object by wrapping
|
||||
* multiple parameters into one "wrapper bean".
|
||||
*/
|
||||
public final static class DocLit extends Wrapped {
|
||||
/**
|
||||
* How does each wrapped parameter binds to XML?
|
||||
*/
|
||||
private final PropertyAccessor[] accessors;
|
||||
|
||||
//private final RawAccessor retAccessor;
|
||||
|
||||
/**
|
||||
* Wrapper bean.
|
||||
*/
|
||||
private final Class wrapper;
|
||||
private boolean dynamicWrapper;
|
||||
|
||||
/**
|
||||
* Needed to get wrapper instantiation method.
|
||||
*/
|
||||
private BindingContext bindingContext;
|
||||
|
||||
/**
|
||||
* Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
|
||||
*/
|
||||
public DocLit(WrapperParameter wp, SOAPVersion soapVersion) {
|
||||
super(wp, soapVersion);
|
||||
bindingContext = wp.getOwner().getBindingContext();
|
||||
wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
|
||||
dynamicWrapper = WrapperComposite.class.equals(wrapper);
|
||||
children = wp.getWrapperChildren();
|
||||
parameterBridges = new XMLBridge[children.size()];
|
||||
accessors = new PropertyAccessor[children.size()];
|
||||
for( int i=0; i<accessors.length; i++ ) {
|
||||
ParameterImpl p = children.get(i);
|
||||
QName name = p.getName();
|
||||
if (dynamicWrapper) {
|
||||
parameterBridges[i] = children.get(i).getInlinedRepeatedElementBridge();
|
||||
if (parameterBridges[i] == null) parameterBridges[i] = children.get(i).getXMLBridge();
|
||||
} else {
|
||||
try {
|
||||
accessors[i] = (dynamicWrapper) ? null :
|
||||
p.getOwner().getBindingContext().getElementPropertyAccessor(
|
||||
wrapper, name.getNamespaceURI(), name.getLocalPart() );
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException( // TODO: i18n
|
||||
wrapper+" do not have a property of the name "+name,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bunch of arguments into a {@link WrapperComposite}.
|
||||
*/
|
||||
Object build(Object[] methodArgs, Object returnValue) {
|
||||
if (dynamicWrapper) return buildWrapperComposite(methodArgs, returnValue);
|
||||
try {
|
||||
//Object bean = wrapper.newInstance();
|
||||
Object bean = bindingContext.newWrapperInstace(wrapper);
|
||||
|
||||
// fill in wrapped parameters from methodArgs
|
||||
for( int i=indices.length-1; i>=0; i-- ) {
|
||||
if (indices[i] == -1) {
|
||||
accessors[i].set(bean, returnValue);
|
||||
} else {
|
||||
accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
} catch (InstantiationException e) {
|
||||
// this is irrecoverable
|
||||
Error x = new InstantiationError(e.getMessage());
|
||||
x.initCause(e);
|
||||
throw x;
|
||||
} catch (IllegalAccessException e) {
|
||||
// this is irrecoverable
|
||||
Error x = new IllegalAccessError(e.getMessage());
|
||||
x.initCause(e);
|
||||
throw x;
|
||||
} catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
|
||||
// this can happen when the set method throw a checked exception or something like that
|
||||
throw new WebServiceException(e); // TODO:i18n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to create a payload JAXB object by wrapping
|
||||
* multiple parameters into a {@link WrapperComposite}.
|
||||
*
|
||||
* <p>
|
||||
* This is used for rpc/lit, as we don't have a wrapper bean for it.
|
||||
* (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
|
||||
*/
|
||||
public final static class RpcLit extends Wrapped {
|
||||
|
||||
/**
|
||||
* Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
|
||||
*/
|
||||
public RpcLit(WrapperParameter wp, SOAPVersion soapVersion) {
|
||||
super(wp, soapVersion);
|
||||
// we'll use CompositeStructure to pack requests
|
||||
assert wp.getTypeInfo().type==WrapperComposite.class;
|
||||
|
||||
parameterBridges = new XMLBridge[children.size()];
|
||||
for( int i=0; i<parameterBridges.length; i++ )
|
||||
parameterBridges[i] = children.get(i).getXMLBridge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bunch of arguments intoa {@link WrapperComposite}.
|
||||
*/
|
||||
Object build(Object[] methodArgs, Object returnValue) {
|
||||
return buildWrapperComposite(methodArgs, returnValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.model.Parameter;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* Moves a Java value unmarshalled from a response message
|
||||
* to the right place.
|
||||
*
|
||||
* <p>
|
||||
* Sometimes values are returned as a return value, and
|
||||
* others are returned in the {@link Holder} value. Instances
|
||||
* of this interface abstracts this detail.
|
||||
*
|
||||
* <p>
|
||||
* {@link EndpointValueSetter} is a stateless behavior encapsulation.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class EndpointValueSetter {
|
||||
private EndpointValueSetter() {}
|
||||
|
||||
/**
|
||||
* Moves the value to the expected place.
|
||||
*
|
||||
* @param obj
|
||||
* The unmarshalled object.
|
||||
* @param args
|
||||
* The arguments that need to be given to the Java method invocation. If <tt>obj</tt>
|
||||
* is supposed to be returned as a {@link Holder} value, a suitable
|
||||
* {@link Holder} is obtained from this argument list and <tt>obj</tt>
|
||||
* is set.
|
||||
*
|
||||
*/
|
||||
abstract void put(Object obj, Object[] args);
|
||||
|
||||
/**
|
||||
* {@link Param}s with small index numbers are used often,
|
||||
* so we pool them to reduce the footprint.
|
||||
*/
|
||||
private static final EndpointValueSetter[] POOL = new EndpointValueSetter[16];
|
||||
|
||||
static {
|
||||
for( int i=0; i<POOL.length; i++ )
|
||||
POOL[i] = new Param(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link EndpointValueSetter} suitable for the given {@link Parameter}.
|
||||
*/
|
||||
public static EndpointValueSetter get(ParameterImpl p) {
|
||||
int idx = p.getIndex();
|
||||
if (p.isIN()) {
|
||||
if (idx<POOL.length) {
|
||||
return POOL[idx];
|
||||
} else {
|
||||
return new Param(idx);
|
||||
}
|
||||
} else {
|
||||
return new HolderParam(idx);
|
||||
}
|
||||
}
|
||||
|
||||
static class Param extends EndpointValueSetter {
|
||||
/**
|
||||
* Index of the argument to put the value to.
|
||||
*/
|
||||
protected final int idx;
|
||||
|
||||
public Param(int idx) {
|
||||
this.idx = idx;
|
||||
}
|
||||
|
||||
void put(Object obj, Object[] args) {
|
||||
if (obj != null) {
|
||||
args[idx] = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class HolderParam extends Param {
|
||||
|
||||
public HolderParam(int idx) {
|
||||
super(idx);
|
||||
}
|
||||
|
||||
@Override
|
||||
void put(Object obj, Object[] args) {
|
||||
Holder holder = new Holder();
|
||||
if (obj != null) {
|
||||
holder.value = obj;
|
||||
}
|
||||
args[idx] = holder;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/xml/internal/ws/server/sei/Invoker.java
Normal file
44
jdkSrc/jdk8/com/sun/xml/internal/ws/server/sei/Invoker.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Hides the detail of calling into application implementations.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public abstract class Invoker {
|
||||
/**
|
||||
* Wrapper for reflection invoke that allows containers to adapt
|
||||
*/
|
||||
public abstract Object invoke( @NotNull Packet p, @NotNull Method m, @NotNull Object... args ) throws InvocationTargetException, IllegalAccessException;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
|
||||
/**
|
||||
* Interface for determining Invoker for a given request
|
||||
*
|
||||
* @since 2.2.6
|
||||
*/
|
||||
public interface InvokerSource<T extends Invoker> {
|
||||
/**
|
||||
* Returns Invoker for the given request
|
||||
* @param request Packet for request
|
||||
* @return Selected invoker
|
||||
*/
|
||||
public @NotNull T getInvoker(Packet request);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
|
||||
import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl;
|
||||
|
||||
/**
|
||||
* Base class for {@link com.sun.xml.internal.ws.server.InvokerTube} restored
|
||||
* to allow for containers to specify alternate implementations of SEI-based
|
||||
* invoking.
|
||||
*/
|
||||
public abstract class InvokerTube<T extends Invoker>
|
||||
extends AbstractTubeImpl implements InvokerSource<T> {
|
||||
|
||||
protected final T invoker;
|
||||
|
||||
protected InvokerTube(T invoker) {
|
||||
this.invoker = invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
protected InvokerTube(InvokerTube<T> that, TubeCloner cloner) {
|
||||
cloner.add(that,this);
|
||||
this.invoker = that.invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Invoker} object that serves the request.
|
||||
*/
|
||||
public @NotNull T getInvoker(Packet request) {
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.Headers;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.message.ByteArrayAttachment;
|
||||
import com.sun.xml.internal.ws.message.DataHandlerAttachment;
|
||||
import com.sun.xml.internal.ws.message.JAXBAttachment;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.spi.db.XMLBridge;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.UUID;
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
|
||||
/**
|
||||
* Puts a non-payload message parameter to {@link Message}.
|
||||
*
|
||||
* <p>
|
||||
* Instance of this class is used to handle header parameters and attachment parameters.
|
||||
* They add things to {@link Message}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public abstract class MessageFiller {
|
||||
|
||||
/**
|
||||
* The index of the method invocation parameters that this object looks for.
|
||||
*/
|
||||
protected final int methodPos;
|
||||
|
||||
protected MessageFiller( int methodPos) {
|
||||
this.methodPos = methodPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an argument of a method invocation into a {@link Message}.
|
||||
*/
|
||||
public abstract void fillIn(Object[] methodArgs, Object returnValue, Message msg);
|
||||
|
||||
/**
|
||||
* Adds a parameter as an MIME attachment to {@link Message}.
|
||||
*/
|
||||
public static abstract class AttachmentFiller extends MessageFiller {
|
||||
protected final ParameterImpl param;
|
||||
protected final ValueGetter getter;
|
||||
protected final String mimeType;
|
||||
private final String contentIdPart;
|
||||
|
||||
protected AttachmentFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param.getIndex());
|
||||
this.param = param;
|
||||
this.getter = getter;
|
||||
mimeType = param.getBinding().getMimeType();
|
||||
try {
|
||||
contentIdPart = URLEncoder.encode(param.getPartName(), "UTF-8")+'=';
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an MessageFiller based on the parameter type
|
||||
*
|
||||
* @param param
|
||||
* runtime Parameter that abstracts the annotated java parameter
|
||||
* @param getter
|
||||
* Gets a value from an object that represents a parameter passed
|
||||
* as a method argument.
|
||||
*/
|
||||
public static MessageFiller createAttachmentFiller(ParameterImpl param, ValueGetter getter) {
|
||||
Class type = (Class)param.getTypeInfo().type;
|
||||
if (DataHandler.class.isAssignableFrom(type) || Source.class.isAssignableFrom(type)) {
|
||||
return new DataHandlerFiller(param, getter);
|
||||
} else if (byte[].class==type) {
|
||||
return new ByteArrayFiller(param, getter);
|
||||
} else if(isXMLMimeType(param.getBinding().getMimeType())) {
|
||||
return new JAXBFiller(param, getter);
|
||||
} else {
|
||||
return new DataHandlerFiller(param, getter);
|
||||
}
|
||||
}
|
||||
|
||||
String getContentId() {
|
||||
return contentIdPart+UUID.randomUUID()+"@jaxws.sun.com";
|
||||
}
|
||||
}
|
||||
|
||||
private static class ByteArrayFiller extends AttachmentFiller {
|
||||
protected ByteArrayFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
|
||||
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
|
||||
if (obj != null) {
|
||||
Attachment att = new ByteArrayAttachment(contentId,(byte[])obj,mimeType);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataHandlerFiller extends AttachmentFiller {
|
||||
protected DataHandlerFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
|
||||
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
|
||||
DataHandler dh = (obj instanceof DataHandler) ? (DataHandler)obj : new DataHandler(obj,mimeType);
|
||||
Attachment att = new DataHandlerAttachment(contentId, dh);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
|
||||
private static class JAXBFiller extends AttachmentFiller {
|
||||
protected JAXBFiller(ParameterImpl param, ValueGetter getter) {
|
||||
super(param, getter);
|
||||
}
|
||||
|
||||
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
|
||||
String contentId = getContentId();
|
||||
Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
|
||||
Attachment att = new JAXBAttachment(contentId, obj, param.getXMLBridge(), mimeType);
|
||||
msg.getAttachments().add(att);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a parameter as an header.
|
||||
*/
|
||||
public static final class Header extends MessageFiller {
|
||||
private final XMLBridge bridge;
|
||||
private final ValueGetter getter;
|
||||
|
||||
public Header(int methodPos, XMLBridge bridge, ValueGetter getter) {
|
||||
super(methodPos);
|
||||
this.bridge = bridge;
|
||||
this.getter = getter;
|
||||
}
|
||||
|
||||
public void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
|
||||
Object value = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]);
|
||||
msg.getHeaders().add(Headers.create(bridge,value));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isXMLMimeType(String mimeType){
|
||||
return mimeType.equals("text/xml") || mimeType.equals("application/xml");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.NextAction;
|
||||
import com.sun.xml.internal.ws.api.server.Invoker;
|
||||
import com.sun.xml.internal.ws.client.sei.MethodHandler;
|
||||
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
|
||||
import com.sun.xml.internal.ws.server.InvokerTube;
|
||||
import com.sun.xml.internal.ws.wsdl.DispatchException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* This pipe is used to invoke SEI based endpoints.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class SEIInvokerTube extends InvokerTube {
|
||||
|
||||
/**
|
||||
* For each method on the port interface we have
|
||||
* a {@link MethodHandler} that processes it.
|
||||
*/
|
||||
private final WSBinding binding;
|
||||
private final AbstractSEIModelImpl model;
|
||||
|
||||
public SEIInvokerTube(AbstractSEIModelImpl model,Invoker invoker, WSBinding binding) {
|
||||
super(invoker);
|
||||
this.binding = binding;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* This binds the parameters for SEI endpoints and invokes the endpoint method. The
|
||||
* return value, and response Holder arguments are used to create a new {@link Message}
|
||||
* that traverses through the Pipeline to transport.
|
||||
*/
|
||||
public @NotNull NextAction processRequest(@NotNull Packet req) {
|
||||
JavaCallInfo call = model.getDatabinding().deserializeRequest(req);
|
||||
if (call.getException() == null) {
|
||||
try {
|
||||
if (req.getMessage().isOneWay(model.getPort()) && req.transportBackChannel != null) {
|
||||
req.transportBackChannel.close();
|
||||
}
|
||||
Object ret = getInvoker(req).invoke(req, call.getMethod(), call.getParameters());
|
||||
call.setReturnValue(ret);
|
||||
} catch (InvocationTargetException e) {
|
||||
call.setException(e);
|
||||
} catch (Exception e) {
|
||||
call.setException(e);
|
||||
}
|
||||
} else if (call.getException() instanceof DispatchException) {
|
||||
DispatchException e = (DispatchException)call.getException();
|
||||
return doReturnWith(req.createServerResponse(e.fault, model.getPort(), null, binding));
|
||||
}
|
||||
Packet res = (Packet) model.getDatabinding().serializeResponse(call);
|
||||
res = req.relateServerResponse(res, req.endpoint.getPort(), model, req.endpoint.getBinding());
|
||||
assert res != null;
|
||||
return doReturnWith(res);
|
||||
}
|
||||
|
||||
public @NotNull NextAction processResponse(@NotNull Packet response) {
|
||||
return doReturnWith(response);
|
||||
}
|
||||
|
||||
public @NotNull NextAction processException(@NotNull Throwable t) {
|
||||
return doThrow(t);
|
||||
}
|
||||
|
||||
}
|
||||
336
jdkSrc/jdk8/com/sun/xml/internal/ws/server/sei/TieHandler.java
Normal file
336
jdkSrc/jdk8/com/sun/xml/internal/ws/server/sei/TieHandler.java
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.MessageContextFactory;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.model.JavaMethod;
|
||||
import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
|
||||
import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
|
||||
import com.sun.xml.internal.ws.model.JavaMethodImpl;
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.model.WrapperParameter;
|
||||
import com.sun.xml.internal.ws.wsdl.DispatchException;
|
||||
|
||||
import javax.jws.WebParam.Mode;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.ProtocolException;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>
|
||||
* This class mainly performs the following two tasks:
|
||||
* <ol>
|
||||
* <li>Takes a {@link Message} that represents a request,
|
||||
* and extracts the arguments (and updates {@link Holder}s.)
|
||||
* <li>Accepts return value and {@link Holder} arguments for a Java method,
|
||||
* and creates {@link JAXBMessage} that represents a response message.
|
||||
* </ol>
|
||||
*
|
||||
* <h2>Creating {@link JAXBMessage}</h2>
|
||||
* <p>
|
||||
* At the construction time, we prepare {@link EndpointArgumentsBuilder} that knows how to create endpoint {@link Method}
|
||||
* invocation arguments.
|
||||
* we also prepare {@link EndpointResponseMessageBuilder} and {@link MessageFiller}s
|
||||
* that know how to move arguments into a {@link Message}.
|
||||
* Some arguments go to the payload, some go to headers, still others go to attachments.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
* @author shih-chang.chen@oracle.com
|
||||
* Refactored from EndpointMethodHandler
|
||||
*/
|
||||
final public class TieHandler implements EndpointCallBridge {
|
||||
|
||||
private final SOAPVersion soapVersion;
|
||||
private final Method method;
|
||||
private final int noOfArgs;
|
||||
private final JavaMethodImpl javaMethodModel;
|
||||
|
||||
private final Boolean isOneWay;
|
||||
|
||||
// Converts {@link Message} --> Object[]
|
||||
private final EndpointArgumentsBuilder argumentsBuilder;
|
||||
|
||||
// these objects together create a response message from method parameters
|
||||
private final EndpointResponseMessageBuilder bodyBuilder;
|
||||
private final MessageFiller[] outFillers;
|
||||
protected MessageContextFactory packetFactory;
|
||||
|
||||
public TieHandler(JavaMethodImpl method, WSBinding binding, MessageContextFactory mcf) {
|
||||
this.soapVersion = binding.getSOAPVersion();
|
||||
this.method = method.getMethod();
|
||||
this.javaMethodModel = method;
|
||||
argumentsBuilder = createArgumentsBuilder();
|
||||
List<MessageFiller> fillers = new ArrayList<MessageFiller>();
|
||||
bodyBuilder = createResponseMessageBuilder(fillers);
|
||||
this.outFillers = fillers.toArray(new MessageFiller[fillers.size()]);
|
||||
this.isOneWay = method.getMEP().isOneWay();
|
||||
this.noOfArgs = this.method.getParameterTypes().length;
|
||||
packetFactory = mcf;
|
||||
}
|
||||
|
||||
/**
|
||||
* It builds EndpointArgumentsBuilder which converts request {@link Message} to endpoint method's invocation
|
||||
* arguments Object[]
|
||||
*
|
||||
* @return EndpointArgumentsBuilder
|
||||
*/
|
||||
private EndpointArgumentsBuilder createArgumentsBuilder() {
|
||||
EndpointArgumentsBuilder argsBuilder;
|
||||
List<ParameterImpl> rp = javaMethodModel.getRequestParameters();
|
||||
List<EndpointArgumentsBuilder> builders = new ArrayList<EndpointArgumentsBuilder>();
|
||||
|
||||
for( ParameterImpl param : rp ) {
|
||||
EndpointValueSetter setter = EndpointValueSetter.get(param);
|
||||
switch(param.getInBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit())
|
||||
builders.add(new EndpointArgumentsBuilder.RpcLit((WrapperParameter)param));
|
||||
else
|
||||
builders.add(new EndpointArgumentsBuilder.DocLit((WrapperParameter)param, Mode.OUT));
|
||||
} else {
|
||||
builders.add(new EndpointArgumentsBuilder.Body(param.getXMLBridge(),setter));
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
builders.add(new EndpointArgumentsBuilder.Header(soapVersion, param, setter));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
builders.add(EndpointArgumentsBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
builders.add(new EndpointArgumentsBuilder.NullSetter(setter,
|
||||
EndpointArgumentsBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
// creates {@link Holder} arguments for OUT parameters
|
||||
List<ParameterImpl> resp = javaMethodModel.getResponseParameters();
|
||||
for( ParameterImpl param : resp ) {
|
||||
if (param.isWrapperStyle()) {
|
||||
WrapperParameter wp = (WrapperParameter)param;
|
||||
List<ParameterImpl> children = wp.getWrapperChildren();
|
||||
for (ParameterImpl p : children) {
|
||||
if (p.isOUT() && p.getIndex() != -1) {
|
||||
EndpointValueSetter setter = EndpointValueSetter.get(p);
|
||||
builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
|
||||
}
|
||||
}
|
||||
} else if (param.isOUT() && param.getIndex() != -1) {
|
||||
EndpointValueSetter setter = EndpointValueSetter.get(param);
|
||||
builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
|
||||
}
|
||||
}
|
||||
|
||||
switch(builders.size()) {
|
||||
case 0:
|
||||
argsBuilder = EndpointArgumentsBuilder.NONE;
|
||||
break;
|
||||
case 1:
|
||||
argsBuilder = builders.get(0);
|
||||
break;
|
||||
default:
|
||||
argsBuilder = new EndpointArgumentsBuilder.Composite(builders);
|
||||
}
|
||||
return argsBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare objects for creating response {@link Message}
|
||||
*/
|
||||
private EndpointResponseMessageBuilder createResponseMessageBuilder(List<MessageFiller> fillers) {
|
||||
|
||||
EndpointResponseMessageBuilder tmpBodyBuilder = null;
|
||||
List<ParameterImpl> rp = javaMethodModel.getResponseParameters();
|
||||
|
||||
for (ParameterImpl param : rp) {
|
||||
ValueGetter getter = ValueGetter.get(param);
|
||||
|
||||
switch(param.getOutBinding().kind) {
|
||||
case BODY:
|
||||
if(param.isWrapperStyle()) {
|
||||
if(param.getParent().getBinding().isRpcLit()) {
|
||||
tmpBodyBuilder = new EndpointResponseMessageBuilder.RpcLit((WrapperParameter)param,
|
||||
soapVersion);
|
||||
} else {
|
||||
tmpBodyBuilder = new EndpointResponseMessageBuilder.DocLit((WrapperParameter)param,
|
||||
soapVersion);
|
||||
}
|
||||
} else {
|
||||
tmpBodyBuilder = new EndpointResponseMessageBuilder.Bare(param, soapVersion);
|
||||
}
|
||||
break;
|
||||
case HEADER:
|
||||
fillers.add(new MessageFiller.Header(param.getIndex(), param.getXMLBridge(), getter ));
|
||||
break;
|
||||
case ATTACHMENT:
|
||||
fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
|
||||
break;
|
||||
case UNBOUND:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError(); // impossible
|
||||
}
|
||||
}
|
||||
|
||||
if (tmpBodyBuilder == null) {
|
||||
// no parameter binds to body. we create an empty message
|
||||
switch(soapVersion) {
|
||||
case SOAP_11:
|
||||
tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP11;
|
||||
break;
|
||||
case SOAP_12:
|
||||
tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP12;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
return tmpBodyBuilder;
|
||||
}
|
||||
|
||||
public Object[] readRequest(Message reqMsg) {
|
||||
Object[] args = new Object[noOfArgs];
|
||||
try {
|
||||
argumentsBuilder.readRequest(reqMsg,args);
|
||||
} catch (JAXBException e) {
|
||||
throw new WebServiceException(e);
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
public Message createResponse(JavaCallInfo call) {
|
||||
Message responseMessage;
|
||||
if (call.getException() == null) {
|
||||
responseMessage = isOneWay ? null : createResponseMessage(call.getParameters(), call.getReturnValue());
|
||||
} else {
|
||||
Throwable e = call.getException();
|
||||
Throwable serviceException = getServiceException(e);
|
||||
if (e instanceof InvocationTargetException || serviceException != null) {
|
||||
// Throwable cause = e.getCause();
|
||||
//if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
|
||||
if (serviceException != null) {
|
||||
// Service specific exception
|
||||
LOGGER.log(Level.FINE, serviceException.getMessage(), serviceException);
|
||||
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion,
|
||||
javaMethodModel.getCheckedException(serviceException.getClass()), serviceException);
|
||||
} else {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof ProtocolException) {
|
||||
// Application code may be throwing it intentionally
|
||||
LOGGER.log(Level.FINE, cause.getMessage(), cause);
|
||||
} else {
|
||||
// Probably some bug in application code
|
||||
LOGGER.log(Level.SEVERE, cause.getMessage(), cause);
|
||||
}
|
||||
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, cause);
|
||||
}
|
||||
} else if (e instanceof DispatchException) {
|
||||
responseMessage = ((DispatchException)e).fault;
|
||||
} else {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
|
||||
}
|
||||
}
|
||||
// return req.createServerResponse(responseMessage, req.endpoint.getPort(), javaMethodModel.getOwner(), req.endpoint.getBinding());
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
Throwable getServiceException(Throwable throwable) {
|
||||
if (javaMethodModel.getCheckedException(throwable.getClass()) != null) return throwable;
|
||||
if (throwable.getCause() != null) {
|
||||
Throwable cause = throwable.getCause();
|
||||
// if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
|
||||
if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
|
||||
// }
|
||||
// if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a response {@link JAXBMessage} from method arguments, return value
|
||||
*
|
||||
* @return response message
|
||||
*/
|
||||
private Message createResponseMessage(Object[] args, Object returnValue) {
|
||||
Message msg = bodyBuilder.createMessage(args, returnValue);
|
||||
|
||||
for (MessageFiller filler : outFillers)
|
||||
filler.fillIn(args, returnValue, msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TieHandler.class.getName());
|
||||
|
||||
@Override
|
||||
public JavaCallInfo deserializeRequest(Packet req) {
|
||||
com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo();
|
||||
call.setMethod(this.getMethod());
|
||||
Object[] args = this.readRequest(req.getMessage());
|
||||
call.setParameters(args);
|
||||
return call;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet serializeResponse(JavaCallInfo call) {
|
||||
Message msg = this.createResponse(call);
|
||||
Packet p = (msg == null) ? (Packet)packetFactory.createContext() : (Packet)packetFactory.createContext(msg);
|
||||
p.setState(Packet.State.ServerResponse);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaMethod getOperationModel() {
|
||||
return javaMethodModel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.sei;
|
||||
|
||||
import com.sun.xml.internal.ws.model.ParameterImpl;
|
||||
import com.sun.xml.internal.ws.api.model.Parameter;
|
||||
|
||||
import javax.jws.WebParam.Mode;
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
/**
|
||||
* Gets a value from an object that represents a parameter passed
|
||||
* as a method argument.
|
||||
*
|
||||
* <p>
|
||||
* This abstraction hides the handling of {@link Holder}.
|
||||
*
|
||||
* <p>
|
||||
* {@link ValueGetter} is a stateless behavior encapsulation.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public enum ValueGetter {
|
||||
/**
|
||||
* {@link ValueGetter} that works for {@link Mode#IN} parameter.
|
||||
*
|
||||
* <p>
|
||||
* Since it's the IN mode, the parameter is not a {@link Holder},
|
||||
* therefore the parameter itself is a value.
|
||||
*/
|
||||
PLAIN() {
|
||||
public Object get(Object parameter) {
|
||||
return parameter;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Creates {@link ValueGetter} that works for {@link Holder},
|
||||
* which is {@link Mode#INOUT} or {@link Mode#OUT}.
|
||||
*
|
||||
* <p>
|
||||
* In those {@link Mode}s, the parameter is a {@link Holder},
|
||||
* so the value to be sent is obtained by getting the value of the holder.
|
||||
*/
|
||||
HOLDER() {
|
||||
public Object get(Object parameter) {
|
||||
if(parameter==null)
|
||||
// the user is allowed to pass in null where a Holder is expected.
|
||||
return null;
|
||||
return ((Holder)parameter).value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the value to be sent, from a parameter given as a method argument.
|
||||
*/
|
||||
public abstract Object get(Object parameter);
|
||||
|
||||
/**
|
||||
* Returns a {@link ValueGetter} suitable for the given {@link Parameter}.
|
||||
*/
|
||||
public static ValueGetter get(ParameterImpl p) {
|
||||
// return value is always PLAIN
|
||||
if(p.getMode() == Mode.IN || p.getIndex() == -1) {
|
||||
return PLAIN;
|
||||
} else {
|
||||
return HOLDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user