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.jaxws.builder;
019    
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    import org.apache.geronimo.common.DeploymentException;
027    import org.apache.geronimo.j2ee.deployment.Module;
028    import org.apache.geronimo.j2ee.deployment.WebModule;
029    import org.apache.geronimo.jaxws.JAXWSUtils;
030    import org.apache.geronimo.jaxws.PortInfo;
031    import org.apache.geronimo.xbeans.javaee.ServletMappingType;
032    import org.apache.geronimo.xbeans.javaee.ServletType;
033    import org.apache.geronimo.xbeans.javaee.WebAppType;
034    
035    public class SimpleWARWebServiceFinder implements WebServiceFinder {
036    
037        private static final Log LOG = LogFactory.getLog(SimpleWARWebServiceFinder.class);
038        
039        public Map<String, PortInfo> discoverWebServices(Module module, 
040                                                         boolean isEJB,
041                                                         Map correctedPortLocations)
042                throws DeploymentException {
043            Map<String, PortInfo> map = new HashMap<String, PortInfo>();
044            discoverPOJOWebServices(module, correctedPortLocations, map);
045            return map;
046        }
047    
048        private void discoverPOJOWebServices(Module module,
049                                             Map correctedPortLocations,
050                                             Map<String, PortInfo> map) 
051            throws DeploymentException {
052            ClassLoader classLoader = module.getEarContext().getClassLoader();
053            WebAppType webApp = (WebAppType) module.getSpecDD();
054    
055            // find web services
056            ServletType[] servletTypes = webApp.getServletArray();
057    
058            if (webApp.getDomNode().getChildNodes().getLength() == 0) {
059                // web.xml not present (empty really), discover annotated
060                // classes and update DD
061                List<Class> services = WARWebServiceFinder.discoverWebServices(module.getModuleFile(), false, this.getClass().getClassLoader());
062                String contextRoot = ((WebModule) module).getContextRoot();
063                for (Class service : services) {
064                    // skip interfaces and such
065                    if (!JAXWSUtils.isWebService(service)) {
066                        continue;
067                    }
068    
069                    LOG.debug("Discovered POJO Web Service: " + service.getName());
070                    
071                    // add new <servlet/> element
072                    ServletType servlet = webApp.addNewServlet();
073                    servlet.addNewServletName().setStringValue(service.getName());
074                    servlet.addNewServletClass().setStringValue(service.getName());
075    
076                    // add new <servlet-mapping/> element
077                    String location = "/" + JAXWSUtils.getServiceName(service);
078                    ServletMappingType servletMapping = webApp.addNewServletMapping();
079                    servletMapping.addNewServletName().setStringValue(service.getName());
080                    servletMapping.addNewUrlPattern().setStringValue(location);
081    
082                    // map service
083                    PortInfo portInfo = new PortInfo();
084                    portInfo.setLocation(contextRoot + location);
085                    map.put(service.getName(), portInfo);
086                }
087            } else {
088                // web.xml present, examine servlet classes and check for web
089                // services
090                for (ServletType servletType : servletTypes) {
091                    String servletName = servletType.getServletName().getStringValue().trim();
092                    if (servletType.isSetServletClass()) {
093                        String servletClassName = servletType.getServletClass().getStringValue().trim();
094                        try {
095                            Class servletClass = classLoader.loadClass(servletClassName);
096                            if (JAXWSUtils.isWebService(servletClass)) {
097                                LOG.debug("Found POJO Web Service: " + servletName);
098                                PortInfo portInfo = new PortInfo();
099                                map.put(servletName, portInfo);
100                            }
101                        } catch (Exception e) {
102                            throw new DeploymentException("Failed to load servlet class "
103                                                          + servletClassName, e);
104                        }
105                    }
106                }
107    
108                // update web service locations
109                for (Map.Entry entry : map.entrySet()) {
110                    String servletName = (String) entry.getKey();
111                    PortInfo portInfo = (PortInfo) entry.getValue();
112    
113                    String location = (String) correctedPortLocations.get(servletName);
114                    if (location != null) {
115                        portInfo.setLocation(location);
116                    }
117                }
118            }
119        } 
120    
121    }