001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.cxf.builder; 018 019 import java.io.FileNotFoundException; 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.net.URL; 023 import java.util.Collections; 024 import java.util.HashMap; 025 import java.util.Map; 026 import java.util.jar.JarFile; 027 028 import javax.xml.bind.JAXBContext; 029 import javax.xml.bind.JAXBElement; 030 import javax.xml.bind.JAXBException; 031 import javax.xml.bind.Unmarshaller; 032 import javax.xml.transform.stream.StreamSource; 033 034 import org.apache.commons.logging.Log; 035 import org.apache.commons.logging.LogFactory; 036 import org.apache.cxf.jaxws.javaee.HandlerChainsType; 037 import org.apache.cxf.jaxws.javaee.PortComponentType; 038 import org.apache.cxf.jaxws.javaee.ServiceImplBeanType; 039 import org.apache.cxf.jaxws.javaee.WebserviceDescriptionType; 040 import org.apache.cxf.jaxws.javaee.WebservicesType; 041 import org.apache.cxf.jaxws.support.JaxWsImplementorInfo; 042 import org.apache.geronimo.common.DeploymentException; 043 import org.apache.geronimo.cxf.pojo.POJOWebServiceContainerFactoryGBean; 044 import org.apache.geronimo.gbean.GBeanData; 045 import org.apache.geronimo.gbean.GBeanInfo; 046 import org.apache.geronimo.gbean.GBeanInfoBuilder; 047 import org.apache.geronimo.j2ee.deployment.Module; 048 import org.apache.geronimo.j2ee.deployment.WebServiceBuilder; 049 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 050 import org.apache.geronimo.jaxws.JAXWSUtils; 051 import org.apache.geronimo.jaxws.PortInfo; 052 import org.apache.geronimo.jaxws.builder.JAXWSServiceBuilder; 053 import org.apache.geronimo.jaxws.builder.WARWebServiceFinder; 054 import org.apache.geronimo.jaxws.builder.WsdlGenerator; 055 import org.apache.geronimo.kernel.repository.Environment; 056 057 public class CXFBuilder extends JAXWSServiceBuilder { 058 private static final Log LOG = LogFactory.getLog(CXFBuilder.class); 059 060 /** 061 * This property if enabled will cause the Sun wsgen tool to be used to 062 * generate the WSDL for servies without WSDL. By default CXF tooling 063 * will be used the generate the WSDL. 064 */ 065 private static final String USE_WSGEN_PROPERTY = 066 "org.apache.geronimo.cxf.use.wsgen"; 067 068 public CXFBuilder() { 069 super(null); 070 } 071 072 public CXFBuilder(Environment defaultEnvironment) { 073 super(defaultEnvironment); 074 this.webServiceFinder = new WARWebServiceFinder(); 075 } 076 077 protected GBeanInfo getContainerFactoryGBeanInfo() { 078 return POJOWebServiceContainerFactoryGBean.GBEAN_INFO; 079 } 080 081 protected Map<String, PortInfo> parseWebServiceDescriptor(InputStream in, 082 URL wsDDUrl, 083 JarFile moduleFile, 084 boolean isEJB, 085 Map correctedPortLocations) 086 throws DeploymentException { 087 088 LOG.debug("Parsing descriptor " + wsDDUrl); 089 090 Map<String, PortInfo> map = null; 091 092 try { 093 JAXBContext ctx = JAXBContext.newInstance(WebservicesType.class); 094 Unmarshaller unmarshaller = ctx.createUnmarshaller(); 095 Object obj = unmarshaller.unmarshal(new StreamSource(in), WebservicesType.class); 096 097 if (obj instanceof JAXBElement) { 098 obj = ((JAXBElement) obj).getValue(); 099 } 100 101 if (!(obj instanceof WebservicesType)) { 102 return map; 103 } 104 WebservicesType wst = (WebservicesType) obj; 105 106 for (WebserviceDescriptionType desc : wst.getWebserviceDescription()) { 107 String wsdlFile = null; 108 if (desc.getWsdlFile() != null) { 109 wsdlFile = getString(desc.getWsdlFile().getValue()); 110 } 111 112 String serviceName = desc.getWebserviceDescriptionName().getValue(); 113 114 for (PortComponentType port : desc.getPortComponent()) { 115 116 PortInfo portInfo = new PortInfo(); 117 118 String serviceLink = null; 119 ServiceImplBeanType beanType = port.getServiceImplBean(); 120 if (beanType.getEjbLink() != null) { 121 serviceLink = beanType.getEjbLink().getValue(); 122 } else if (beanType.getServletLink().getValue() != null) { 123 serviceLink = beanType.getServletLink().getValue(); 124 } 125 portInfo.setServiceLink(serviceLink); 126 127 if (port.getServiceEndpointInterface() != null) { 128 String sei = port.getServiceEndpointInterface().getValue(); 129 portInfo.setServiceEndpointInterfaceName(sei); 130 } 131 132 String portName = port.getPortComponentName().getValue(); 133 portInfo.setPortName(portName); 134 135 portInfo.setProtocolBinding(port.getProtocolBinding()); 136 portInfo.setServiceName(serviceName); 137 portInfo.setWsdlFile(wsdlFile); 138 139 if (port.getEnableMtom() != null) { 140 portInfo.setEnableMTOM(port.getEnableMtom().isValue()); 141 } 142 143 portInfo.setHandlers(HandlerChainsType.class, port.getHandlerChains()); 144 145 if (port.getWsdlPort() != null) { 146 portInfo.setWsdlPort(port.getWsdlPort().getValue()); 147 } 148 149 if (port.getWsdlService() != null) { 150 portInfo.setWsdlService(port.getWsdlService().getValue()); 151 } 152 153 String location = (String) correctedPortLocations.get(serviceLink); 154 portInfo.setLocation(location); 155 156 if (map == null) { 157 map = new HashMap<String, PortInfo>(); 158 } 159 map.put(serviceLink, portInfo); 160 } 161 } 162 163 return map; 164 } catch (FileNotFoundException e) { 165 return Collections.emptyMap(); 166 } catch (IOException ex) { 167 throw new DeploymentException("Unable to read " + wsDDUrl, ex); 168 } catch (JAXBException ex) { 169 throw new DeploymentException("Unable to parse " + wsDDUrl, ex); 170 } catch (Exception ex) { 171 throw new DeploymentException("Unknown deployment error", ex); 172 } finally { 173 try { 174 in.close(); 175 } catch (IOException e) { 176 // ignore 177 } 178 } 179 } 180 181 private static String getString(String in) { 182 if (in != null) { 183 in = in.trim(); 184 if (in.length() == 0) { 185 return null; 186 } 187 } 188 return in; 189 } 190 191 @Override 192 protected void initialize(GBeanData targetGBean, Class serviceClass, PortInfo portInfo, Module module) 193 throws DeploymentException { 194 if (Boolean.getBoolean(USE_WSGEN_PROPERTY)) { 195 generateWSDL(serviceClass, portInfo, module); 196 } 197 } 198 199 private void generateWSDL(Class serviceClass, PortInfo portInfo, Module module) 200 throws DeploymentException { 201 if (isWsdlSet(portInfo, serviceClass)) { 202 LOG.debug("Service " + portInfo.getServiceName() + " has WSDL."); 203 return; 204 } 205 LOG.debug("Service " + portInfo.getServiceName() + " does not have WSDL. Generating WSDL..."); 206 207 WsdlGenerator generator = new WsdlGenerator(); 208 generator.setSunSAAJ(); 209 210 JaxWsImplementorInfo serviceInfo = new JaxWsImplementorInfo(serviceClass); 211 212 // set wsdl service 213 if (portInfo.getWsdlService() == null) { 214 generator.setWsdlService(serviceInfo.getServiceName()); 215 } else { 216 generator.setWsdlService(portInfo.getWsdlService()); 217 } 218 219 // set wsdl port 220 if (portInfo.getWsdlPort() != null) { 221 generator.setWsdlPort(portInfo.getWsdlPort()); 222 } 223 224 String wsdlFile = generator.generateWsdl(module, serviceClass.getName(), module.getEarContext(), portInfo); 225 portInfo.setWsdlFile(wsdlFile); 226 227 LOG.debug("Generated " + wsdlFile + " for service " + portInfo.getServiceName()); 228 } 229 230 private boolean isWsdlSet(PortInfo portInfo, Class serviceClass) { 231 return (portInfo.getWsdlFile() != null && !portInfo.getWsdlFile().trim().equals("")) 232 || JAXWSUtils.containsWsdlLocation(serviceClass, serviceClass.getClassLoader()); 233 } 234 235 public static final GBeanInfo GBEAN_INFO; 236 237 static { 238 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(CXFBuilder.class, NameFactory.MODULE_BUILDER); 239 infoBuilder.addInterface(WebServiceBuilder.class); 240 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true); 241 242 infoBuilder.setConstructor(new String[]{"defaultEnvironment"}); 243 244 GBEAN_INFO = infoBuilder.getBeanInfo(); 245 } 246 247 public static GBeanInfo getGBeanInfo() { 248 return GBEAN_INFO; 249 } 250 251 }