1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.geronimo.cxf; 20 21 import java.net.MalformedURLException; 22 import java.net.URI; 23 import java.net.URL; 24 import java.util.List; 25 import java.util.concurrent.Executor; 26 27 import javax.xml.ws.Binding; 28 import javax.xml.ws.WebServiceException; 29 import javax.xml.ws.handler.Handler; 30 import javax.xml.ws.http.HTTPBinding; 31 import javax.xml.ws.soap.SOAPBinding; 32 33 import org.apache.cxf.Bus; 34 import org.apache.cxf.endpoint.Server; 35 import org.apache.cxf.endpoint.ServerImpl; 36 import org.apache.cxf.jaxws.JaxWsServerFactoryBean; 37 import org.apache.cxf.jaxws.handler.PortInfoImpl; 38 import org.apache.cxf.jaxws.support.JaxWsEndpointImpl; 39 import org.apache.cxf.jaxws.support.JaxWsImplementorInfo; 40 import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean; 41 import org.apache.cxf.service.Service; 42 import org.apache.geronimo.jaxws.HandlerChainsUtils; 43 import org.apache.geronimo.jaxws.PortInfo; 44 import org.apache.geronimo.jaxws.annotations.AnnotationException; 45 import org.apache.geronimo.jaxws.annotations.AnnotationProcessor; 46 import org.apache.geronimo.jaxws.handler.GeronimoHandlerResolver; 47 import org.apache.geronimo.xbeans.javaee.HandlerChainsType; 48 49 public abstract class CXFEndpoint { 50 51 protected Bus bus; 52 53 protected Object implementor; 54 55 protected Server server; 56 57 protected Service service; 58 59 protected JaxWsImplementorInfo implInfo; 60 61 protected JaxWsServiceFactoryBean serviceFactory; 62 63 protected PortInfo portInfo; 64 65 protected AnnotationProcessor annotationProcessor; 66 67 private String address; 68 69 public CXFEndpoint(Bus bus, Object implementor) { 70 this.bus = bus; 71 this.implementor = implementor; 72 this.portInfo = (PortInfo) bus.getExtension(PortInfo.class); 73 74 this.bus.setExtension(this, CXFEndpoint.class); 75 } 76 77 protected URL getWsdlURL(URL configurationBaseUrl, String wsdlFile) { 78 URL wsdlURL = null; 79 if (wsdlFile != null && wsdlFile.trim().length() > 0) { 80 wsdlFile = wsdlFile.trim(); 81 try { 82 wsdlURL = new URL(wsdlFile); 83 } catch (MalformedURLException e) { 84 // Not a URL, try as a resource 85 wsdlURL = getImplementorClass().getResource("/" + wsdlFile); 86 87 if (wsdlURL == null && configurationBaseUrl != null) { 88 // Cannot get it as a resource, try with 89 // configurationBaseUrl 90 try { 91 wsdlURL = new URL(configurationBaseUrl, wsdlFile); 92 } catch (MalformedURLException ee) { 93 // ignore 94 } 95 } 96 } 97 } 98 return wsdlURL; 99 } 100 101 protected Class getImplementorClass() { 102 return this.implementor.getClass(); 103 } 104 105 protected org.apache.cxf.endpoint.Endpoint getEndpoint() { 106 return ((ServerImpl) getServer()).getEndpoint(); 107 } 108 109 public boolean isSOAP11() { 110 return SOAPBinding.SOAP11HTTP_BINDING.equals(implInfo.getBindingType()) || 111 SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(implInfo.getBindingType()); 112 } 113 114 public boolean isHTTP() { 115 return HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType()); 116 } 117 118 public ServerImpl getServer() { 119 return (ServerImpl) server; 120 } 121 122 public Binding getBinding() { 123 return ((JaxWsEndpointImpl) getEndpoint()).getJaxwsBinding(); 124 } 125 126 public void setExecutor(Executor executor) { 127 service.setExecutor(executor); 128 } 129 130 public Executor getExecutor() { 131 return service.getExecutor(); 132 } 133 134 public Object getImplementor() { 135 return implementor; 136 } 137 138 public boolean isPublished() { 139 return server != null; 140 } 141 142 public void publish(String address) { 143 doPublish(address); 144 } 145 146 private static class GeronimoJaxWsServerFactoryBean extends JaxWsServerFactoryBean { 147 public GeronimoJaxWsServerFactoryBean() { 148 // disable CXF resource injection 149 doInit = false; 150 } 151 } 152 153 protected void doPublish(String baseAddress) { 154 // XXX: assume port 8080 by default since we don't know the actual port at startup 155 String address = (baseAddress == null) ? "http://localhost:8080" : baseAddress; 156 157 JaxWsServerFactoryBean svrFactory = new GeronimoJaxWsServerFactoryBean(); 158 svrFactory.setBus(bus); 159 svrFactory.setAddress(address + this.portInfo.getLocation()); 160 svrFactory.setServiceFactory(serviceFactory); 161 svrFactory.setStart(false); 162 svrFactory.setServiceBean(implementor); 163 164 if (HTTPBinding.HTTP_BINDING.equals(implInfo.getBindingType())) { 165 svrFactory.setTransportId("http://cxf.apache.org/bindings/xformat"); 166 } 167 168 server = svrFactory.create(); 169 170 init(); 171 172 org.apache.cxf.endpoint.Endpoint endpoint = getEndpoint(); 173 174 if (getBinding() instanceof SOAPBinding && this.portInfo.isMTOMEnabled() != null) { 175 ((SOAPBinding)getBinding()).setMTOMEnabled(this.portInfo.isMTOMEnabled()); 176 } 177 178 server.start(); 179 } 180 181 protected void init() { 182 } 183 184 /* 185 * Update service's address on the very first invocation. The address 186 * assumed at start up might not be valid. 187 */ 188 synchronized void updateAddress(URI request) { 189 if (this.address == null) { 190 String requestAddress = CXFWebServiceContainer.getBaseUri(request); 191 getEndpoint().getEndpointInfo().setAddress(requestAddress); 192 this.address = requestAddress; 193 } 194 } 195 196 /* 197 * Set appropriate handlers for the port/service/bindings. 198 */ 199 protected void initHandlers() throws Exception { 200 HandlerChainsType handlerChains = 201 HandlerChainsUtils.getHandlerChains(this.portInfo.getHandlersAsXML()); 202 GeronimoHandlerResolver handlerResolver = 203 new GeronimoHandlerResolver(getImplementorClass().getClassLoader(), 204 getImplementorClass(), 205 handlerChains, 206 null); 207 208 PortInfoImpl portInfo = new PortInfoImpl(implInfo.getBindingType(), 209 serviceFactory.getEndpointName(), 210 service.getName()); 211 212 List<Handler> chain = handlerResolver.getHandlerChain(portInfo); 213 214 getBinding().setHandlerChain(chain); 215 } 216 217 protected void injectResources(Object instance) throws AnnotationException { 218 this.annotationProcessor.processAnnotations(instance); 219 this.annotationProcessor.invokePostConstruct(instance); 220 } 221 222 protected void injectHandlers() { 223 List<Handler> handlers = getBinding().getHandlerChain(); 224 try { 225 for (Handler handler : handlers) { 226 injectResources(handler); 227 } 228 } catch (AnnotationException e) { 229 throw new WebServiceException("Handler annotation failed", e); 230 } 231 } 232 233 protected void destroyHandlers() { 234 if (this.annotationProcessor != null) { 235 // call handlers preDestroy 236 List<Handler> handlers = getBinding().getHandlerChain(); 237 for (Handler handler : handlers) { 238 this.annotationProcessor.invokePreDestroy(handler); 239 } 240 } 241 } 242 243 public void stop() { 244 // shutdown server 245 if (this.server != null) { 246 this.server.stop(); 247 } 248 } 249 }