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