001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License. You may obtain a copy of the License at
009     *
010     * http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied. See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.geronimo.cxf.ejb;
020    
021    import java.net.URL;
022    import java.util.List;
023    
024    import javax.naming.InitialContext;
025    import javax.naming.NamingException;
026    import javax.xml.ws.WebServiceContext;
027    import javax.xml.ws.WebServiceException;
028    
029    import org.apache.cxf.Bus;
030    import org.apache.cxf.binding.soap.SoapBinding;
031    import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
032    import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
033    import org.apache.cxf.endpoint.Endpoint;
034    import org.apache.cxf.interceptor.Interceptor;
035    import org.apache.cxf.jaxws.handler.logical.LogicalHandlerInInterceptor;
036    import org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor;
037    import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
038    import org.apache.geronimo.cxf.CXFEndpoint;
039    import org.apache.geronimo.cxf.CXFServiceConfiguration;
040    import org.apache.geronimo.cxf.GeronimoJaxWsImplementorInfo;
041    import org.apache.geronimo.jaxws.JAXWSAnnotationProcessor;
042    import org.apache.geronimo.jaxws.JNDIResolver;
043    import org.apache.openejb.DeploymentInfo;
044    
045    public class EJBEndpoint extends CXFEndpoint {
046        
047        public EJBEndpoint(Bus bus,
048                           URL configurationBaseUrl,
049                           Class instance) {
050            super(bus, instance);
051                    
052            implInfo = new GeronimoJaxWsImplementorInfo(instance, this.portInfo, instance.getClassLoader());
053    
054            serviceFactory = new JaxWsServiceFactoryBean(implInfo);       
055            serviceFactory.setBus(bus);
056    
057            String wsdlLocation = null;
058            if (this.portInfo.getWsdlFile() != null) {
059                wsdlLocation = this.portInfo.getWsdlFile();
060            } else {
061                wsdlLocation = implInfo.getWsdlLocation();
062            }        
063            URL wsdlURL = getWsdlURL(configurationBaseUrl, wsdlLocation);
064    
065            // install as first to overwrite annotations (wsdl-file, wsdl-port, wsdl-service)
066            CXFServiceConfiguration configuration = 
067                new CXFServiceConfiguration(this.portInfo, wsdlURL);
068            serviceFactory.getConfigurations().add(0, configuration);
069    
070            service = serviceFactory.create();        
071        }
072        
073        protected Class getImplementorClass() {
074            return (Class)this.implementor;
075        }
076        
077        protected void init() {
078            // configure handlers
079            try {
080                initHandlers();
081            } catch (Exception e) {
082                throw new WebServiceException("Error configuring handlers", e);
083            }
084                    
085            DeploymentInfo deploymentInfo = 
086                (DeploymentInfo)bus.getExtension(DeploymentInfo.class);
087            
088            service.setInvoker(new EJBMethodInvoker(this, this.bus, deploymentInfo));  
089            
090            Endpoint endpoint = getEndpoint();
091            
092            /* 
093             * Remove interceptors that perform handler processing since
094             * handler processing must happen within the EJB container.
095             */        
096            removeHandlerInterceptors(bus.getInInterceptors());
097            removeHandlerInterceptors(endpoint.getInInterceptors());
098            removeHandlerInterceptors(endpoint.getBinding().getInInterceptors());
099            removeHandlerInterceptors(endpoint.getService().getInInterceptors());
100            
101            // install SAAJ interceptor        
102            if (endpoint.getBinding() instanceof SoapBinding &&
103                !this.implInfo.isWebServiceProvider()) {
104                endpoint.getService().getInInterceptors().add(new SAAJInInterceptor());
105            }        
106        }
107            
108        private static void removeHandlerInterceptors(List<Interceptor> interceptors) {
109            for (Interceptor interceptor : interceptors) {
110                if (interceptor instanceof MustUnderstandInterceptor ||
111                    interceptor instanceof LogicalHandlerInInterceptor ||
112                    interceptor instanceof SOAPHandlerInterceptor) {
113                    interceptors.remove(interceptor);
114                }
115            } 
116        }
117        
118        public synchronized void injectHandlers() {
119            if (this.annotationProcessor != null) {
120                // assume injection was already done
121                return;
122            }
123            
124            WebServiceContext wsContext = null;
125            try {
126                InitialContext ctx = new InitialContext();
127                wsContext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
128            } catch (NamingException e) {
129                throw new WebServiceException("Failed to lookup WebServiceContext", e);
130            }
131            
132            this.annotationProcessor = new JAXWSAnnotationProcessor(new JNDIResolver(), wsContext);
133            super.injectHandlers();
134        }
135        
136        public void stop() {
137            // call handler preDestroy
138            destroyHandlers();
139    
140            // shutdown server
141            super.stop();
142        }
143        
144    }