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.axis.builder;
019    
020    import java.net.URI;
021    import java.net.URISyntaxException;
022    import java.util.ArrayList;
023    import java.util.HashMap;
024    import java.util.HashSet;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.Set;
028    
029    import javax.xml.namespace.QName;
030    
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    import org.apache.geronimo.common.DeploymentException;
034    import org.apache.geronimo.gbean.GBeanInfo;
035    import org.apache.geronimo.gbean.GBeanInfoBuilder;
036    import org.apache.geronimo.j2ee.deployment.HandlerInfoInfo;
037    import org.apache.geronimo.j2ee.deployment.Module;
038    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
039    import org.apache.geronimo.kernel.ClassLoading;
040    import org.apache.geronimo.kernel.repository.Environment;
041    import org.apache.geronimo.naming.deployment.AbstractNamingBuilder;
042    import org.apache.geronimo.naming.deployment.ServiceRefBuilder;
043    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefDocument;
044    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
045    import org.apache.geronimo.xbeans.javaee.ParamValueType;
046    import org.apache.geronimo.xbeans.javaee.PortComponentRefType;
047    import org.apache.geronimo.xbeans.javaee.ServiceRefHandlerType;
048    import org.apache.geronimo.xbeans.javaee.ServiceRefType;
049    import org.apache.geronimo.xbeans.javaee.XsdQNameType;
050    import org.apache.xmlbeans.QNameSet;
051    import org.apache.xmlbeans.XmlObject;
052    
053    /**
054     * @version $Rev: 539548 $ $Date: 2007-05-18 14:29:40 -0400 (Fri, 18 May 2007) $
055     */
056    public class AxisServiceRefBuilder extends AbstractNamingBuilder implements ServiceRefBuilder {
057        private static final Log log = LogFactory.getLog(AxisServiceRefBuilder.class);
058        private final QNameSet serviceRefQNameSet;
059        private static final QName GER_SERVICE_REF_QNAME = GerServiceRefDocument.type.getDocumentElementName();
060        private static final QNameSet GER_SERVICE_REF_QNAME_SET = QNameSet.singleton(GER_SERVICE_REF_QNAME);
061    
062        private final AxisBuilder axisBuilder;
063    
064        public AxisServiceRefBuilder(Environment defaultEnvironment, String[] eeNamespaces, AxisBuilder axisBuilder) {
065            super(defaultEnvironment);
066            this.axisBuilder = axisBuilder;
067            serviceRefQNameSet = buildQNameSet(eeNamespaces, "service-ref");
068        }
069    
070        protected boolean willMergeEnvironment(XmlObject specDD, XmlObject plan) {
071            return specDD.selectChildren(serviceRefQNameSet).length > 0;
072        }
073    
074        public void buildNaming(XmlObject specDD, XmlObject plan, Module module, Map componentContext) throws DeploymentException {
075            List<ServiceRefType> serviceRefsUntyped = convert(specDD.selectChildren(serviceRefQNameSet), JEE_CONVERTER, ServiceRefType.class, ServiceRefType.type);
076            XmlObject[] gerServiceRefsUntyped = plan == null ? NO_REFS : plan.selectChildren(GER_SERVICE_REF_QNAME_SET);
077            Map serviceRefMap = mapServiceRefs(gerServiceRefsUntyped);
078    
079            for (ServiceRefType serviceRef : serviceRefsUntyped) {
080                String name = getStringValue(serviceRef.getServiceRefName());
081                addInjections(name, serviceRef.getInjectionTargetArray(), componentContext);
082                GerServiceRefType serviceRefType = (GerServiceRefType) serviceRefMap.get(name);
083                serviceRefMap.remove(name);
084                buildNaming(serviceRef, serviceRefType, module, componentContext);
085            }
086    
087            if (serviceRefMap.size() > 0) {
088                log.warn("Failed to build reference to service reference "+serviceRefMap.keySet()+" defined in plan file, reason - corresponding entry in deployment descriptor missing.");
089            }
090        }
091    
092        public void buildNaming(XmlObject serviceRef, GerServiceRefType gerServiceRefType, Module module, Map componentContext) throws DeploymentException {
093            ServiceRefType serviceRefType =
094                    (ServiceRefType) convert(serviceRef, JEE_CONVERTER, ServiceRefType.type);
095            buildNaming(serviceRefType, gerServiceRefType, module, componentContext);
096        }
097    
098        private void buildNaming(ServiceRefType serviceRef, GerServiceRefType serviceRefType, Module module, Map componentContext) throws DeploymentException {
099            String name = getStringValue(serviceRef.getServiceRefName());
100            ClassLoader cl = module.getEarContext().getClassLoader();
101    
102    //            Map credentialsNameMap = (Map) serviceRefCredentialsNameMap.get(name);
103            String serviceInterfaceName = getStringValue(serviceRef.getServiceInterface());
104            assureInterface(serviceInterfaceName, "javax.xml.rpc.Service", "[Web]Service", cl);
105            Class serviceInterface;
106            try {
107                serviceInterface = cl.loadClass(serviceInterfaceName);
108            } catch (ClassNotFoundException e) {
109                throw new DeploymentException("Could not load service interface class: " + serviceInterfaceName, e);
110            }
111            URI wsdlURI = null;
112            if (serviceRef.isSetWsdlFile()) {
113                try {
114                    wsdlURI = new URI(serviceRef.getWsdlFile().getStringValue().trim());
115                } catch (URISyntaxException e) {
116                    throw new DeploymentException("could not construct wsdl uri from " + serviceRef.getWsdlFile().getStringValue(), e);
117                }
118            }
119            URI jaxrpcMappingURI = null;
120            if (serviceRef.isSetJaxrpcMappingFile()) {
121                try {
122                    jaxrpcMappingURI = new URI(getStringValue(serviceRef.getJaxrpcMappingFile()));
123                } catch (URISyntaxException e) {
124                    throw new DeploymentException("Could not construct jaxrpc mapping uri from " + serviceRef.getJaxrpcMappingFile(), e);
125                }
126            }
127            QName serviceQName = null;
128            if (serviceRef.isSetServiceQname()) {
129                serviceQName = serviceRef.getServiceQname().getQNameValue();
130            }
131            Map portComponentRefMap = new HashMap();
132            PortComponentRefType[] portComponentRefs = serviceRef.getPortComponentRefArray();
133            if (portComponentRefs != null) {
134                for (int j = 0; j < portComponentRefs.length; j++) {
135                    PortComponentRefType portComponentRef = portComponentRefs[j];
136                    String portComponentLink = getStringValue(portComponentRef.getPortComponentLink());
137                    String serviceEndpointInterfaceType = getStringValue(portComponentRef.getServiceEndpointInterface());
138                    assureInterface(serviceEndpointInterfaceType, "java.rmi.Remote", "ServiceEndpoint", cl);
139                    Class serviceEndpointClass;
140                    try {
141                        serviceEndpointClass = cl.loadClass(serviceEndpointInterfaceType);
142                    } catch (ClassNotFoundException e) {
143                        throw new DeploymentException("could not load service endpoint class " + serviceEndpointInterfaceType, e);
144                    }
145                    portComponentRefMap.put(serviceEndpointClass, portComponentLink);
146                }
147            }
148            ServiceRefHandlerType[] handlers = serviceRef.getHandlerArray();
149            List handlerInfos = buildHandlerInfoList(handlers, cl);
150    
151    //we could get a Reference or the actual serializable Service back.
152            Object ref = axisBuilder.createService(serviceInterface, wsdlURI, jaxrpcMappingURI, serviceQName, portComponentRefMap, handlerInfos, serviceRefType, module, cl);
153            getJndiContextMap(componentContext).put(ENV + name, ref);
154        }
155    
156        public QNameSet getSpecQNameSet() {
157            return serviceRefQNameSet;
158        }
159    
160        public QNameSet getPlanQNameSet() {
161            return GER_SERVICE_REF_QNAME_SET;
162        }
163    
164    
165        private static List buildHandlerInfoList(ServiceRefHandlerType[] handlers, ClassLoader classLoader) throws DeploymentException {
166            List handlerInfos = new ArrayList();
167            for (int i = 0; i < handlers.length; i++) {
168                ServiceRefHandlerType handler = handlers[i];
169                org.apache.geronimo.xbeans.javaee.String[] portNameArray = handler.getPortNameArray();
170                List portNames = new ArrayList();
171                for (int j = 0; j < portNameArray.length; j++) {
172                    portNames.add(portNameArray[j].getStringValue().trim());
173    
174                }
175    //            Set portNames = new HashSet(Arrays.asList(portNameArray));
176                String handlerClassName = handler.getHandlerClass().getStringValue().trim();
177                Class handlerClass;
178                try {
179                    handlerClass = ClassLoading.loadClass(handlerClassName, classLoader);
180                } catch (ClassNotFoundException e) {
181                    throw new DeploymentException("Could not load handler class", e);
182                }
183                Map config = new HashMap();
184                ParamValueType[] paramValues = handler.getInitParamArray();
185                for (int j = 0; j < paramValues.length; j++) {
186                    ParamValueType paramValue = paramValues[j];
187                    String paramName = paramValue.getParamName().getStringValue().trim();
188                    String paramStringValue = paramValue.getParamValue().getStringValue().trim();
189                    config.put(paramName, paramStringValue);
190                }
191                XsdQNameType[] soapHeaderQNames = handler.getSoapHeaderArray();
192                QName[] headerQNames = new QName[soapHeaderQNames.length];
193                for (int j = 0; j < soapHeaderQNames.length; j++) {
194                    XsdQNameType soapHeaderQName = soapHeaderQNames[j];
195                    headerQNames[j] = soapHeaderQName.getQNameValue();
196                }
197                Set soapRoles = new HashSet();
198                for (int j = 0; j < handler.getSoapRoleArray().length; j++) {
199                    String soapRole = handler.getSoapRoleArray(j).getStringValue().trim();
200                    soapRoles.add(soapRole);
201                }
202                HandlerInfoInfo handlerInfoInfo = new HandlerInfoInfo(new HashSet(portNames), handlerClass, config, headerQNames, soapRoles);
203                handlerInfos.add(handlerInfoInfo);
204            }
205            return handlerInfos;
206        }
207    
208        private static Map mapServiceRefs(XmlObject[] refs) {
209            Map refMap = new HashMap();
210            if (refs != null) {
211                for (int i = 0; i < refs.length; i++) {
212                    GerServiceRefType ref = (GerServiceRefType) refs[i].copy().changeType(GerServiceRefType.type);
213                    String serviceRefName = ref.getServiceRefName().trim();
214                    refMap.put(serviceRefName, ref);
215                }
216            }
217            return refMap;
218        }
219    
220        // This is temporary
221        private static String getStringValue(org.apache.geronimo.xbeans.j2ee.String string) {
222            if (string == null) {
223                return null;
224            }
225            String s = string.getStringValue();
226            return s == null ? null : s.trim();
227        }
228    
229        public static final GBeanInfo GBEAN_INFO;
230    
231        static {
232            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(AxisServiceRefBuilder.class, NameFactory.MODULE_BUILDER);
233            infoBuilder.addInterface(ServiceRefBuilder.class);
234            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
235            infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
236            infoBuilder.addReference("AxisBuilder", AxisBuilder.class, NameFactory.MODULE_BUILDER);
237    
238            infoBuilder.setConstructor(new String[]{"defaultEnvironment", "eeNamespaces", "AxisBuilder"});
239    
240            GBEAN_INFO = infoBuilder.getBeanInfo();
241        }
242    
243        public static GBeanInfo getGBeanInfo() {
244            return GBEAN_INFO;
245        }
246    }