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