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;
020    
021    import java.net.MalformedURLException;
022    import java.net.URL;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.concurrent.Executor;
026    
027    import javax.xml.transform.Source;
028    import javax.xml.ws.Binding;
029    import javax.xml.ws.Endpoint;
030    import javax.xml.ws.WebServiceException;
031    import javax.xml.ws.handler.Handler;
032    import javax.xml.ws.http.HTTPBinding;
033    import javax.xml.ws.soap.SOAPBinding;
034    
035    import org.apache.cxf.Bus;
036    import org.apache.cxf.endpoint.Server;
037    import org.apache.cxf.endpoint.ServerImpl;
038    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
039    import org.apache.cxf.jaxws.handler.PortInfoImpl;
040    import org.apache.cxf.jaxws.javaee.HandlerChainsType;
041    import org.apache.cxf.jaxws.support.JaxWsEndpointImpl;
042    import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
043    import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
044    import org.apache.cxf.service.Service;
045    import org.apache.geronimo.jaxws.PortInfo;
046    import org.apache.geronimo.jaxws.annotations.AnnotationException;
047    import org.apache.geronimo.jaxws.annotations.AnnotationProcessor;
048    
049    public abstract class CXFEndpoint extends Endpoint {
050    
051        protected Bus bus;
052    
053        protected Object implementor;
054    
055        protected Server server;
056    
057        protected Service service;
058    
059        protected JaxWsImplementorInfo implInfo;
060    
061        protected JaxWsServiceFactoryBean serviceFactory;
062    
063        protected PortInfo portInfo;
064        
065        protected AnnotationProcessor annotationProcessor;
066    
067        public CXFEndpoint(Bus bus, Object implementor) {
068            this.bus = bus;
069            this.implementor = implementor;
070            this.portInfo = (PortInfo) bus.getExtension(PortInfo.class);       
071        }
072      
073        protected URL getWsdlURL(URL configurationBaseUrl, String wsdlFile) {
074            URL wsdlURL = null;
075            if (wsdlFile != null && wsdlFile.trim().length() > 0) {
076                wsdlFile = wsdlFile.trim();
077                try {
078                    wsdlURL = new URL(wsdlFile);
079                } catch (MalformedURLException e) {
080                    // Not a URL, try as a resource
081                    wsdlURL = getImplementorClass().getResource("/" + wsdlFile);
082    
083                    if (wsdlURL == null && configurationBaseUrl != null) {
084                        // Cannot get it as a resource, try with
085                        // configurationBaseUrl
086                        try {
087                            wsdlURL = new URL(configurationBaseUrl, wsdlFile);
088                        } catch (MalformedURLException ee) {
089                            // ignore
090                        }
091                    }
092                }
093            }
094            return wsdlURL;
095        }
096        
097        protected Class getImplementorClass() {
098            return this.implementor.getClass();
099        }
100        
101        protected org.apache.cxf.endpoint.Endpoint getEndpoint() {
102            return ((ServerImpl) getServer()).getEndpoint();
103        }
104    
105        public ServerImpl getServer() {
106            return (ServerImpl) server;
107        }
108    
109        public Binding getBinding() {
110            return ((JaxWsEndpointImpl) getEndpoint()).getJaxwsBinding();
111        }
112    
113        public void setExecutor(Executor executor) {
114            service.setExecutor(executor);
115        }
116    
117        public Executor getExecutor() {
118            return service.getExecutor();
119        }
120    
121        @Override
122        public Object getImplementor() {
123            return implementor;
124        }
125    
126        @Override
127        public List<Source> getMetadata() {
128            // TODO Auto-generated method stub
129            return null;
130        }
131    
132        @Override
133        public Map<String, Object> getProperties() {
134            // TODO Auto-generated method stub
135            return null;
136        }
137    
138        @Override
139        public boolean isPublished() {
140            return server != null;
141        }
142    
143        @Override
144        public void publish(Object arg0) {
145            // TODO Auto-generated method stub
146        }
147    
148        @Override
149        public void publish(String address) {
150            doPublish(address);
151        }
152    
153        public void setMetadata(List<Source> arg0) {
154            // TODO Auto-generated method stub
155        }
156    
157        @Override
158        public void setProperties(Map<String, Object> arg0) {
159            // TODO Auto-generated method stub
160        }
161    
162        private static class GeronimoJaxWsServerFactoryBean extends JaxWsServerFactoryBean {
163            public GeronimoJaxWsServerFactoryBean() {
164                // disable CXF resource injection
165                doInit = false;
166            }
167        }
168        
169        protected void doPublish(String address) {
170            JaxWsServerFactoryBean svrFactory = new GeronimoJaxWsServerFactoryBean();
171            svrFactory.setBus(bus);
172            svrFactory.setAddress(address);
173            svrFactory.setServiceFactory(serviceFactory);
174            svrFactory.setStart(false);
175            svrFactory.setServiceBean(implementor);
176                  
177            if (HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType())) {
178                svrFactory.setTransportId("http://cxf.apache.org/bindings/xformat");
179            }
180            
181            server = svrFactory.create();
182            
183            init();
184    
185            org.apache.cxf.endpoint.Endpoint endpoint = getEndpoint();
186    
187            if (getBinding() instanceof SOAPBinding) {
188                ((SOAPBinding)getBinding()).setMTOMEnabled(this.portInfo.isMTOMEnabled());
189            }
190            
191            /**
192            if (endpoint.getEnableSchemaValidation()) {
193                endpoint.ge
194                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED, 
195                             endpoint.getEnableSchemaValidation());
196            }
197            **/
198            server.start();
199        }
200    
201        protected void init() { 
202        }
203              
204        /*
205         * Set appropriate handlers for the port/service/bindings.
206         */
207        protected void initHandlers() throws Exception {        
208            HandlerChainsType handlerChains = this.portInfo.getHandlers(HandlerChainsType.class);
209            CXFHandlerResolver handlerResolver =
210                new CXFHandlerResolver(getImplementorClass().getClassLoader(), 
211                                       getImplementorClass(),
212                                       handlerChains, 
213                                       null);
214                          
215            PortInfoImpl portInfo = new PortInfoImpl(implInfo.getBindingType(), 
216                                                     serviceFactory.getEndpointName(),
217                                                     service.getName());
218            
219            List<Handler> chain = handlerResolver.getHandlerChain(portInfo);
220    
221            getBinding().setHandlerChain(chain);
222        }
223            
224        protected void injectResources(Object instance) throws AnnotationException {
225            this.annotationProcessor.processAnnotations(instance);
226            this.annotationProcessor.invokePostConstruct(instance);
227        }
228        
229        protected void injectHandlers() {
230            List<Handler> handlers = getBinding().getHandlerChain();
231            try {
232                for (Handler handler : handlers) {
233                    injectResources(handler);
234                }
235            } catch (AnnotationException e) {
236                throw new WebServiceException("Handler annotation failed", e);
237            }
238        }
239        
240        protected void destroyHandlers() {
241            if (this.annotationProcessor != null) {
242                // call handlers preDestroy
243                List<Handler> handlers = getBinding().getHandlerChain();
244                for (Handler handler : handlers) {
245                    this.annotationProcessor.invokePreDestroy(handler);
246                }
247            }
248        }
249        
250        public void stop() {        
251            // shutdown server
252            if (this.server != null) {
253                this.server.stop();
254            }
255        }
256    }