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    
018    package org.apache.geronimo.axis2.builder;
019    
020    import java.io.FileNotFoundException;
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.net.URL;
024    import java.util.Collections;
025    import java.util.HashMap;
026    import java.util.Map;
027    import java.util.jar.JarFile;
028    
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    import org.apache.geronimo.axis2.pojo.POJOWebServiceContainerFactoryGBean;
032    import org.apache.geronimo.common.DeploymentException;
033    import org.apache.geronimo.gbean.GBeanData;
034    import org.apache.geronimo.gbean.GBeanInfo;
035    import org.apache.geronimo.gbean.GBeanInfoBuilder;
036    import org.apache.geronimo.j2ee.deployment.Module;
037    import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
038    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
039    import org.apache.geronimo.jaxws.JAXWSUtils;
040    import org.apache.geronimo.jaxws.PortInfo;
041    import org.apache.geronimo.jaxws.builder.JAXWSServiceBuilder;
042    import org.apache.geronimo.jaxws.builder.WARWebServiceFinder;
043    import org.apache.geronimo.jaxws.builder.WsdlGenerator;
044    import org.apache.geronimo.kernel.repository.Environment;
045    import org.apache.geronimo.xbeans.javaee.PortComponentType;
046    import org.apache.geronimo.xbeans.javaee.ServiceImplBeanType;
047    import org.apache.geronimo.xbeans.javaee.WebserviceDescriptionType;
048    import org.apache.geronimo.xbeans.javaee.WebservicesDocument;
049    import org.apache.geronimo.xbeans.javaee.WebservicesType;
050    import org.apache.xmlbeans.XmlCursor;
051    import org.apache.xmlbeans.XmlObject;
052    
053    /**
054     * @version $Rev$ $Date$
055     */
056    public class Axis2Builder extends JAXWSServiceBuilder {
057    
058        private static final Log log = LogFactory.getLog(Axis2Builder.class);
059            
060        public Axis2Builder(Environment defaultEnviroment) {
061            super(defaultEnviroment);
062            this.webServiceFinder = new WARWebServiceFinder();
063        }
064        
065        public Axis2Builder(){
066            super(null);
067        }
068        
069        protected GBeanInfo getContainerFactoryGBeanInfo() {
070            return POJOWebServiceContainerFactoryGBean.GBEAN_INFO;
071        }
072        
073        protected Map<String, PortInfo> parseWebServiceDescriptor(InputStream in,
074                                                                  URL wsDDUrl,
075                                                                  JarFile moduleFile,
076                                                                  boolean isEJB,
077                                                                  Map correctedPortLocations)
078                throws DeploymentException {
079    
080            log.debug("Parsing descriptor " + wsDDUrl);
081    
082            Map<String, PortInfo> map = null;
083            XmlCursor cursor = null;
084    
085            try {
086                XmlObject xobj = XmlObject.Factory.parse(in);
087               
088                cursor = xobj.newCursor();
089                cursor.toStartDoc();
090                cursor.toFirstChild();
091                //the checking is needed as we also send JAX-RPC based webservices.xml here
092                if ("http://java.sun.com/xml/ns/javaee".equals(cursor.getName().getNamespaceURI())) {
093                    WebservicesDocument wd = (WebservicesDocument)xobj.changeType(WebservicesDocument.type);
094                    WebservicesType wst = wd.getWebservices();
095    
096                    for (WebserviceDescriptionType desc : wst.getWebserviceDescriptionArray()) {
097                        String wsdlFile = null;
098                        if (desc.getWsdlFile() != null) {
099                            wsdlFile = getString(desc.getWsdlFile().getStringValue());
100                        }
101    
102                        String serviceName = desc.getWebserviceDescriptionName().getStringValue();
103    
104                        for (PortComponentType port : desc.getPortComponentArray()) {
105    
106                            PortInfo portInfo = new PortInfo();
107                            String serviceLink = null;
108                            ServiceImplBeanType beanType = port.getServiceImplBean();
109                            if (beanType.getEjbLink() != null) {
110                                serviceLink = beanType.getEjbLink().getStringValue();
111                            } else if (beanType.getServletLink().getStringValue() != null) {
112                                serviceLink = beanType.getServletLink().getStringValue();
113                            }
114                            portInfo.setServiceLink(serviceLink);
115    
116                            if (port.getServiceEndpointInterface() != null) {
117                                String sei = port.getServiceEndpointInterface().getStringValue();
118                                portInfo.setServiceEndpointInterfaceName(sei);
119                            }
120    
121                            String portName = port.getPortComponentName().getStringValue();
122                            portInfo.setPortName(portName);
123    
124                            portInfo.setProtocolBinding(port.getProtocolBinding());
125                            portInfo.setServiceName(serviceName);
126                            portInfo.setWsdlFile(wsdlFile);
127    
128                            if (port.getEnableMtom() != null) {
129                                portInfo.setEnableMTOM(port.getEnableMtom().getBooleanValue());
130                            }
131    
132                            if (port.getHandlerChains() != null) {
133                                StringBuffer chains = new StringBuffer("<handler-chains xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
134                                chains.append(port.getHandlerChains().xmlText());
135                                chains.append("</handler-chains>");
136                                portInfo.setHandlersAsXML(chains.toString());
137                            }
138    
139                            if (port.getWsdlPort() != null) {
140                                portInfo.setWsdlPort(port.getWsdlPort().getQNameValue());
141                            }
142    
143                            if (port.getWsdlService() != null) {
144                                portInfo.setWsdlService(port.getWsdlService().getQNameValue());
145                            }
146    
147                            String location = (String) correctedPortLocations.get(serviceLink);
148                            portInfo.setLocation(location);
149    
150                            if (map == null) {
151                                map = new HashMap<String, PortInfo>();
152                            }
153    
154                            map.put(serviceLink, portInfo);
155                        }
156                    }
157                } else {
158                    log.debug("Descriptor ignored (not a Java EE 5 descriptor)");
159                }
160                
161                return map;
162            } catch (FileNotFoundException e) {
163                return Collections.emptyMap();
164            } catch (IOException ex) {
165                throw new DeploymentException("Unable to read " + wsDDUrl, ex);
166            } catch (Exception ex) {
167                throw new DeploymentException("Unknown deployment error", ex);
168            } finally {
169                if (cursor != null) {
170                    cursor.dispose();
171                }
172                try {
173                    in.close();
174                } catch (IOException e) {
175                    // ignore
176                }
177            }
178        }
179    
180        private static String getString(String in) {
181            if (in != null) {
182                in = in.trim();
183                if (in.length() == 0) {
184                    return null;
185                }
186            }
187            return in;
188        }
189       
190        @Override
191        protected void initialize(GBeanData targetGBean, Class serviceClass, PortInfo portInfo, Module module) 
192            throws DeploymentException {
193            String serviceName = (portInfo.getServiceName() == null ? serviceClass.getName() : portInfo.getServiceName());
194            if (isWsdlSet(portInfo, serviceClass)) {
195                log.debug("Service " + serviceName + " has WSDL.");
196                return;
197            }        
198            
199            if (isHTTPBinding(portInfo, serviceClass)) {
200                log.debug("Service " + serviceName + " has HTTPBinding.");
201                return;
202            }
203            
204            if (JAXWSUtils.isWebServiceProvider(serviceClass)) {
205                throw new DeploymentException("WSDL must be specified for @WebServiceProvider service " + serviceName);
206            }
207            
208            log.debug("Service " + serviceName + " does not have WSDL. Generating WSDL...");
209    
210            WsdlGenerator generator = new WsdlGenerator();
211            generator.setAxis2SAAJ();
212            
213            // set wsdl service
214            if (portInfo.getWsdlService() == null) {
215                generator.setWsdlService(JAXWSUtils.getServiceQName(serviceClass));
216            } else {
217                generator.setWsdlService(portInfo.getWsdlService());
218            }
219            
220            // set wsdl port
221            if (portInfo.getWsdlPort() != null) {
222                generator.setWsdlPort(portInfo.getWsdlPort());
223            }
224                    
225            String wsdlFile = generator.generateWsdl(module, serviceClass.getName(), module.getEarContext(), portInfo);
226            portInfo.setWsdlFile(wsdlFile);
227            
228            log.debug("Generated " + wsdlFile + " for service " + serviceName);
229        }
230        
231        public static final GBeanInfo GBEAN_INFO;
232    
233        static {
234            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(Axis2Builder.class, NameFactory.MODULE_BUILDER);
235            infoBuilder.addInterface(WebServiceBuilder.class);
236            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
237            infoBuilder.setConstructor(new String[]{"defaultEnvironment"});
238            GBEAN_INFO = infoBuilder.getBeanInfo();
239        }
240    
241        public static GBeanInfo getGBeanInfo() {
242            return GBEAN_INFO;
243        }
244    }