001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.axis.builder;
020    
021    import java.net.URI;
022    import java.net.URISyntaxException;
023    import java.util.ArrayList;
024    import java.util.HashMap;
025    import java.util.HashSet;
026    import java.util.List;
027    import java.util.Map;
028    import java.util.Set;
029    
030    import javax.xml.namespace.QName;
031    
032    import org.apache.geronimo.common.DeploymentException;
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.j2ee.deployment.HandlerInfoInfo;
036    import org.apache.geronimo.j2ee.deployment.Module;
037    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
038    import org.apache.geronimo.kernel.ClassLoading;
039    import org.apache.geronimo.kernel.config.Configuration;
040    import org.apache.geronimo.kernel.repository.Environment;
041    import org.apache.geronimo.naming.deployment.AbstractNamingBuilder;
042    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefDocument;
043    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
044    import org.apache.geronimo.xbeans.j2ee.ParamValueType;
045    import org.apache.geronimo.xbeans.j2ee.PortComponentRefType;
046    import org.apache.geronimo.xbeans.j2ee.ServiceRefHandlerType;
047    import org.apache.geronimo.xbeans.j2ee.ServiceRefType;
048    import org.apache.geronimo.xbeans.j2ee.XsdQNameType;
049    import org.apache.xmlbeans.QNameSet;
050    import org.apache.xmlbeans.XmlObject;
051    
052    /**
053     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
054     */
055    public class AxisServiceRefBuilder extends AbstractNamingBuilder {
056        private final QNameSet serviceRefQNameSet;
057        private static final QName GER_SERVICE_REF_QNAME = GerServiceRefDocument.type.getDocumentElementName();
058        private static final QNameSet GER_SERVICE_REF_QNAME_SET = QNameSet.singleton(GER_SERVICE_REF_QNAME);
059    
060        private final AxisBuilder axisBuilder;
061    
062        public AxisServiceRefBuilder(Environment defaultEnvironment, String[] eeNamespaces, AxisBuilder axisBuilder) {
063            super(defaultEnvironment);
064            this.axisBuilder = axisBuilder;
065            serviceRefQNameSet = buildQNameSet(eeNamespaces, "service-ref");
066        }
067    
068        protected boolean willMergeEnvironment(XmlObject specDD, XmlObject plan) {
069             return getServiceRefs(specDD).length > 0;
070        }
071        
072        public void buildNaming(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module, Map componentContext) throws DeploymentException {
073            XmlObject[] serviceRefsUntyped = getServiceRefs(specDD);
074            XmlObject[] gerServiceRefsUntyped = plan == null? NO_REFS: plan.selectChildren(GER_SERVICE_REF_QNAME_SET);
075            Map serviceRefMap = mapServiceRefs(gerServiceRefsUntyped);
076            ClassLoader cl = module.getEarContext().getClassLoader();
077    
078            for (int i = 0; i < serviceRefsUntyped.length; i++) {
079                ServiceRefType serviceRef = (ServiceRefType) serviceRefsUntyped[i];
080                String name = getStringValue(serviceRef.getServiceRefName());
081                GerServiceRefType serviceRefType = (GerServiceRefType) serviceRefMap.get(name);
082    //            Map credentialsNameMap = (Map) serviceRefCredentialsNameMap.get(name);
083                String serviceInterfaceName = getStringValue(serviceRef.getServiceInterface());
084                assureInterface(serviceInterfaceName, "javax.xml.rpc.Service", "[Web]Service", cl);
085                Class serviceInterface;
086                try {
087                    serviceInterface = cl.loadClass(serviceInterfaceName);
088                } catch (ClassNotFoundException e) {
089                    throw new DeploymentException("Could not load service interface class: " + serviceInterfaceName, e);
090                }
091                URI wsdlURI = null;
092                if (serviceRef.isSetWsdlFile()) {
093                    try {
094                        wsdlURI = new URI(serviceRef.getWsdlFile().getStringValue().trim());
095                    } catch (URISyntaxException e) {
096                        throw new DeploymentException("could not construct wsdl uri from " + serviceRef.getWsdlFile().getStringValue(), e);
097                    }
098                }
099                URI jaxrpcMappingURI = null;
100                if (serviceRef.isSetJaxrpcMappingFile()) {
101                    try {
102                        jaxrpcMappingURI = new URI(getStringValue(serviceRef.getJaxrpcMappingFile()));
103                    } catch (URISyntaxException e) {
104                        throw new DeploymentException("Could not construct jaxrpc mapping uri from " + serviceRef.getJaxrpcMappingFile(), e);
105                    }
106                }
107                QName serviceQName = null;
108                if (serviceRef.isSetServiceQname()) {
109                    serviceQName = serviceRef.getServiceQname().getQNameValue();
110                }
111                Map portComponentRefMap = new HashMap();
112                PortComponentRefType[] portComponentRefs = serviceRef.getPortComponentRefArray();
113                if (portComponentRefs != null) {
114                    for (int j = 0; j < portComponentRefs.length; j++) {
115                        PortComponentRefType portComponentRef = portComponentRefs[j];
116                        String portComponentLink = getStringValue(portComponentRef.getPortComponentLink());
117                        String serviceEndpointInterfaceType = getStringValue(portComponentRef.getServiceEndpointInterface());
118                        assureInterface(serviceEndpointInterfaceType, "java.rmi.Remote", "ServiceEndpoint", cl);
119                        Class serviceEndpointClass;
120                        try {
121                            serviceEndpointClass = cl.loadClass(serviceEndpointInterfaceType);
122                        } catch (ClassNotFoundException e) {
123                            throw new DeploymentException("could not load service endpoint class " + serviceEndpointInterfaceType, e);
124                        }
125                        portComponentRefMap.put(serviceEndpointClass, portComponentLink);
126                    }
127                }
128                ServiceRefHandlerType[] handlers = serviceRef.getHandlerArray();
129                List handlerInfos = buildHandlerInfoList(handlers, cl);
130    
131    //we could get a Reference or the actual serializable Service back.
132                Object ref = axisBuilder.createService(serviceInterface, wsdlURI, jaxrpcMappingURI, serviceQName, portComponentRefMap, handlerInfos, serviceRefType, module, cl);
133                getJndiContextMap(componentContext).put(ENV + name, ref);
134            }
135    
136        }
137    
138        private XmlObject[] getServiceRefs(XmlObject specDD) {
139            return convert(specDD.selectChildren(serviceRefQNameSet), J2EE_CONVERTER, ServiceRefType.type);
140        }
141    
142        public QNameSet getSpecQNameSet() {
143            return serviceRefQNameSet;
144        }
145    
146        public QNameSet getPlanQNameSet() {
147            return GER_SERVICE_REF_QNAME_SET;
148        }
149    
150    
151        private static List buildHandlerInfoList(ServiceRefHandlerType[] handlers, ClassLoader classLoader) throws DeploymentException {
152            List handlerInfos = new ArrayList();
153            for (int i = 0; i < handlers.length; i++) {
154                ServiceRefHandlerType handler = handlers[i];
155                org.apache.geronimo.xbeans.j2ee.String[] portNameArray = handler.getPortNameArray();
156                List portNames = new ArrayList();
157                for (int j = 0; j < portNameArray.length; j++) {
158                    portNames.add(portNameArray[j].getStringValue().trim());
159    
160                }
161    //            Set portNames = new HashSet(Arrays.asList(portNameArray));
162                String handlerClassName = handler.getHandlerClass().getStringValue().trim();
163                Class handlerClass;
164                try {
165                    handlerClass = ClassLoading.loadClass(handlerClassName, classLoader);
166                } catch (ClassNotFoundException e) {
167                    throw new DeploymentException("Could not load handler class", e);
168                }
169                Map config = new HashMap();
170                ParamValueType[] paramValues = handler.getInitParamArray();
171                for (int j = 0; j < paramValues.length; j++) {
172                    ParamValueType paramValue = paramValues[j];
173                    String paramName = paramValue.getParamName().getStringValue().trim();
174                    String paramStringValue = paramValue.getParamValue().getStringValue().trim();
175                    config.put(paramName, paramStringValue);
176                }
177                XsdQNameType[] soapHeaderQNames = handler.getSoapHeaderArray();
178                QName[] headerQNames = new QName[soapHeaderQNames.length];
179                for (int j = 0; j < soapHeaderQNames.length; j++) {
180                    XsdQNameType soapHeaderQName = soapHeaderQNames[j];
181                    headerQNames[j] = soapHeaderQName.getQNameValue();
182                }
183                Set soapRoles = new HashSet();
184                for (int j = 0; j < handler.getSoapRoleArray().length; j++) {
185                    String soapRole = handler.getSoapRoleArray(j).getStringValue().trim();
186                    soapRoles.add(soapRole);
187                }
188                HandlerInfoInfo handlerInfoInfo = new HandlerInfoInfo(new HashSet(portNames), handlerClass, config, headerQNames, soapRoles);
189                handlerInfos.add(handlerInfoInfo);
190            }
191            return handlerInfos;
192        }
193    
194    
195        private static Map mapServiceRefs(XmlObject[] refs) {
196            Map refMap = new HashMap();
197            if (refs != null) {
198                for (int i = 0; i < refs.length; i++) {
199                    GerServiceRefType ref = (GerServiceRefType) refs[i].copy().changeType(GerServiceRefType.type);
200                    String serviceRefName = ref.getServiceRefName().trim();
201                    refMap.put(serviceRefName, ref);
202                }
203            }
204            return refMap;
205        }
206    
207        public static final GBeanInfo GBEAN_INFO;
208    
209        static {
210            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(AxisServiceRefBuilder.class, NameFactory.MODULE_BUILDER);
211            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
212            infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
213            infoBuilder.addReference("AxisBuilder", AxisBuilder.class, NameFactory.MODULE_BUILDER);
214    
215            infoBuilder.setConstructor(new String[] {"defaultEnvironment", "eeNamespaces", "AxisBuilder"});
216    
217            GBEAN_INFO = infoBuilder.getBeanInfo();
218        }
219    
220        public static GBeanInfo getGBeanInfo() {
221            return GBEAN_INFO;
222        }
223    }