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 boolean isSOAP11() {
106           return SOAPBinding.SOAP11HTTP_BINDING.equals(implInfo.getBindingType()) ||
107                  SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(implInfo.getBindingType());
108        }
109        
110        public boolean isHTTP() {
111            return HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType());
112         }
113        
114        public ServerImpl getServer() {
115            return (ServerImpl) server;
116        }
117    
118        public Binding getBinding() {
119            return ((JaxWsEndpointImpl) getEndpoint()).getJaxwsBinding();
120        }
121    
122        public void setExecutor(Executor executor) {
123            service.setExecutor(executor);
124        }
125    
126        public Executor getExecutor() {
127            return service.getExecutor();
128        }
129    
130        @Override
131        public Object getImplementor() {
132            return implementor;
133        }
134    
135        @Override
136        public List<Source> getMetadata() {
137            // TODO Auto-generated method stub
138            return null;
139        }
140    
141        @Override
142        public Map<String, Object> getProperties() {
143            // TODO Auto-generated method stub
144            return null;
145        }
146    
147        @Override
148        public boolean isPublished() {
149            return server != null;
150        }
151    
152        @Override
153        public void publish(Object arg0) {
154            // TODO Auto-generated method stub
155        }
156    
157        @Override
158        public void publish(String address) {
159            doPublish(address);
160        }
161    
162        public void setMetadata(List<Source> arg0) {
163            // TODO Auto-generated method stub
164        }
165    
166        @Override
167        public void setProperties(Map<String, Object> arg0) {
168            // TODO Auto-generated method stub
169        }
170    
171        private static class GeronimoJaxWsServerFactoryBean extends JaxWsServerFactoryBean {
172            public GeronimoJaxWsServerFactoryBean() {
173                // disable CXF resource injection
174                doInit = false;
175            }
176        }
177        
178        protected void doPublish(String address) {
179            JaxWsServerFactoryBean svrFactory = new GeronimoJaxWsServerFactoryBean();
180            svrFactory.setBus(bus);
181            svrFactory.setAddress(address);
182            svrFactory.setServiceFactory(serviceFactory);
183            svrFactory.setStart(false);
184            svrFactory.setServiceBean(implementor);
185                  
186            if (HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType())) {
187                svrFactory.setTransportId("http://cxf.apache.org/bindings/xformat");
188            }
189            
190            server = svrFactory.create();
191            
192            init();
193    
194            org.apache.cxf.endpoint.Endpoint endpoint = getEndpoint();
195    
196            if (getBinding() instanceof SOAPBinding) {
197                ((SOAPBinding)getBinding()).setMTOMEnabled(this.portInfo.isMTOMEnabled());
198            }
199            
200            /**
201            if (endpoint.getEnableSchemaValidation()) {
202                endpoint.ge
203                endpoint.put(Message.SCHEMA_VALIDATION_ENABLED, 
204                             endpoint.getEnableSchemaValidation());
205            }
206            **/
207            server.start();
208        }
209    
210        protected void init() { 
211        }
212              
213        /*
214         * Set appropriate handlers for the port/service/bindings.
215         */
216        protected void initHandlers() throws Exception {        
217            HandlerChainsType handlerChains = this.portInfo.getHandlers(HandlerChainsType.class);
218            CXFHandlerResolver handlerResolver =
219                new CXFHandlerResolver(getImplementorClass().getClassLoader(), 
220                                       getImplementorClass(),
221                                       handlerChains, 
222                                       null);
223                          
224            PortInfoImpl portInfo = new PortInfoImpl(implInfo.getBindingType(), 
225                                                     serviceFactory.getEndpointName(),
226                                                     service.getName());
227            
228            List<Handler> chain = handlerResolver.getHandlerChain(portInfo);
229    
230            getBinding().setHandlerChain(chain);
231        }
232            
233        protected void injectResources(Object instance) throws AnnotationException {
234            this.annotationProcessor.processAnnotations(instance);
235            this.annotationProcessor.invokePostConstruct(instance);
236        }
237        
238        protected void injectHandlers() {
239            List<Handler> handlers = getBinding().getHandlerChain();
240            try {
241                for (Handler handler : handlers) {
242                    injectResources(handler);
243                }
244            } catch (AnnotationException e) {
245                throw new WebServiceException("Handler annotation failed", e);
246            }
247        }
248        
249        protected void destroyHandlers() {
250            if (this.annotationProcessor != null) {
251                // call handlers preDestroy
252                List<Handler> handlers = getBinding().getHandlerChain();
253                for (Handler handler : handlers) {
254                    this.annotationProcessor.invokePreDestroy(handler);
255                }
256            }
257        }
258        
259        public void stop() {        
260            // shutdown server
261            if (this.server != null) {
262                this.server.stop();
263            }
264        }
265    }