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.servicemix.common.wsdl1;
018    
019    import org.apache.servicemix.common.AbstractDeployer;
020    import org.apache.servicemix.common.Endpoint;
021    import org.apache.servicemix.common.ServiceMixComponent;
022    import org.apache.servicemix.common.ServiceUnit;
023    import org.w3c.dom.Document;
024    
025    import com.ibm.wsdl.Constants;
026    
027    import javax.jbi.management.DeploymentException;
028    import javax.wsdl.Binding;
029    import javax.wsdl.Definition;
030    import javax.wsdl.Port;
031    import javax.wsdl.Service;
032    import javax.wsdl.WSDLException;
033    import javax.wsdl.extensions.ExtensibilityElement;
034    import javax.wsdl.extensions.ExtensionRegistry;
035    import javax.wsdl.factory.WSDLFactory;
036    import javax.wsdl.xml.WSDLReader;
037    import javax.xml.parsers.DocumentBuilderFactory;
038    
039    import java.io.File;
040    import java.io.FilenameFilter;
041    import java.util.Iterator;
042    import java.util.Map;
043    
044    public abstract class AbstractWsdl1Deployer extends AbstractDeployer {
045    
046        protected FilenameFilter filter;
047        
048        public AbstractWsdl1Deployer(ServiceMixComponent component) {
049            super(component);
050            filter = new WsdlFilter();
051        }
052    
053        /* (non-Javadoc)
054         * @see org.apache.servicemix.common.Deployer#canDeploy(java.lang.String, java.lang.String)
055         */
056        public boolean canDeploy(String serviceUnitName, 
057                                 String serviceUnitRootPath) {
058            File[] wsdls = new File(serviceUnitRootPath).listFiles(filter);
059            return wsdls != null && wsdls.length > 0;
060        }
061        
062        /* (non-Javadoc)
063         * @see org.apache.servicemix.common.Deployer#deploy(java.lang.String, java.lang.String)
064         */
065        public ServiceUnit deploy(String serviceUnitName, 
066                                  String serviceUnitRootPath) throws DeploymentException {
067            File[] wsdls = new File(serviceUnitRootPath).listFiles(filter);
068            if (wsdls == null || wsdls.length == 0) {
069                throw failure("deploy", "No wsdl found", null);
070            }
071            ServiceUnit su = createServiceUnit();
072            su.setComponent(component);
073            su.setName(serviceUnitName);
074            su.setRootPath(serviceUnitRootPath);
075            for (int i = 0; i < wsdls.length; i++) {
076                initFromWsdl(su, wsdls[i]);
077            }
078            if (su.getEndpoints().size() == 0) {
079                throw failure("deploy", "Invalid wsdl: no endpoints found", null);
080            }
081            return su;
082        }
083        
084        protected void initFromWsdl(ServiceUnit su, File wsdl) throws DeploymentException {
085            Document description;
086            Definition definition;
087            try {
088                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
089                factory.setNamespaceAware(true);
090                description = factory.newDocumentBuilder().parse(wsdl);
091                definition = createWsdlReader().readWSDL(null, description);
092            } catch (Exception e) {
093                throw failure("deploy", "Could not parse " + wsdl, e);
094            }
095            Map services = definition.getServices();
096            if (services.size() == 0) {
097                failure("deploy", "Invalid wsdl " + wsdl + ": no defined services", null);
098            }
099            for (Iterator itSvc = services.values().iterator(); itSvc.hasNext();) {
100                Service svc = (Service) itSvc.next();
101                for (Iterator itPorts = svc.getPorts().values().iterator(); itPorts.hasNext();) {
102                    JbiEndpoint jbiEndpoint = null;
103                    Port port = (Port) itPorts.next();
104                    ExtensibilityElement portElement = null;
105                    for (Iterator itElems = port.getExtensibilityElements().iterator(); itElems.hasNext();) {
106                        ExtensibilityElement elem = (ExtensibilityElement) itElems.next();
107                        if (elem instanceof JbiEndpoint) {
108                            jbiEndpoint = (JbiEndpoint) elem;
109                        } else if (filterPortElement(elem)) {
110                            if (portElement == null) {
111                                portElement = elem;
112                            } else {
113                                throw failure("deploy", "Invalid wsdl " + wsdl + ": more than one port element match", null);
114                            }
115                        }
116                    }
117                    if (portElement != null) {
118                        Binding binding = port.getBinding();
119                        ExtensibilityElement bindingElement = null;
120                        for (Iterator itElems = binding.getExtensibilityElements().iterator(); itElems.hasNext();) {
121                            ExtensibilityElement elem = (ExtensibilityElement) itElems.next();
122                            if (filterBindingElement(elem)) {
123                                if (bindingElement == null) {
124                                    bindingElement = elem;
125                                } else {
126                                    throw failure("deploy", "Invalid wsdl " + wsdl + ": more than one binding element match", null);
127                                }
128                            }
129                        }
130                        if (bindingElement == null) {
131                            throw failure("deploy", "Invalid wsdl " + wsdl + ": no matching binding element found", null);
132                        }
133                        Endpoint ep = createEndpoint(portElement, bindingElement, jbiEndpoint);
134                        if (ep != null) {
135                            ep.setServiceUnit(su);
136                            ep.setDescription(description);
137                            ep.setDefinition(definition);
138                            ep.setService(svc.getQName());
139                            ep.setEndpoint(port.getName());
140                            ep.setInterfaceName(binding.getPortType().getQName());
141                            validate(ep);
142                            su.addEndpoint(ep);
143                        }
144                    }
145                }
146            }
147        }    
148        
149        protected WSDLReader createWsdlReader() throws WSDLException {
150            WSDLFactory factory = WSDLFactory.newInstance();
151            ExtensionRegistry registry = factory.newPopulatedExtensionRegistry();
152            registerExtensions(registry);
153            WSDLReader reader = factory.newWSDLReader();
154            reader.setFeature(Constants.FEATURE_VERBOSE, false);
155            reader.setExtensionRegistry(registry);
156            return reader;
157        }
158        
159        protected void registerExtensions(ExtensionRegistry registry) {
160            JbiExtension.register(registry);
161        }
162    
163        protected ServiceUnit createServiceUnit() {
164            return new ServiceUnit();
165        }
166        
167        protected abstract Endpoint createEndpoint(ExtensibilityElement portElement,
168                                                   ExtensibilityElement bindingElement,
169                                                   JbiEndpoint jbiEndpoint);
170        
171        protected abstract boolean filterPortElement(ExtensibilityElement element);
172        
173        protected abstract boolean filterBindingElement(ExtensibilityElement element);
174        
175        public static class WsdlFilter implements FilenameFilter {
176    
177            public boolean accept(File dir, String name) {
178                return name.endsWith(".wsdl");
179            }
180            
181        }
182        
183    }