aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.server; aoqi@0: aoqi@0: import com.sun.istack.internal.NotNull; aoqi@0: import com.sun.istack.internal.Nullable; aoqi@0: import com.sun.xml.internal.stream.buffer.XMLStreamBuffer; aoqi@0: import com.sun.xml.internal.ws.addressing.EPRSDDocumentFilter; aoqi@0: import com.sun.xml.internal.ws.addressing.WSEPRExtension; aoqi@0: import com.sun.xml.internal.ws.api.Component; aoqi@0: import com.sun.xml.internal.ws.api.ComponentFeature; aoqi@0: import com.sun.xml.internal.ws.api.ComponentsFeature; aoqi@0: import com.sun.xml.internal.ws.api.SOAPVersion; aoqi@0: import com.sun.xml.internal.ws.api.WSBinding; aoqi@0: import com.sun.xml.internal.ws.api.addressing.AddressingVersion; aoqi@0: import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; aoqi@0: import com.sun.xml.internal.ws.api.message.Message; aoqi@0: import com.sun.xml.internal.ws.api.message.Packet; aoqi@0: import com.sun.xml.internal.ws.api.model.SEIModel; aoqi@0: import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; aoqi@0: import com.sun.xml.internal.ws.api.pipe.*; aoqi@0: import com.sun.xml.internal.ws.api.server.*; aoqi@0: import com.sun.xml.internal.ws.binding.BindingImpl; aoqi@0: import com.sun.xml.internal.ws.fault.SOAPFaultBuilder; aoqi@0: import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties; aoqi@0: import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties; aoqi@0: import com.sun.xml.internal.ws.model.wsdl.WSDLProperties; aoqi@0: import com.sun.xml.internal.ws.policy.PolicyMap; aoqi@0: import com.sun.xml.internal.ws.resources.HandlerMessages; aoqi@0: import com.sun.xml.internal.ws.util.Pool; aoqi@0: import com.sun.xml.internal.ws.util.Pool.TubePool; aoqi@0: import com.sun.xml.internal.ws.util.ServiceFinder; aoqi@0: import com.sun.xml.internal.ws.wsdl.OperationDispatcher; aoqi@0: import com.sun.org.glassfish.gmbal.ManagedObjectManager; aoqi@0: import org.w3c.dom.Element; aoqi@0: aoqi@0: import javax.annotation.PreDestroy; aoqi@0: import javax.xml.namespace.QName; aoqi@0: import javax.xml.stream.XMLStreamException; aoqi@0: import javax.xml.ws.EndpointReference; aoqi@0: import javax.xml.ws.WebServiceException; aoqi@0: import javax.xml.ws.handler.Handler; aoqi@0: import java.lang.reflect.Method; aoqi@0: import java.util.*; aoqi@0: import java.util.concurrent.CopyOnWriteArraySet; aoqi@0: import java.util.concurrent.Executor; aoqi@0: import java.util.logging.Level; aoqi@0: import java.util.logging.Logger; aoqi@0: import javax.management.ObjectName; aoqi@0: aoqi@0: /** aoqi@0: * {@link WSEndpoint} implementation. aoqi@0: * aoqi@0: * @author Kohsuke Kawaguchi aoqi@0: * @author Jitendra Kotamraju aoqi@0: */ aoqi@0: public /*final*/ class WSEndpointImpl extends WSEndpoint implements LazyMOMProvider.WSEndpointScopeChangeListener { aoqi@0: aoqi@0: private static final Logger logger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint"); aoqi@0: aoqi@0: private final @NotNull QName serviceName; aoqi@0: private final @NotNull QName portName; aoqi@0: protected final WSBinding binding; aoqi@0: private final SEIModel seiModel; aoqi@0: private final @NotNull Container container; aoqi@0: private final WSDLPort port; aoqi@0: aoqi@0: protected final Tube masterTubeline; aoqi@0: private final ServiceDefinitionImpl serviceDef; aoqi@0: private final SOAPVersion soapVersion; aoqi@0: private final Engine engine; aoqi@0: private final @NotNull Codec masterCodec; aoqi@0: private final @NotNull PolicyMap endpointPolicy; aoqi@0: private final Pool tubePool; aoqi@0: private final OperationDispatcher operationDispatcher; aoqi@0: private @NotNull ManagedObjectManager managedObjectManager; aoqi@0: private boolean managedObjectManagerClosed = false; aoqi@0: private final Object managedObjectManagerLock = new Object(); aoqi@0: private LazyMOMProvider.Scope lazyMOMProviderScope = LazyMOMProvider.Scope.STANDALONE; aoqi@0: private final @NotNull ServerTubeAssemblerContext context; aoqi@0: aoqi@0: private Map endpointReferenceExtensions = new HashMap(); aoqi@0: /** aoqi@0: * Set to true once we start shutting down this endpoint. Used to avoid aoqi@0: * running the clean up processing twice. aoqi@0: * aoqi@0: * @see #dispose() aoqi@0: */ aoqi@0: private boolean disposed; aoqi@0: private final Class implementationClass; aoqi@0: private final @NotNull aoqi@0: WSDLProperties wsdlProperties; aoqi@0: private final Set componentRegistry = new CopyOnWriteArraySet(); aoqi@0: aoqi@0: protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding, aoqi@0: Container container, SEIModel seiModel, WSDLPort port, aoqi@0: Class implementationClass, aoqi@0: @Nullable ServiceDefinitionImpl serviceDef, aoqi@0: EndpointAwareTube terminalTube, boolean isSynchronous, aoqi@0: PolicyMap endpointPolicy) { aoqi@0: this.serviceName = serviceName; aoqi@0: this.portName = portName; aoqi@0: this.binding = binding; aoqi@0: this.soapVersion = binding.getSOAPVersion(); aoqi@0: this.container = container; aoqi@0: this.port = port; aoqi@0: this.implementationClass = implementationClass; aoqi@0: this.serviceDef = serviceDef; aoqi@0: this.seiModel = seiModel; aoqi@0: this.endpointPolicy = endpointPolicy; aoqi@0: aoqi@0: LazyMOMProvider.INSTANCE.registerEndpoint(this); aoqi@0: initManagedObjectManager(); aoqi@0: aoqi@0: if (serviceDef != null) { aoqi@0: serviceDef.setOwner(this); aoqi@0: } aoqi@0: aoqi@0: ComponentFeature cf = binding.getFeature(ComponentFeature.class); aoqi@0: if (cf != null) { aoqi@0: switch (cf.getTarget()) { aoqi@0: case ENDPOINT: aoqi@0: componentRegistry.add(cf.getComponent()); aoqi@0: break; aoqi@0: case CONTAINER: aoqi@0: container.getComponents().add(cf.getComponent()); aoqi@0: break; aoqi@0: default: aoqi@0: throw new IllegalArgumentException(); aoqi@0: } aoqi@0: } aoqi@0: ComponentsFeature csf = binding.getFeature(ComponentsFeature.class); aoqi@0: if (csf != null) { aoqi@0: for (ComponentFeature cfi : csf.getComponentFeatures()) { aoqi@0: switch (cfi.getTarget()) { aoqi@0: case ENDPOINT: aoqi@0: componentRegistry.add(cfi.getComponent()); aoqi@0: break; aoqi@0: case CONTAINER: aoqi@0: container.getComponents().add(cfi.getComponent()); aoqi@0: break; aoqi@0: default: aoqi@0: throw new IllegalArgumentException(); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: TubelineAssembler assembler = TubelineAssemblerFactory.create( aoqi@0: Thread.currentThread().getContextClassLoader(), binding.getBindingId(), container); aoqi@0: assert assembler != null; aoqi@0: aoqi@0: this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel); aoqi@0: aoqi@0: context = createServerTubeAssemblerContext(terminalTube, isSynchronous); aoqi@0: this.masterTubeline = assembler.createServer(context); aoqi@0: aoqi@0: Codec c = context.getCodec(); aoqi@0: if (c instanceof EndpointAwareCodec) { aoqi@0: // create a copy to avoid sharing the codec between multiple endpoints aoqi@0: c = c.copy(); aoqi@0: ((EndpointAwareCodec) c).setEndpoint(this); aoqi@0: } aoqi@0: this.masterCodec = c; aoqi@0: aoqi@0: tubePool = new TubePool(masterTubeline); aoqi@0: terminalTube.setEndpoint(this); aoqi@0: engine = new Engine(toString(), container); aoqi@0: wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel); aoqi@0: aoqi@0: Map eprExtensions = new HashMap(); aoqi@0: try { aoqi@0: if (port != null) { aoqi@0: //gather EPR extrensions from WSDL Model aoqi@0: WSEndpointReference wsdlEpr = port.getEPR(); aoqi@0: if (wsdlEpr != null) { aoqi@0: for (WSEndpointReference.EPRExtension extnEl : wsdlEpr.getEPRExtensions()) { aoqi@0: eprExtensions.put(extnEl.getQName(), extnEl); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: EndpointReferenceExtensionContributor[] eprExtnContributors = ServiceFinder.find(EndpointReferenceExtensionContributor.class).toArray(); aoqi@0: for(EndpointReferenceExtensionContributor eprExtnContributor :eprExtnContributors) { aoqi@0: WSEndpointReference.EPRExtension wsdlEPRExtn = eprExtensions.remove(eprExtnContributor.getQName()); aoqi@0: WSEndpointReference.EPRExtension endpointEprExtn = eprExtnContributor.getEPRExtension(this,wsdlEPRExtn); aoqi@0: if (endpointEprExtn != null) { aoqi@0: eprExtensions.put(endpointEprExtn.getQName(), endpointEprExtn); aoqi@0: } aoqi@0: } aoqi@0: for (WSEndpointReference.EPRExtension extn : eprExtensions.values()) { aoqi@0: endpointReferenceExtensions.put(extn.getQName(), new WSEPRExtension( aoqi@0: XMLStreamBuffer.createNewBufferFromXMLStreamReader(extn.readAsXMLStreamReader()),extn.getQName())); aoqi@0: } aoqi@0: } catch (XMLStreamException ex) { aoqi@0: throw new WebServiceException(ex); aoqi@0: } aoqi@0: if(!eprExtensions.isEmpty()) { aoqi@0: serviceDef.addFilter(new EPRSDDocumentFilter(this)); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: protected ServerTubeAssemblerContext createServerTubeAssemblerContext( aoqi@0: EndpointAwareTube terminalTube, boolean isSynchronous) { aoqi@0: ServerTubeAssemblerContext ctx = new ServerPipeAssemblerContext( aoqi@0: seiModel, port, this, terminalTube, isSynchronous); aoqi@0: return ctx; aoqi@0: } aoqi@0: aoqi@0: protected WSEndpointImpl(@NotNull QName serviceName, @NotNull QName portName, WSBinding binding, Container container, aoqi@0: SEIModel seiModel, WSDLPort port, aoqi@0: Tube masterTubeline) { aoqi@0: this.serviceName = serviceName; aoqi@0: this.portName = portName; aoqi@0: this.binding = binding; aoqi@0: this.soapVersion = binding.getSOAPVersion(); aoqi@0: this.container = container; aoqi@0: this.endpointPolicy = null; aoqi@0: this.port = port; aoqi@0: this.seiModel = seiModel; aoqi@0: this.serviceDef = null; aoqi@0: this.implementationClass = null; aoqi@0: this.masterTubeline = masterTubeline; aoqi@0: this.masterCodec = ((BindingImpl) this.binding).createCodec(); aoqi@0: aoqi@0: LazyMOMProvider.INSTANCE.registerEndpoint(this); aoqi@0: initManagedObjectManager(); aoqi@0: aoqi@0: this.operationDispatcher = (port == null) ? null : new OperationDispatcher(port, binding, seiModel); aoqi@0: this.context = new ServerPipeAssemblerContext( aoqi@0: seiModel, port, this, null /* not known */, false); aoqi@0: aoqi@0: tubePool = new TubePool(masterTubeline); aoqi@0: engine = new Engine(toString(), container); aoqi@0: wsdlProperties = (port == null) ? new WSDLDirectProperties(serviceName, portName, seiModel) : new WSDLPortProperties(port, seiModel); aoqi@0: } aoqi@0: aoqi@0: public Collection getEndpointReferenceExtensions() { aoqi@0: return endpointReferenceExtensions.values(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Nullable when there is no associated WSDL Model aoqi@0: * @return aoqi@0: */ aoqi@0: public @Nullable OperationDispatcher getOperationDispatcher() { aoqi@0: return operationDispatcher; aoqi@0: } aoqi@0: aoqi@0: public PolicyMap getPolicyMap() { aoqi@0: return endpointPolicy; aoqi@0: } aoqi@0: aoqi@0: public @NotNull Class getImplementationClass() { aoqi@0: return implementationClass; aoqi@0: } aoqi@0: aoqi@0: public @NotNull WSBinding getBinding() { aoqi@0: return binding; aoqi@0: } aoqi@0: aoqi@0: public @NotNull Container getContainer() { aoqi@0: return container; aoqi@0: } aoqi@0: aoqi@0: public WSDLPort getPort() { aoqi@0: return port; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public @Nullable SEIModel getSEIModel() { aoqi@0: return seiModel; aoqi@0: } aoqi@0: aoqi@0: public void setExecutor(Executor exec) { aoqi@0: engine.setExecutor(exec); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public Engine getEngine() { aoqi@0: return engine; aoqi@0: } aoqi@0: aoqi@0: public void schedule(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) { aoqi@0: processAsync(request, callback, interceptor, true); aoqi@0: } aoqi@0: aoqi@0: private void processAsync(final Packet request, aoqi@0: final CompletionCallback callback, aoqi@0: FiberContextSwitchInterceptor interceptor, boolean schedule) { aoqi@0: Container old = ContainerResolver.getDefault().enterContainer(container); aoqi@0: try { aoqi@0: request.endpoint = WSEndpointImpl.this; aoqi@0: request.addSatellite(wsdlProperties); aoqi@0: aoqi@0: Fiber fiber = engine.createFiber(); aoqi@0: fiber.setDeliverThrowableInPacket(true); aoqi@0: if (interceptor != null) { aoqi@0: fiber.addInterceptor(interceptor); aoqi@0: } aoqi@0: final Tube tube = tubePool.take(); aoqi@0: Fiber.CompletionCallback cbak = new Fiber.CompletionCallback() { aoqi@0: public void onCompletion(@NotNull Packet response) { aoqi@0: ThrowableContainerPropertySet tc = response.getSatellite(ThrowableContainerPropertySet.class); aoqi@0: if (tc == null) { aoqi@0: // Only recycle tubes in non-exception path as some Tubes may be aoqi@0: // in invalid state following exception aoqi@0: tubePool.recycle(tube); aoqi@0: } aoqi@0: aoqi@0: if (callback != null) { aoqi@0: if (tc != null) { aoqi@0: response = createServiceResponseForException(tc, aoqi@0: response, aoqi@0: soapVersion, aoqi@0: request.endpoint.getPort(), aoqi@0: null, aoqi@0: request.endpoint.getBinding()); aoqi@0: } aoqi@0: callback.onCompletion(response); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public void onCompletion(@NotNull Throwable error) { aoqi@0: // will never be called now that we are using aoqi@0: // fiber.setDeliverThrowableInPacket(true); aoqi@0: throw new IllegalStateException(); aoqi@0: } aoqi@0: }; aoqi@0: aoqi@0: fiber.start(tube, request, cbak, aoqi@0: binding.isFeatureEnabled(SyncStartForAsyncFeature.class) aoqi@0: || !schedule); aoqi@0: } finally { aoqi@0: ContainerResolver.getDefault().exitContainer(old); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public Packet createServiceResponseForException(final ThrowableContainerPropertySet tc, aoqi@0: final Packet responsePacket, aoqi@0: final SOAPVersion soapVersion, aoqi@0: final WSDLPort wsdlPort, aoqi@0: final SEIModel seiModel, aoqi@0: final WSBinding binding) aoqi@0: { aoqi@0: // This will happen in addressing if it is enabled. aoqi@0: if (tc.isFaultCreated()) return responsePacket; aoqi@0: aoqi@0: final Message faultMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, tc.getThrowable()); aoqi@0: final Packet result = responsePacket.createServerResponse(faultMessage, wsdlPort, seiModel, binding); aoqi@0: // Pass info to upper layers aoqi@0: tc.setFaultMessage(faultMessage); aoqi@0: tc.setResponsePacket(responsePacket); aoqi@0: tc.setFaultCreated(true); aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public void process(final Packet request, final CompletionCallback callback, FiberContextSwitchInterceptor interceptor) { aoqi@0: processAsync(request, callback, interceptor, false); aoqi@0: } aoqi@0: aoqi@0: public @NotNull aoqi@0: PipeHead createPipeHead() { aoqi@0: return new PipeHead() { aoqi@0: private final Tube tube = TubeCloner.clone(masterTubeline); aoqi@0: aoqi@0: public @NotNull aoqi@0: Packet process(Packet request, WebServiceContextDelegate wscd, aoqi@0: TransportBackChannel tbc) { aoqi@0: Container old = ContainerResolver.getDefault().enterContainer(container); aoqi@0: try { aoqi@0: request.webServiceContextDelegate = wscd; aoqi@0: request.transportBackChannel = tbc; aoqi@0: request.endpoint = WSEndpointImpl.this; aoqi@0: request.addSatellite(wsdlProperties); aoqi@0: aoqi@0: Fiber fiber = engine.createFiber(); aoqi@0: Packet response; aoqi@0: try { aoqi@0: response = fiber.runSync(tube, request); aoqi@0: } catch (RuntimeException re) { aoqi@0: // Catch all runtime exceptions so that transport aoqi@0: // doesn't aoqi@0: // have to worry about converting to wire message aoqi@0: // TODO XML/HTTP binding aoqi@0: Message faultMsg = SOAPFaultBuilder aoqi@0: .createSOAPFaultMessage(soapVersion, null, re); aoqi@0: response = request.createServerResponse(faultMsg, aoqi@0: request.endpoint.getPort(), null, aoqi@0: request.endpoint.getBinding()); aoqi@0: } aoqi@0: return response; aoqi@0: } finally { aoqi@0: ContainerResolver.getDefault().exitContainer(old); aoqi@0: } aoqi@0: } aoqi@0: }; aoqi@0: } aoqi@0: aoqi@0: public synchronized void dispose() { aoqi@0: if (disposed) { aoqi@0: return; aoqi@0: } aoqi@0: disposed = true; aoqi@0: aoqi@0: masterTubeline.preDestroy(); aoqi@0: aoqi@0: for (Handler handler : binding.getHandlerChain()) { aoqi@0: for (Method method : handler.getClass().getMethods()) { aoqi@0: if (method.getAnnotation(PreDestroy.class) == null) { aoqi@0: continue; aoqi@0: } aoqi@0: try { aoqi@0: method.invoke(handler); aoqi@0: } catch (Exception e) { aoqi@0: logger.log(Level.WARNING, HandlerMessages.HANDLER_PREDESTROY_IGNORE(e.getMessage()), e); aoqi@0: } aoqi@0: break; aoqi@0: } aoqi@0: } aoqi@0: closeManagedObjectManager(); aoqi@0: LazyMOMProvider.INSTANCE.unregisterEndpoint(this); aoqi@0: } aoqi@0: aoqi@0: public ServiceDefinitionImpl getServiceDefinition() { aoqi@0: return serviceDef; aoqi@0: } aoqi@0: aoqi@0: public Set getComponentRegistry() { aoqi@0: Set sec = new EndpointComponentSet(); aoqi@0: for (Component c : componentRegistry) { aoqi@0: sec.add(c instanceof EndpointComponentWrapper ? aoqi@0: ((EndpointComponentWrapper) c).component : aoqi@0: new ComponentWrapper(c)); aoqi@0: } aoqi@0: return sec; aoqi@0: } aoqi@0: aoqi@0: private class EndpointComponentSet extends HashSet { aoqi@0: aoqi@0: @Override aoqi@0: public Iterator iterator() { aoqi@0: final Iterator it = super.iterator(); aoqi@0: return new Iterator() { aoqi@0: private EndpointComponent last = null; aoqi@0: aoqi@0: public boolean hasNext() { aoqi@0: return it.hasNext(); aoqi@0: } aoqi@0: aoqi@0: public EndpointComponent next() { aoqi@0: last = it.next(); aoqi@0: return last; aoqi@0: } aoqi@0: aoqi@0: public void remove() { aoqi@0: it.remove(); aoqi@0: if (last != null) { aoqi@0: componentRegistry.remove(last instanceof ComponentWrapper ? aoqi@0: ((ComponentWrapper) last).component : aoqi@0: new EndpointComponentWrapper(last)); aoqi@0: } aoqi@0: last = null; aoqi@0: } aoqi@0: }; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public boolean add(EndpointComponent e) { aoqi@0: boolean result = super.add(e); aoqi@0: if (result) { aoqi@0: componentRegistry.add(new EndpointComponentWrapper(e)); aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public boolean remove(Object o) { aoqi@0: boolean result = super.remove(o); aoqi@0: if (result) { aoqi@0: componentRegistry.remove(o instanceof ComponentWrapper ? aoqi@0: ((ComponentWrapper) o).component : aoqi@0: new EndpointComponentWrapper((EndpointComponent)o)); aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: } aoqi@0: aoqi@0: private static class ComponentWrapper implements EndpointComponent { aoqi@0: private final Component component; aoqi@0: aoqi@0: public ComponentWrapper(Component component) { aoqi@0: this.component = component; aoqi@0: } aoqi@0: aoqi@0: public S getSPI(Class spiType) { aoqi@0: return component.getSPI(spiType); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public int hashCode() { aoqi@0: return component.hashCode(); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public boolean equals(Object obj) { aoqi@0: return component.equals(obj); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: private static class EndpointComponentWrapper implements Component { aoqi@0: private final EndpointComponent component; aoqi@0: aoqi@0: public EndpointComponentWrapper(EndpointComponent component) { aoqi@0: this.component = component; aoqi@0: } aoqi@0: aoqi@0: public S getSPI(Class spiType) { aoqi@0: return component.getSPI(spiType); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public int hashCode() { aoqi@0: return component.hashCode(); aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public boolean equals(Object obj) { aoqi@0: return component.equals(obj); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public @NotNull Set getComponents() { aoqi@0: return componentRegistry; aoqi@0: } aoqi@0: aoqi@0: public T getEndpointReference(Class clazz, String address, String wsdlAddress, Element... referenceParameters) { aoqi@0: List refParams = null; aoqi@0: if (referenceParameters != null) { aoqi@0: refParams = Arrays.asList(referenceParameters); aoqi@0: } aoqi@0: return getEndpointReference(clazz, address, wsdlAddress, null, refParams); aoqi@0: } aoqi@0: aoqi@0: public T getEndpointReference(Class clazz, aoqi@0: String address, String wsdlAddress, List metadata, aoqi@0: List referenceParameters) { aoqi@0: QName portType = null; aoqi@0: if (port != null) { aoqi@0: portType = port.getBinding().getPortTypeName(); aoqi@0: } aoqi@0: aoqi@0: AddressingVersion av = AddressingVersion.fromSpecClass(clazz); aoqi@0: return new WSEndpointReference( aoqi@0: av, address, serviceName, portName, portType, metadata, wsdlAddress, referenceParameters, endpointReferenceExtensions.values(), null).toSpec(clazz); aoqi@0: aoqi@0: } aoqi@0: aoqi@0: public @NotNull QName getPortName() { aoqi@0: return portName; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: public @NotNull Codec createCodec() { aoqi@0: return masterCodec.copy(); aoqi@0: } aoqi@0: aoqi@0: public @NotNull QName getServiceName() { aoqi@0: return serviceName; aoqi@0: } aoqi@0: aoqi@0: private void initManagedObjectManager() { aoqi@0: synchronized (managedObjectManagerLock) { aoqi@0: if (managedObjectManager == null) { aoqi@0: switch (this.lazyMOMProviderScope) { aoqi@0: case GLASSFISH_NO_JMX: aoqi@0: managedObjectManager = new WSEndpointMOMProxy(this); aoqi@0: break; aoqi@0: default: aoqi@0: managedObjectManager = obtainManagedObjectManager(); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public @NotNull ManagedObjectManager getManagedObjectManager() { aoqi@0: return managedObjectManager; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Obtains a real instance of {@code ManagedObjectManager} class no matter what lazyMOMProviderScope is this endpoint in (or if the aoqi@0: * Gmbal API calls should be deferred). aoqi@0: * aoqi@0: * @see com.sun.xml.internal.ws.api.server.LazyMOMProvider.Scope aoqi@0: * @return an instance of {@code ManagedObjectManager} aoqi@0: */ aoqi@0: @NotNull ManagedObjectManager obtainManagedObjectManager() { aoqi@0: final MonitorRootService monitorRootService = new MonitorRootService(this); aoqi@0: final ManagedObjectManager mOM = monitorRootService.createManagedObjectManager(this); aoqi@0: aoqi@0: // ManagedObjectManager was suspended due to root creation (see MonitorBase#initMOM) aoqi@0: mOM.resumeJMXRegistration(); aoqi@0: aoqi@0: return mOM; aoqi@0: } aoqi@0: aoqi@0: public void scopeChanged(LazyMOMProvider.Scope scope) { aoqi@0: synchronized (managedObjectManagerLock) { aoqi@0: if (managedObjectManagerClosed) { aoqi@0: return; aoqi@0: } aoqi@0: aoqi@0: this.lazyMOMProviderScope = scope; aoqi@0: aoqi@0: // possible lazyMOMProviderScope change can be LazyMOMProvider.Scope.GLASSFISH_NO_JMX or LazyMOMProvider.Scope.GLASSFISH_JMX aoqi@0: if (managedObjectManager == null) { aoqi@0: if (scope != LazyMOMProvider.Scope.GLASSFISH_NO_JMX) { aoqi@0: managedObjectManager = obtainManagedObjectManager(); aoqi@0: } else { aoqi@0: managedObjectManager = new WSEndpointMOMProxy(this); aoqi@0: } aoqi@0: } else { aoqi@0: // if ManagedObjectManager for this endpoint has already been created and is uninitialized proxy then aoqi@0: // fill it with a real instance aoqi@0: if (managedObjectManager instanceof WSEndpointMOMProxy aoqi@0: && !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) { aoqi@0: ((WSEndpointMOMProxy)managedObjectManager).setManagedObjectManager(obtainManagedObjectManager()); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring"); aoqi@0: aoqi@0: // This can be called independently of WSEndpoint.dispose. aoqi@0: // Example: the WSCM framework calls this before dispose. aoqi@0: @Override aoqi@0: public void closeManagedObjectManager() { aoqi@0: synchronized (managedObjectManagerLock) { aoqi@0: if (managedObjectManagerClosed == true) { aoqi@0: return; aoqi@0: } aoqi@0: if (managedObjectManager != null) { aoqi@0: boolean close = true; aoqi@0: aoqi@0: // ManagedObjectManager doesn't need to be closed because it exists only as a proxy aoqi@0: if (managedObjectManager instanceof WSEndpointMOMProxy aoqi@0: && !((WSEndpointMOMProxy)managedObjectManager).isInitialized()) { aoqi@0: close = false; aoqi@0: } aoqi@0: aoqi@0: if (close) { aoqi@0: try { aoqi@0: final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot()); aoqi@0: // The name is null when the MOM is a NOOP. aoqi@0: if (name != null) { aoqi@0: monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name); aoqi@0: } aoqi@0: managedObjectManager.close(); aoqi@0: } catch (java.io.IOException e) { aoqi@0: monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: managedObjectManagerClosed = true; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public @NotNull @Override ServerTubeAssemblerContext getAssemblerContext() { aoqi@0: return context; aoqi@0: } aoqi@0: }