FileDocCategorySizeDatePackage
EjbRuntimeEndpointInfo.javaAPI DocGlassfish v2 API18237Fri Jun 01 09:21:52 BST 2007com.sun.enterprise.webservice

EjbRuntimeEndpointInfo

public class EjbRuntimeEndpointInfo extends Object
Runtime dispatch information about one ejb web service endpoint. This class must support concurrent access, since a single instance will be used for all web service invocations through the same ejb endpoint.

NOT THREAD SAFE

author
Jerome Dochez

Fields Summary
protected static final Logger
logger
protected final com.sun.enterprise.deployment.WebServiceEndpoint
endpoint
protected final com.sun.ejb.containers.StatelessSessionContainer
container
protected final Object
webServiceEndpointServant
protected final com.sun.enterprise.InvocationManager
invManager
private com.sun.xml.ws.transport.http.servlet.ServletAdapter
adapter
private com.sun.xml.ws.transport.http.servlet.ServletAdapterList
adapterList
private WebServiceContextImpl
wsCtxt
private boolean
handlersConfigured
protected EjbMessageDispatcher
messageDispatcher
Constructors Summary
public EjbRuntimeEndpointInfo(com.sun.enterprise.deployment.WebServiceEndpoint webServiceEndpoint, com.sun.ejb.containers.StatelessSessionContainer ejbContainer, Object servant)


      
                                    
                                    
                                  
        endpoint = webServiceEndpoint;
        container  = ejbContainer;
        webServiceEndpointServant = servant;

        Switch theSwitch = Switch.getSwitch();
        invManager = theSwitch.getInvocationManager();
    
Methods Summary
public com.sun.ejb.ContainergetContainer()

        return container;
    
public com.sun.enterprise.deployment.WebServiceEndpointgetEndpoint()

        return endpoint;
    
public java.lang.StringgetEndpointAddressUri()

        return endpoint.getEndpointAddressUri();
    
public EjbMessageDispatchergetMessageDispatcher()

        if (messageDispatcher==null) {
            messageDispatcher = new Ejb3MessageDispatcher();            
        }
        return messageDispatcher;
    
public javax.xml.ws.WebServiceContextgetWebServiceContext()

        return wsCtxt;
    
public voidinitRuntimeInfo(com.sun.xml.ws.transport.http.servlet.ServletAdapterList list)
Force initialization of the endpoint runtime information as well as the handlers injection

 
        try { 
            this.adapterList = list;
            prepareInvocation(true); 
        } finally { 
            invManager.postInvoke(invManager.getCurrentInvocation()); 
        } 
         
    
public java.lang.ObjectprepareInvocation(boolean doPreInvoke)


        // For proper injection of handlers, we have to configure handler
        // after invManager.preInvoke but the Invocation.contextData has to be set
        // before invManager.preInvoke. So the steps of configuring jaxws handlers and 
        // init'ing jaxws is done here - this sequence is important
        if (adapter==null) {
            synchronized(this) {
                if(adapter == null) {
                    try {
                        // Set webservice context here
                        // If the endpoint has a WebServiceContext with @Resource then
                        // that has to be used
                        Invocation tmpInv = new Invocation();
                        tmpInv.isWebService = true;
                        tmpInv.container = container;                
                        tmpInv.transactionAttribute = Container.TX_NOT_INITIALIZED;
                        invManager.preInvoke(tmpInv);
                        EjbDescriptor ejbDesc = endpoint.getEjbComponentImpl();
                        Iterator<ResourceReferenceDescriptor> it = ejbDesc.getResourceReferenceDescriptors().iterator();
                        while(it.hasNext()) {
                            ResourceReferenceDescriptor r = it.next();            
                            if(r.isWebServiceContext()) {
                                Iterator<InjectionTarget> iter = r.getInjectionTargets().iterator();
                                boolean matchingClassFound = false;
                                while(iter.hasNext()) {
                                    InjectionTarget target = iter.next();
                                    if(ejbDesc.getEjbClassName().equals(target.getClassName())) {
                                        matchingClassFound = true;
                                        break;
                                    }
                                }
                                if(!matchingClassFound) {
                                    continue;
                                }
                                try {
                                    javax.naming.InitialContext ic = new javax.naming.InitialContext();
                                    wsCtxt = (WebServiceContextImpl) ic.lookup("java:comp/env/" + r.getName());
                                } catch (Throwable t) {
                                    // Swallowed intentionally
                                }
                            }
                        }
                        if(wsCtxt == null) {
                            wsCtxt = new WebServiceContextImpl();
                        }
                    } catch (Throwable t) {
                        logger.severe("Cannot initialize endpoint " + endpoint.getName() + " : error is : " + t.getMessage());
                        return null;
                    } finally {
                        invManager.postInvoke(invManager.getCurrentInvocation());                         
                    }
                }
            }
        }
        
        if(doPreInvoke) {
                // We need to split the preInvoke tasks into stages since handlers
                // need access to java:comp/env and method authorization must take
                // place before handlers are run.  Note that the application 
                // classloader was set much earlier when the invocation first arrived
                // so we don't need to set it here.
                Invocation inv = new Invocation();

                // Do the portions of preInvoke that don't need a Method object.
                inv.isWebService = true;
                inv.container = container;                
                inv.transactionAttribute = Container.TX_NOT_INITIALIZED;

                // If the endpoint has at least one handler, method
                // authorization will be performed by a container-provided handler
                // before any application handler handleRequest methods are called.
                // Otherwise, the ejb container will do the authorization.
                inv.securityPermissions =  Container.SEC_NOT_INITIALIZED;

                // AS per latest spec change, the MessageContext object in WebSvcCtxt
                // should be the same one as used in the ejb's interceptors'        
                inv.setContextData(wsCtxt);
                
                // In all cases, the WebServiceInvocationHandler will do the
                // remaining preInvoke tasks : getContext, preInvokeTx, etc.
                invManager.preInvoke(inv);
        }

        // Now process handlers and init jaxws RI
        if(!handlersConfigured && doPreInvoke) {
            synchronized(this) {
                if(!handlersConfigured) {
                    try {
                        WsUtil wsu = new WsUtil();
                        String implClassName = endpoint.getEjbComponentImpl().getEjbClassName();
                        Class clazz = container.getClassLoader().loadClass(implClassName);

                        // Get the proper binding using BindingID
                        String givenBinding = endpoint.getProtocolBinding();

                        // Get list of all wsdls and schema
                        SDDocumentSource primaryWsdl = null;
                        Collection docs = null;
                        if(endpoint.getWebService().hasWsdlFile()) {
                            BaseManager mgr;
                            if(endpoint.getBundleDescriptor().getApplication().isVirtual()) {
                                mgr = DeploymentServiceUtils.getInstanceManager(DeployableObjectType.EJB);
                            } else {
                                mgr = DeploymentServiceUtils.getInstanceManager(DeployableObjectType.APP);
                            }
                            String deployedDir = 
                                mgr.getLocation(endpoint.getBundleDescriptor().getApplication().getRegistrationName());
                            File pkgedWsdl = null;
                            if(deployedDir != null) {
                                if(endpoint.getBundleDescriptor().getApplication().isVirtual()) {
                                    pkgedWsdl = new File(deployedDir+File.separator+
                                                endpoint.getWebService().getWsdlFileUri());
                                } else {
                                    pkgedWsdl = new File(deployedDir+File.separator+
                                            endpoint.getBundleDescriptor().getModuleDescriptor().getArchiveUri().replaceAll("\\.", "_") +
                                            File.separator + endpoint.getWebService().getWsdlFileUri());
                                }
                            } else {
                                pkgedWsdl = new File(endpoint.getWebService().getWsdlFileUrl().getFile());
                            }
                            if(pkgedWsdl.exists()) {
                                primaryWsdl = SDDocumentSource.create(pkgedWsdl.toURL());
                                docs = wsu.getWsdlsAndSchemas(pkgedWsdl);
                            }
                        }

                        // Create a Container to pass ServletContext and also inserting the pipe
                        JAXWSContainer container = new JAXWSContainer(null,
                                endpoint);

                        // Get catalog info
                        java.net.URL catalogURL = null;
                        File catalogFile = new File(endpoint.getBundleDescriptor().getDeploymentDescriptorDir() +
                                File.separator + "jax-ws-catalog.xml");
                        if(catalogFile.exists()) {
                            catalogURL = catalogFile.toURL();
                        }

                        // Create Binding and set service side handlers on this binding

                        boolean mtomEnabled = wsu.getMtom(endpoint);
                        WSBinding binding = null;
                        // Only if MTOm is enabled create the Binding with the MTOMFeature
                        if (mtomEnabled) {
                            MTOMFeature mtom = new MTOMFeature(true);
                            binding = BindingID.parse(givenBinding).createBinding(mtom);
                        } else {
                            binding = BindingID.parse(givenBinding).createBinding();
                        }
                        wsu.configureJAXWSServiceHandlers(endpoint, 
                            endpoint.getProtocolBinding(), binding);

                        // Create the jaxws2.1 invoker and use this
                        Invoker inv = new InstanceResolverImpl(clazz).createInvoker();
                        WSEndpoint wsep = WSEndpoint.create(
                                clazz, // The endpoint class
                                false, // we do not want JAXWS to process @HandlerChain
                                new EjbInvokerImpl(clazz, inv, webServiceEndpointServant, wsCtxt), // the invoker
                                endpoint.getServiceName(), // the service QName
                                endpoint.getWsdlPort(), // the port
                                container,
                                binding, // Derive binding
                                primaryWsdl, // primary WSDL
                                docs, // Collection of imported WSDLs and schema
                                catalogURL
                                );

                        String uri = endpoint.getEndpointAddressUri();
                        String urlPattern = uri.startsWith("/") ? uri : "/" + uri;
                        if(urlPattern.indexOf("/", 1) != -1) {
                            urlPattern = urlPattern.substring(urlPattern.indexOf("/", 1));
                        }

                        // All set; Create the adapter
                        if(adapterList == null) {
                            adapterList = new ServletAdapterList();
                        }
                        adapter = adapterList.createAdapter(endpoint.getName(), urlPattern, wsep);
                        handlersConfigured=true;
                    } catch (Throwable t) {
                        logger.severe("Cannot initialize endpoint " + endpoint.getName() + " : error is : " + t.getMessage());
                        t.printStackTrace();
                        adapter = null;                    
                    }
                }
            }
        }
        return adapter;
    
public voidreleaseImplementor()
Called after attempt to handle message. This is coded defensively so we attempt to clean up no matter how much progress we made in getImplementor. One important thing is to complete the invocation manager preInvoke().

        try {
            Invocation inv = (Invocation) invManager.getCurrentInvocation();

            // Only use container version of postInvoke if we got past
            // assigning an ejb instance to this invocation.  This is
            // because the web service invocation does an InvocationManager
            // preInvoke *before* assigning an ejb instance.  So, we need
            // to ensure that InvocationManager.postInvoke is always
            // called.  It was cleaner to keep this logic in this class
            // and WebServiceInvocationHandler rather than change the
            // behavior of BaseContainer.preInvoke and 
            // BaseContainer.postInvoke.

            if( inv != null ) {
                if( inv.ejb != null ) {
                    container.webServicePostInvoke(inv);
                } else {
                    invManager.postInvoke(inv);
                }
            }
        } catch(Throwable t) {
            logger.log(Level.FINE, "", t);
        }