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.jaxws.builder;
018    
019    import java.net.URL;
020    import java.util.Collection;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.jar.JarFile;
025    
026    import org.apache.geronimo.common.DeploymentException;
027    import org.apache.geronimo.deployment.ModuleIDBuilder;
028    import org.apache.geronimo.deployment.service.EnvironmentBuilder;
029    import org.apache.geronimo.gbean.AbstractName;
030    import org.apache.geronimo.gbean.AbstractNameQuery;
031    import org.apache.geronimo.gbean.GBeanData;
032    import org.apache.geronimo.gbean.GBeanInfo;
033    import org.apache.geronimo.gbean.GBeanInfoBuilder;
034    import org.apache.geronimo.j2ee.deployment.EARContext;
035    import org.apache.geronimo.j2ee.deployment.Module;
036    import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension;
037    import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
038    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
039    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
040    import org.apache.geronimo.kernel.Kernel;
041    import org.apache.geronimo.kernel.Naming;
042    import org.apache.geronimo.kernel.config.ConfigurationModuleType;
043    import org.apache.geronimo.kernel.config.ConfigurationStore;
044    import org.apache.geronimo.kernel.repository.Environment;
045    import org.apache.geronimo.openejb.deployment.EjbModule;
046    import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
047    import org.apache.openejb.jee.oejb2.GeronimoEjbJarType;
048    import org.apache.openejb.jee.oejb2.WebServiceBindingType;
049    import org.apache.openejb.jee.oejb2.WebServiceBindingType.WebServiceSecurityType;
050    
051    /**
052     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
053     */
054    public class JAXWSEJBModuleBuilderExtension implements ModuleBuilderExtension {
055    
056        protected WebServiceBuilder jaxwsBuilder;
057        protected AbstractNameQuery listener;    
058        protected GBeanInfo wsGBeanInfo;
059        protected Environment defaultEnvironment;
060    
061        public JAXWSEJBModuleBuilderExtension() throws Exception {
062        }
063    
064        public JAXWSEJBModuleBuilderExtension(WebServiceBuilder wsBuilder,
065                                              Environment defaultEnvironment,
066                                              AbstractNameQuery listener,
067                                              Object dataLink,
068                                              Kernel kernel) throws Exception {
069            this.jaxwsBuilder = wsBuilder;
070            this.listener = listener;    
071            this.defaultEnvironment = defaultEnvironment;
072            this.wsGBeanInfo = getGBeanInfo(kernel, dataLink);
073        }
074        
075        private static GBeanInfo getGBeanInfo(Kernel kernel, Object webServiceLinkTemplate) throws Exception {
076            AbstractName webServiceLinkTemplateName = kernel.getAbstractNameFor(webServiceLinkTemplate);
077            return kernel.getGBeanInfo(webServiceLinkTemplateName);
078        }
079    
080        public void createModule(Module module, Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
081            if (this.defaultEnvironment != null) {
082                EnvironmentBuilder.mergeEnvironments(environment, this.defaultEnvironment);
083            } 
084        }
085    
086        public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repository) throws DeploymentException {
087        }
088    
089        public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
090            if (module.getType() != ConfigurationModuleType.EJB) {
091                return;
092            }
093           
094            EjbModule ejbModule = (EjbModule) module;
095            Environment environment = module.getEnvironment();
096                    
097            //overridden web service locations       
098            Map correctedPortLocations = new HashMap();         
099            GeronimoEjbJarType geronimoEjbJarType = 
100                (GeronimoEjbJarType) ejbModule.getEjbModule().getAltDDs().get("geronimo-openejb.xml");
101            if (geronimoEjbJarType != null) {
102               for (WebServiceBindingType bt : geronimoEjbJarType.getWebServiceBinding()) {
103                   String location = bt.getWebServiceAddress();
104                   if (location != null) {
105                       location = location.trim();
106                       if (!location.startsWith("/")) {
107                           location = "/" + location;
108                       }
109                       correctedPortLocations.put(bt.getEjbName(), location);
110                   }
111               }
112            }      
113            
114            jaxwsBuilder.findWebServices(module, true, correctedPortLocations, environment, ejbModule.getSharedContext());
115        }
116    
117        public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
118            if (module.getType() != ConfigurationModuleType.EJB) {
119                return;
120            }
121    
122            EjbModule ejbModule = (EjbModule) module;
123    
124            Map<String, WebServiceBindingType> wsBindingMap = 
125                createWebServiceBindingMap(ejbModule);
126            
127            for (EnterpriseBeanInfo bean : ejbModule.getEjbJarInfo().enterpriseBeans) {
128                if (bean.type != EnterpriseBeanInfo.STATELESS) {
129                    continue;
130                }
131                
132                String ejbName = bean.ejbName;
133    
134                AbstractName sessionName = earContext.getNaming().createChildName(module.getModuleName(), ejbName, NameFactory.STATELESS_SESSION_BEAN);
135    
136                assert sessionName != null: "StatelesSessionBean object name is null";
137    
138                AbstractName ejbWebServiceName = earContext.getNaming().createChildName(sessionName, ejbName, NameFactory.WEB_SERVICE_LINK);
139                
140                GBeanData ejbWebServiceGBean = new GBeanData(ejbWebServiceName, this.wsGBeanInfo);
141    
142                ejbWebServiceGBean.setAttribute("ejbName", ejbName);
143                ejbWebServiceGBean.setAttribute("ejbClass", bean.ejbClass);
144                
145                WebServiceBindingType wsBinding = wsBindingMap.get(ejbName);
146                if (wsBinding != null) {
147                    List<String> ddVirtualHosts = wsBinding.getWebServiceVirtualHost();
148                    if (ddVirtualHosts != null) {                    
149                        String[] virtualHosts = new String[ddVirtualHosts.size()];
150                        for (int i=0; i<ddVirtualHosts.size(); i++) {                    
151                            virtualHosts[i] = ddVirtualHosts.get(i).trim();
152                        }
153                        ejbWebServiceGBean.setAttribute("virtualHosts", virtualHosts);
154                    }
155                    
156                    WebServiceSecurityType wsSecurity = wsBinding.getWebServiceSecurity();
157                    if (wsSecurity != null) {
158                        ejbWebServiceGBean.setAttribute("securityRealmName", wsSecurity.getSecurityRealmName().trim());
159                        ejbWebServiceGBean.setAttribute("transportGuarantee", wsSecurity.getTransportGuarantee().toString());
160                        ejbWebServiceGBean.setAttribute("authMethod", wsSecurity.getAuthMethod().value());
161                        if (wsSecurity.getRealmName() != null) {
162                            ejbWebServiceGBean.setAttribute("realmName", wsSecurity.getRealmName().trim());                    
163                        }
164                    }
165                }
166                
167                if (jaxwsBuilder.configureEJB(ejbWebServiceGBean, bean.ejbName, ejbModule, 
168                                              ejbModule.getSharedContext(), cl)) {
169    
170                    try {
171                        earContext.addGBean(ejbWebServiceGBean);
172                    } catch (GBeanAlreadyExistsException e) {
173                        throw new DeploymentException(
174                                "Could not add ejb web service gbean to context",
175                                e);
176                    }
177                    
178                    if (this.listener != null) {
179                        ejbWebServiceGBean.setReferencePattern("WebServiceContainer", this.listener);
180                    }
181                    
182                    ejbWebServiceGBean.setReferencePattern("EjbDeployment", sessionName);
183                }
184                
185                ejbWebServiceGBean.clearAttribute("ejbName");
186                ejbWebServiceGBean.clearAttribute("ejbClass");
187                
188            }
189        }
190        
191        private Map<String, WebServiceBindingType> createWebServiceBindingMap(EjbModule ejbModule) {
192            Map<String, WebServiceBindingType> wsBindingMap = 
193                new HashMap<String, WebServiceBindingType>();
194            GeronimoEjbJarType geronimoEjbJarType = 
195                (GeronimoEjbJarType) ejbModule.getEjbModule().getAltDDs().get("geronimo-openejb.xml");
196            if (geronimoEjbJarType != null) {
197                for (WebServiceBindingType bt : geronimoEjbJarType.getWebServiceBinding()) {
198                    wsBindingMap.put(bt.getEjbName(), bt);
199                }
200            }
201            return wsBindingMap;
202        } 
203        
204        public static final GBeanInfo GBEAN_INFO;
205    
206        static {
207            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JAXWSEJBModuleBuilderExtension.class, NameFactory.MODULE_BUILDER);
208            infoBuilder.addInterface(ModuleBuilderExtension.class);
209            infoBuilder.addReference("WebServiceBuilder", WebServiceBuilder.class, NameFactory.MODULE_BUILDER);
210            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
211            infoBuilder.addAttribute("listener", AbstractNameQuery.class, true);
212            infoBuilder.addReference("WebServiceLinkTemplate", Object.class, NameFactory.WEB_SERVICE_LINK);
213            infoBuilder.addAttribute("kernel", Kernel.class, false);
214    
215            infoBuilder.setConstructor(new String[]{
216                    "WebServiceBuilder",
217                    "defaultEnvironment", 
218                    "listener", 
219                    "WebServiceLinkTemplate",
220                    "kernel"
221            });
222    
223            GBEAN_INFO = infoBuilder.getBeanInfo();
224        }
225    
226        public static GBeanInfo getGBeanInfo() {
227            return GBEAN_INFO;
228        }    
229        
230    }