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