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.axis.builder;
018    
019    import java.lang.reflect.Method;
020    import java.net.MalformedURLException;
021    import java.net.URI;
022    import java.net.URISyntaxException;
023    import java.net.URL;
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Collections;
027    import java.util.HashMap;
028    import java.util.HashSet;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.Set;
033    import java.util.jar.JarFile;
034    
035    import javax.jws.WebService;
036    import javax.wsdl.Binding;
037    import javax.wsdl.BindingOperation;
038    import javax.wsdl.Definition;
039    import javax.wsdl.Operation;
040    import javax.wsdl.Port;
041    import javax.wsdl.PortType;
042    import javax.wsdl.extensions.soap.SOAPAddress;
043    import javax.wsdl.extensions.soap.SOAPBinding;
044    import javax.xml.namespace.QName;
045    import javax.xml.rpc.handler.HandlerInfo;
046    import javax.xml.ws.WebServiceProvider;
047    
048    import org.apache.axis.constants.Style;
049    import org.apache.axis.description.JavaServiceDesc;
050    import org.apache.axis.handlers.HandlerInfoChainFactory;
051    import org.apache.axis.handlers.soap.SOAPService;
052    import org.apache.axis.providers.java.RPCProvider;
053    import org.apache.axis.soap.SOAPConstants;
054    import org.apache.commons.logging.Log;
055    import org.apache.commons.logging.LogFactory;
056    import org.apache.geronimo.axis.client.AxisServiceReference;
057    import org.apache.geronimo.axis.client.OperationInfo;
058    import org.apache.geronimo.axis.client.SEIFactory;
059    import org.apache.geronimo.axis.client.SEIFactoryImpl;
060    import org.apache.geronimo.axis.server.AxisWebServiceContainer;
061    import org.apache.geronimo.axis.server.POJOProvider;
062    import org.apache.geronimo.axis.server.ServiceInfo;
063    import org.apache.geronimo.common.DeploymentException;
064    import org.apache.geronimo.gbean.GBeanData;
065    import org.apache.geronimo.gbean.GBeanInfo;
066    import org.apache.geronimo.gbean.GBeanInfoBuilder;
067    import org.apache.geronimo.gbean.AbstractName;
068    import org.apache.geronimo.j2ee.deployment.Module;
069    import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
070    import org.apache.geronimo.j2ee.deployment.HandlerInfoInfo;
071    import org.apache.geronimo.j2ee.deployment.WebModule;
072    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
073    import org.apache.geronimo.xbeans.geronimo.naming.GerPortCompletionType;
074    import org.apache.geronimo.xbeans.geronimo.naming.GerPortType;
075    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceCompletionType;
076    import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
077    import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType;
078    import org.apache.geronimo.xbeans.j2ee.JavaXmlTypeMappingType;
079    import org.apache.geronimo.xbeans.j2ee.ServiceEndpointInterfaceMappingType;
080    import org.apache.geronimo.xbeans.j2ee.ServiceEndpointMethodMappingType;
081    import org.apache.geronimo.deployment.util.DeploymentUtil;
082    import org.apache.geronimo.deployment.DeploymentContext;
083    import org.apache.geronimo.deployment.service.EnvironmentBuilder;
084    import org.apache.geronimo.webservices.SerializableWebServiceContainerFactoryGBean;
085    import org.apache.geronimo.webservices.builder.DescriptorVersion;
086    import org.apache.geronimo.webservices.builder.PortInfo;
087    import org.apache.geronimo.webservices.builder.SchemaInfoBuilder;
088    import org.apache.geronimo.webservices.builder.WSDescriptorParser;
089    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
090    import org.apache.geronimo.kernel.repository.Environment;
091    
092    /**
093     * @version $Rev: 561670 $ $Date: 2007-08-01 01:59:34 -0400 (Wed, 01 Aug 2007) $
094     */
095    public class AxisBuilder implements WebServiceBuilder {
096    
097        private static final Log LOG = LogFactory.getLog(AxisBuilder.class);
098        
099        private static final SOAPConstants SOAP_VERSION = SOAPConstants.SOAP11_CONSTANTS;
100    
101        private final Environment defaultEnvironment;
102        private static final String KEY = AxisBuilder.class.getName();
103    
104        public AxisBuilder() {
105            defaultEnvironment = null;
106        }
107    
108        public AxisBuilder(Environment defaultEnvironment) {
109            this.defaultEnvironment = defaultEnvironment;
110        }
111    
112        public void findWebServices(Module module, boolean isEJB, Map servletLocations, Environment environment, Map sharedContext) throws DeploymentException {
113            findWebServices(module.getModuleFile(), isEJB, servletLocations, environment, sharedContext);       
114        }
115        
116        public void findWebServices(JarFile moduleFile, boolean isEJB, Map servletLocations, Environment environment, Map sharedContext) throws DeploymentException {
117            final String path = isEJB ? "META-INF/webservices.xml" : "WEB-INF/webservices.xml";
118            try {
119                URL wsDDUrl = DeploymentUtil.createJarURL(moduleFile, path);
120                Map portMap = WSDescriptorParser.parseWebServiceDescriptor(wsDDUrl, moduleFile, isEJB, servletLocations);
121                if (portMap != null) {
122                    if (defaultEnvironment != null) {
123                        EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
124                    }
125                    sharedContext.put(KEY, portMap);
126                } else {
127                    sharedContext.put(KEY, Collections.EMPTY_MAP);
128                }
129            } catch (MalformedURLException e) {
130                // The webservices.xml file doesn't exist.
131            }
132        }
133    
134        public boolean configurePOJO(GBeanData targetGBean, String servletName, Module module, String servletClassName, DeploymentContext context) throws DeploymentException {
135            Map sharedContext = ((WebModule) module).getSharedContext();
136            Map portInfoMap = (Map) sharedContext.get(KEY);
137            PortInfo portInfo = (PortInfo) portInfoMap.get(servletName);
138            if (portInfo == null) {
139                //not ours
140                return false;
141            }
142            
143            ClassLoader cl = context.getClassLoader();
144            Class serviceClass = loadClass(servletClassName, cl);        
145            if (isJAXWSWebService(serviceClass)) {
146                if (DescriptorVersion.J2EE.equals(portInfo.getDescriptorVersion())) {
147                    // This is a JAX-WS web service in J2EE descriptor so throw an exception
148                    throw new DeploymentException("JAX-WS web service '" + portInfo.getPortComponentName() 
149                                                  + "' cannot be specified in J2EE webservices.xml descriptor.");
150                } else {
151                    // This is a JAX-WS web service in JAVAEE descriptor so ignore
152                    return false;
153                }
154            }
155            
156            portInfo.initialize(module.getModuleFile());
157            
158            LOG.debug("Publishing JAX-RPC '" + portInfo.getPortComponentName() 
159                      + "' service at " + portInfo.getContextURI());
160            
161            ServiceInfo serviceInfo = AxisServiceBuilder.createServiceInfo(portInfo, cl);
162            JavaServiceDesc serviceDesc = serviceInfo.getServiceDesc();
163    
164            targetGBean.setAttribute("pojoClassName", servletClassName);
165            RPCProvider provider = new POJOProvider();
166    
167            SOAPService service = new SOAPService(null, provider, null);
168            service.setServiceDescription(serviceDesc);
169            service.setOption("className", servletClassName);
170    
171            HandlerInfoChainFactory handlerInfoChainFactory = new HandlerInfoChainFactory(serviceInfo.getHandlerInfos());
172            service.setOption(org.apache.axis.Constants.ATTR_HANDLERINFOCHAIN, handlerInfoChainFactory);
173    
174            URI location;
175            try {
176                location = new URI(serviceDesc.getEndpointURL());
177            } catch (URISyntaxException e) {
178                throw new DeploymentException("Invalid webservice endpoint URI", e);
179            }
180            URI wsdlURI;
181            try {
182                wsdlURI = new URI(serviceDesc.getWSDLFile());
183            } catch (URISyntaxException e) {
184                throw new DeploymentException("Invalid wsdl URI", e);
185    
186            }
187    
188            AxisWebServiceContainer axisWebServiceContainer = new AxisWebServiceContainer(location, wsdlURI, service, serviceInfo.getWsdlMap(), cl);
189            AbstractName webServiceContainerFactoryName = context.getNaming().createChildName(targetGBean.getAbstractName(), "webServiceContainer", NameFactory.GERONIMO_SERVICE);
190            GBeanData webServiceContainerFactoryGBean = new GBeanData(webServiceContainerFactoryName, SerializableWebServiceContainerFactoryGBean.GBEAN_INFO);
191            webServiceContainerFactoryGBean.setAttribute("webServiceContainer", axisWebServiceContainer);
192            try {
193                context.addGBean(webServiceContainerFactoryGBean);
194            } catch (GBeanAlreadyExistsException e) {
195                throw new DeploymentException("Could not add webServiceContainerFactoryGBean", e);
196            }
197            targetGBean.setReferencePattern("WebServiceContainerFactory", webServiceContainerFactoryName);
198            return true;
199        }
200    
201        public boolean configureEJB(GBeanData targetGBean, String ejbName, Module module, Map sharedContext, ClassLoader classLoader) throws DeploymentException {
202            Map portInfoMap = (Map) sharedContext.get(KEY);
203            PortInfo portInfo = (PortInfo) portInfoMap.get(ejbName);
204            if (portInfo == null) {
205                //not ours
206                return false;
207            }
208            
209            String beanClassName = (String)targetGBean.getAttribute("ejbClass");
210            Class serviceClass = loadClass(beanClassName, classLoader);
211            if (isJAXWSWebService(serviceClass)) {
212                if (DescriptorVersion.J2EE.equals(portInfo.getDescriptorVersion())) {
213                    // This is a JAX-WS web service in J2EE descriptor so throw an exception
214                    throw new DeploymentException("JAX-WS web service '" + portInfo.getPortComponentName() 
215                                                  + "' cannot be specified in J2EE webservices.xml descriptor.");
216                } else {
217                    // This is a JAX-WS web service in JAVAEE descriptor so ignore
218                    return false;
219                }
220            }
221            
222            portInfo.initialize(module.getModuleFile());
223            
224            LOG.debug("Publishing EJB JAX-RPC '" + portInfo.getPortComponentName() 
225                      + "' service at " + portInfo.getContextURI());
226            
227            ServiceInfo serviceInfo = AxisServiceBuilder.createServiceInfo(portInfo, classLoader);
228            targetGBean.setAttribute("serviceInfo", serviceInfo);
229            JavaServiceDesc serviceDesc = serviceInfo.getServiceDesc();
230            URI location = portInfo.getContextURI();
231            targetGBean.setAttribute("location", location);
232            URI wsdlURI;
233            try {
234                wsdlURI = new URI(serviceDesc.getWSDLFile());
235            } catch (URISyntaxException e) {
236                throw new DeploymentException("Invalid wsdl URI", e);
237            }
238            targetGBean.setAttribute("wsdlURI", wsdlURI);
239            return true;
240        }
241    
242    
243        //ServicereferenceBuilder
244        public Object createService(Class serviceInterface, URI wsdlURI, URI jaxrpcMappingURI, QName serviceQName, Map portComponentRefMap, List handlerInfos, Object serviceRefType, Module module, ClassLoader classLoader) throws DeploymentException {
245            GerServiceRefType gerServiceRefType = (GerServiceRefType) serviceRefType;
246            JarFile moduleFile = module.getModuleFile();
247            SchemaInfoBuilder schemaInfoBuilder = null;
248            JavaWsdlMappingType mapping = null;
249            if (wsdlURI != null) {
250                schemaInfoBuilder = new SchemaInfoBuilder(moduleFile, wsdlURI);
251    
252                mapping = WSDescriptorParser.readJaxrpcMapping(moduleFile, jaxrpcMappingURI);
253            }
254    
255            return createService(serviceInterface, schemaInfoBuilder, mapping, serviceQName, SOAP_VERSION, handlerInfos, gerServiceRefType, module, classLoader);
256        }
257    
258        public Object createService(Class serviceInterface, SchemaInfoBuilder schemaInfoBuilder, JavaWsdlMappingType mapping, QName serviceQName, SOAPConstants soapVersion, List handlerInfos, GerServiceRefType serviceRefType, Module module, ClassLoader classloader) throws DeploymentException {
259            Map seiPortNameToFactoryMap = new HashMap();
260            Map seiClassNameToFactoryMap = new HashMap();
261            if (schemaInfoBuilder != null) {
262                buildSEIFactoryMap(schemaInfoBuilder, serviceRefType, mapping, handlerInfos, serviceQName, soapVersion, seiPortNameToFactoryMap, seiClassNameToFactoryMap, classloader);
263            }
264            return new AxisServiceReference(serviceInterface.getName(), seiPortNameToFactoryMap, seiClassNameToFactoryMap);
265        }
266    
267        public void buildSEIFactoryMap(SchemaInfoBuilder schemaInfoBuilder, GerServiceRefType serviceRefType, JavaWsdlMappingType mapping, List handlerInfos, QName serviceQName, SOAPConstants soapVersion, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap, ClassLoader classLoader) throws DeploymentException {
268            Map exceptionMap = WSDescriptorParser.getExceptionMap(mapping);
269    
270            Definition definition = schemaInfoBuilder.getDefinition();
271            //check for consistency
272            if (definition.getServices().size() == 0) {
273                //partial wsdl
274                if (serviceRefType == null || !serviceRefType.isSetServiceCompletion()) {
275                    throw new DeploymentException("Partial wsdl, but no service completion supplied");
276                }
277                GerServiceCompletionType serviceCompletion = serviceRefType.getServiceCompletion();
278                String serviceLocalName = serviceCompletion.getServiceName().trim();
279                String namespace = definition.getTargetNamespace();
280                serviceQName = new QName(namespace, serviceLocalName);
281                javax.wsdl.Service service = definition.createService();
282                service.setQName(serviceQName);
283                GerPortCompletionType[] portCompletions = serviceCompletion.getPortCompletionArray();
284                for (int i = 0; i < portCompletions.length; i++) {
285                    GerPortCompletionType portCompletion = portCompletions[i];
286                    GerPortType port = portCompletion.getPort();
287                    URL location = getLocation(port);
288                    String portName = port.getPortName().trim();
289                    String bindingName = portCompletion.getBindingName().trim();
290                    QName bindingQName = new QName(namespace, bindingName);
291                    Binding binding = definition.getBinding(bindingQName);
292                    if (binding == null) {
293                        throw new DeploymentException("No binding found with qname: " + bindingQName);
294                    }
295                    String credentialsName = port.isSetCredentialsName() ? port.getCredentialsName().trim() : null;
296                    mapBinding(binding, mapping, serviceQName, classLoader, soapVersion, schemaInfoBuilder, portName, location, handlerInfos, seiPortNameToFactoryMap, seiClassNameToFactoryMap, credentialsName, exceptionMap);
297    
298                }
299            } else {
300                //full wsdl
301                if (serviceRefType != null && serviceRefType.isSetServiceCompletion()) {
302                    throw new DeploymentException("Full wsdl, but service completion supplied");
303                }
304                //organize the extra port info
305                Map portMap = new HashMap();
306                if (serviceRefType != null) {
307                    GerPortType[] ports = serviceRefType.getPortArray();
308                    for (int i = 0; i < ports.length; i++) {
309                        GerPortType port = ports[i];
310                        String portName = port.getPortName().trim();
311                        portMap.put(portName, port);
312                    }
313                }
314    
315                //find the service we are working with
316                javax.wsdl.Service service = getService(serviceQName, schemaInfoBuilder.getDefinition());
317                if (serviceQName == null) {
318                    serviceQName = service.getQName();
319                }
320    
321                Map wsdlPortMap = service.getPorts();
322                for (Iterator iterator = wsdlPortMap.entrySet().iterator(); iterator.hasNext();) {
323                    Map.Entry entry = (Map.Entry) iterator.next();
324                    String portName = (String) entry.getKey();
325                    Port port = (Port) entry.getValue();
326    
327                    GerPortType gerPort = (GerPortType) portMap.get(portName);
328    
329                    URL location = gerPort == null ? getAddressLocation(port) : getLocation(gerPort);
330                    //skip non-soap ports
331                    if (location == null) {
332                        continue;
333                    }
334                    String credentialsName = gerPort == null || gerPort.getCredentialsName() == null ? null : gerPort.getCredentialsName().trim();
335    
336                    Binding binding = port.getBinding();
337    
338                    mapBinding(binding, mapping, serviceQName, classLoader, soapVersion, schemaInfoBuilder, portName, location, handlerInfos, seiPortNameToFactoryMap, seiClassNameToFactoryMap, credentialsName, exceptionMap);
339                }
340            }
341        }
342    
343        private void mapBinding(Binding binding, JavaWsdlMappingType mapping, QName serviceQName, ClassLoader classLoader, SOAPConstants soapVersion, SchemaInfoBuilder schemaInfoBuilder, String portName, URL location, List handlerInfos, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap, String credentialsName, Map exceptionMap) throws DeploymentException {
344            Style portStyle = getStyle(binding);
345    
346            PortType portType = binding.getPortType();
347    
348            ServiceEndpointInterfaceMappingType[] endpointMappings = mapping.getServiceEndpointInterfaceMappingArray();
349    
350            //port type corresponds to SEI
351            List operations = portType.getOperations();
352            OperationInfo[] operationInfos = new OperationInfo[operations.size()];
353            if (endpointMappings.length == 0) {
354                doLightweightMapping(serviceQName, portType, mapping, classLoader, operations, binding, portStyle, soapVersion, operationInfos, schemaInfoBuilder, portName, location, handlerInfos, seiPortNameToFactoryMap, seiClassNameToFactoryMap, credentialsName);
355            } else {
356                doHeavyweightMapping(serviceQName, portType, endpointMappings, classLoader, operations, binding, portStyle, soapVersion, exceptionMap, schemaInfoBuilder, mapping, operationInfos, portName, location, handlerInfos, seiPortNameToFactoryMap, seiClassNameToFactoryMap, credentialsName);
357            }
358        }
359    
360        private URL getLocation(GerPortType port) throws DeploymentException {
361            String protocol = port.getProtocol().trim();
362            String host = port.getHost().trim();
363            int portNum = port.getPort();
364            String uri = port.getUri().trim();
365            String locationURIString = protocol + "://" + host + ":" + portNum + uri;
366            URL location;
367            try {
368                location = new URL(locationURIString);
369            } catch (MalformedURLException e) {
370                throw new DeploymentException("Could not construct web service location URL from " + locationURIString, e);
371            }
372            return location;
373        }
374    
375        private javax.wsdl.Service getService(QName serviceQName, Definition definition) throws DeploymentException {
376            javax.wsdl.Service service;
377            if (serviceQName != null) {
378                service = definition.getService(serviceQName);
379                if (service == null) {
380                    throw new DeploymentException("No service wsdl for supplied service qname " + serviceQName);
381                }
382            } else {
383                Map services = definition.getServices();
384                if (services.size() > 1) {
385                    throw new DeploymentException("no serviceQName supplied, and there are " + services.size() + " services");
386                }
387                if (services.size() == 0) {
388                    throw new DeploymentException("No service in wsdl, and no service completion supplied!");
389                } else {
390                    service = (javax.wsdl.Service) services.values().iterator().next();
391                }
392            }
393            return service;
394        }
395    
396        private Style getStyle(Binding binding) throws DeploymentException {
397            SOAPBinding soapBinding = (SOAPBinding) SchemaInfoBuilder.getExtensibilityElement(SOAPBinding.class, binding.getExtensibilityElements());
398    //            String transportURI = soapBinding.getTransportURI();
399            String portStyleString = soapBinding.getStyle();
400            return Style.getStyle(portStyleString);
401        }
402    
403        private URL getAddressLocation(Port port) throws DeploymentException {
404            SOAPAddress soapAddress;
405            try {
406                soapAddress = (SOAPAddress) SchemaInfoBuilder.getExtensibilityElement(SOAPAddress.class, port.getExtensibilityElements());
407            } catch (DeploymentException e) {
408                //a http: protocol REST service.  Skip it.
409                return null;
410            }
411            String locationURIString = soapAddress.getLocationURI();
412            URL location;
413            try {
414                location = new URL(locationURIString);
415            } catch (MalformedURLException e) {
416                throw new DeploymentException("Could not construct web service location URL from " + locationURIString, e);
417            }
418            return location;
419        }
420    
421        private void doHeavyweightMapping(QName serviceName, PortType portType, ServiceEndpointInterfaceMappingType[] endpointMappings, ClassLoader classLoader, List operations, Binding binding, Style portStyle, SOAPConstants soapVersion, Map exceptionMap, SchemaInfoBuilder schemaInfoBuilder, JavaWsdlMappingType mapping, OperationInfo[] operationInfos, String portName, URL location, List handlerInfos, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap, String credentialsName) throws DeploymentException {
422            Class serviceEndpointInterface;
423            SEIFactory seiFactory;
424            //complete jaxrpc mapping file supplied
425            QName portTypeQName = portType.getQName();
426            ServiceEndpointInterfaceMappingType endpointMapping = WSDescriptorParser.getServiceEndpointInterfaceMapping(endpointMappings, portTypeQName);
427            String fqcn = endpointMapping.getServiceEndpointInterface().getStringValue();
428            try {
429                serviceEndpointInterface = classLoader.loadClass(fqcn);
430            } catch (ClassNotFoundException e) {
431                throw new DeploymentException("Could not load service endpoint interface", e);
432            }
433    //        Class enhancedServiceEndpointClass = enhanceServiceEndpointInterface(serviceEndpointInterface, context, module, classLoader);
434    
435            Collection operationDescs = new ArrayList();
436            ServiceEndpointMethodMappingType[] methodMappings = endpointMapping.getServiceEndpointMethodMappingArray();
437            int i = 0;
438            Set wrapperElementQNames = new HashSet();
439            JavaXmlTypeMappingType[] javaXmlTypeMappings = mapping.getJavaXmlTypeMappingArray();
440            boolean hasEncoded = false;
441            for (Iterator ops = operations.iterator(); ops.hasNext();) {
442                Operation operation = (Operation) ops.next();
443                String operationName = operation.getName();
444                //the obvious method seems to be buggy
445    //            BindingOperation bindingOperation = binding.getBindingOperation(operationName, operation.getInput().getName(), operation.getOutput() == null ? null : operation.getOutput().getName());
446                BindingOperation bindingOperation = null;
447                List bops = binding.getBindingOperations();
448                for (Iterator iterator = bops.iterator(); iterator.hasNext();) {
449                    BindingOperation bindingOperation1 = (BindingOperation) iterator.next();
450                    if (bindingOperation1.getOperation().equals(operation)) {
451                        bindingOperation = bindingOperation1;
452                        break;
453                    }
454                }
455                if (bindingOperation == null) {
456                    throw new DeploymentException("No BindingOperation for operation: " + operationName + ", input: " + operation.getInput().getName() + ", output: " + (operation.getOutput() == null ? "<none>" : operation.getOutput().getName()));
457                }
458                ServiceEndpointMethodMappingType methodMapping = WSDescriptorParser.getMethodMappingForOperation(operationName, methodMappings);
459                HeavyweightOperationDescBuilder operationDescBuilder = new HeavyweightOperationDescBuilder(bindingOperation, mapping, methodMapping, portStyle, exceptionMap, schemaInfoBuilder, javaXmlTypeMappings, classLoader, serviceEndpointInterface);
460                OperationInfo operationInfo = operationDescBuilder.buildOperationInfo(soapVersion);
461                operationInfos[i++] = operationInfo;
462                operationDescs.add(operationInfo.getOperationDesc());
463                wrapperElementQNames.addAll(operationDescBuilder.getWrapperElementQNames());
464                hasEncoded |= operationDescBuilder.isEncoded();
465            }
466            HeavyweightTypeInfoBuilder builder = new HeavyweightTypeInfoBuilder(classLoader, schemaInfoBuilder.getSchemaTypeKeyToSchemaTypeMap(), wrapperElementQNames, operationDescs, hasEncoded);
467            List typeInfo = builder.buildTypeInfo(mapping);
468    
469            seiFactory = createSEIFactory(serviceName, portName, serviceEndpointInterface.getName(), typeInfo, location, operationInfos, handlerInfos, credentialsName);
470            seiPortNameToFactoryMap.put(portName, seiFactory);
471            seiClassNameToFactoryMap.put(serviceEndpointInterface.getName(), seiFactory);
472        }
473    
474        private void doLightweightMapping(QName serviceName, PortType portType, JavaWsdlMappingType mapping, ClassLoader classLoader, List operations, Binding binding, Style portStyle, SOAPConstants soapVersion, OperationInfo[] operationInfos, SchemaInfoBuilder schemaInfoBuilder, String portName, URL location, List handlerInfos, Map seiPortNameToFactoryMap, Map seiClassNameToFactoryMap, String credentialsName) throws DeploymentException {
475            Class serviceEndpointInterface;
476            SEIFactory seiFactory;
477            //lightweight jaxrpc mapping supplied
478            serviceEndpointInterface = getServiceEndpointInterfaceLightweight(portType, mapping, classLoader);
479    //        Class enhancedServiceEndpointClass = enhanceServiceEndpointInterface(serviceEndpointInterface, context, module, classLoader);
480    
481            int i = 0;
482            for (Iterator ops = operations.iterator(); ops.hasNext();) {
483                Operation operation = (Operation) ops.next();
484                Method method = WSDescriptorParser.getMethodForOperation(serviceEndpointInterface, operation);
485                BindingOperation bindingOperation = binding.getBindingOperation(operation.getName(), operation.getInput().getName(), operation.getOutput() == null ? null : operation.getOutput().getName());
486                operationInfos[i++] = buildOperationInfoLightweight(method, bindingOperation, portStyle, soapVersion);
487            }
488            LightweightTypeInfoBuilder builder = new LightweightTypeInfoBuilder(classLoader, schemaInfoBuilder.getSchemaTypeKeyToSchemaTypeMap(), Collections.EMPTY_SET);
489            List typeInfo = builder.buildTypeInfo(mapping);
490    
491            seiFactory = createSEIFactory(serviceName, portName, serviceEndpointInterface.getName(), typeInfo, location, operationInfos, handlerInfos, credentialsName);
492            seiPortNameToFactoryMap.put(portName, seiFactory);
493            seiClassNameToFactoryMap.put(serviceEndpointInterface.getName(), seiFactory);
494        }
495    
496        private Class getServiceEndpointInterfaceLightweight(PortType portType, JavaWsdlMappingType mappings, ClassLoader classLoader) throws DeploymentException {
497            QName portTypeQName = portType.getQName();
498            String portTypeNamespace = portTypeQName.getNamespaceURI();
499            String portTypePackage = WSDescriptorParser.getPackageFromNamespace(portTypeNamespace, mappings);
500            StringBuffer shortInterfaceName = new StringBuffer(portTypeQName.getLocalPart());
501            shortInterfaceName.setCharAt(0, Character.toUpperCase(shortInterfaceName.charAt(0)));
502            //TODO just use one buffer!
503            String fqcn = portTypePackage + "." + shortInterfaceName.toString();
504            try {
505                return classLoader.loadClass(fqcn);
506            } catch (ClassNotFoundException e) {
507                throw new DeploymentException("Could not load service endpoint interface type", e);
508            }
509        }
510    
511    
512        public SEIFactory createSEIFactory(QName serviceName, String portName, String enhancedServiceEndpointClassName, List typeInfo, URL location, OperationInfo[] operationInfos, List handlerInfoInfos, String credentialsName) throws DeploymentException {
513            List handlerInfos = buildHandlerInfosForPort(portName, handlerInfoInfos);
514            return new SEIFactoryImpl(serviceName, portName, enhancedServiceEndpointClassName, operationInfos, typeInfo, location, handlerInfos, credentialsName);
515        }
516    
517        private List buildHandlerInfosForPort(String portName, List handlerInfoInfos) {
518            List handlerInfos = new ArrayList();
519            for (Iterator iterator = handlerInfoInfos.iterator(); iterator.hasNext();) {
520                HandlerInfoInfo handlerInfoInfo = (HandlerInfoInfo) iterator.next();
521                Set portNames = handlerInfoInfo.getPortNames();
522                if (portNames.isEmpty() || portNames.contains(portName)) {
523                    HandlerInfo handlerInfo = new HandlerInfo(handlerInfoInfo.getHandlerClass(), handlerInfoInfo.getHandlerConfig(), handlerInfoInfo.getSoapHeaders());
524                    handlerInfos.add(handlerInfo);
525    
526                    //TODO what about the soap roles??
527                }
528            }
529            return handlerInfos;
530        }
531    
532        public OperationInfo buildOperationInfoLightweight(Method method, BindingOperation bindingOperation, Style defaultStyle, SOAPConstants soapVersion) throws DeploymentException {
533            LightweightOperationDescBuilder operationDescBuilder = new LightweightOperationDescBuilder(bindingOperation, method);
534            return operationDescBuilder.buildOperationInfo(soapVersion);
535        }
536    
537    
538        Class<?> loadClass(String className, ClassLoader loader) throws DeploymentException {
539            try {
540                return loader.loadClass(className);
541            } catch (ClassNotFoundException ex) {
542                throw new DeploymentException("Unable to load Web Service class: " + className);
543            }
544        }
545        
546        static boolean isJAXWSWebService(Class clazz) {
547            return (clazz.isAnnotationPresent(WebService.class) || 
548                    clazz.isAnnotationPresent(WebServiceProvider.class));
549        }
550        
551        public static final GBeanInfo GBEAN_INFO;
552    
553        static {
554            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(AxisBuilder.class, NameFactory.MODULE_BUILDER);
555            infoBuilder.addInterface(WebServiceBuilder.class);
556            infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
557    
558            infoBuilder.setConstructor(new String[]{"defaultEnvironment"});
559    
560            GBEAN_INFO = infoBuilder.getBeanInfo();
561        }
562    
563        public static GBeanInfo getGBeanInfo() {
564            return GBEAN_INFO;
565        }
566    
567    }