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.cxf;
018    
019    import java.util.ArrayList;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import javax.wsdl.Definition;
025    import javax.wsdl.Port;
026    import javax.wsdl.Service;
027    import javax.wsdl.extensions.ExtensibilityElement;
028    import javax.wsdl.extensions.schema.SchemaReference;
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.cxf.Bus;
034    import org.apache.cxf.service.model.EndpointInfo;
035    import org.apache.cxf.tools.common.extensions.soap.SoapAddress;
036    import org.apache.cxf.tools.util.SOAPBindingUtil;
037    import org.apache.cxf.transport.http.WSDLQueryHandler;
038    import org.xmlsoap.schemas.wsdl.http.AddressType;
039    
040    public class GeronimoQueryHandler extends WSDLQueryHandler {
041    
042        private static final Log LOG = LogFactory.getLog(GeronimoQueryHandler.class);
043    
044        public GeronimoQueryHandler(Bus bus) {
045            super(bus);
046        }
047    
048        protected void updateDefinition(Definition def,
049                                        Map<String, Definition> done,
050                                        Map<String, SchemaReference> doneSchemas,
051                                        String base,
052                                        EndpointInfo ei) {
053            if (done.get("") == def) {
054                QName serviceName = ei.getService().getName();
055                String portName = ei.getName().getLocalPart();
056                updateServices(serviceName, portName, def, base);
057            }
058            super.updateDefinition(def, done, doneSchemas, base, ei);
059        }
060    
061        private void updateServices(QName serviceName, 
062                                    String portName, 
063                                    Definition def, 
064                                    String baseUri) {
065            boolean updated = false;
066            Map services = def.getServices();
067            if (services != null) {
068                ArrayList<QName> servicesToRemove = new ArrayList<QName>();
069                
070                Iterator serviceIterator = services.entrySet().iterator();
071                while (serviceIterator.hasNext()) {
072                    Map.Entry serviceEntry = (Map.Entry) serviceIterator.next();
073                    QName currServiceName = (QName) serviceEntry.getKey();
074                    if (currServiceName.equals(serviceName)) {
075                        Service service = (Service) serviceEntry.getValue();
076                        updatePorts(portName, service, baseUri);
077                        updated = true;
078                    } else {
079                        servicesToRemove.add(currServiceName);
080                    }
081                }
082                
083                for (QName serviceToRemove : servicesToRemove) {
084                    def.removeService(serviceToRemove);                
085                }
086            }
087            if (!updated) {
088                LOG.warn("WSDL '" + serviceName.getLocalPart() + "' service not found.");
089            }
090        }
091    
092        private void updatePorts(String portName, 
093                                 Service service, 
094                                 String baseUri) {
095            boolean updated = false;
096            Map ports = service.getPorts();
097            if (ports != null) {
098                ArrayList<String> portsToRemove = new ArrayList<String>();
099                
100                Iterator portIterator = ports.entrySet().iterator();
101                while (portIterator.hasNext()) {
102                    Map.Entry portEntry = (Map.Entry) portIterator.next();
103                    String currPortName = (String) portEntry.getKey();
104                    if (currPortName.equals(portName)) {
105                        Port port = (Port) portEntry.getValue();
106                        updatePortLocation(port, baseUri);
107                        updated = true;
108                    } else {
109                        portsToRemove.add(currPortName);
110                    }
111                }
112                
113                for (String portToRemove : portsToRemove) {
114                    service.removePort(portToRemove);               
115                }
116            }
117            if (!updated) {
118                LOG.warn("WSDL '" + portName + "' port not found.");
119            }
120        }
121    
122        private void updatePortLocation(Port port, 
123                                        String baseUri) {
124            List<?> exts = port.getExtensibilityElements();
125            if (exts != null && exts.size() > 0) {
126                ExtensibilityElement el = (ExtensibilityElement) exts.get(0);
127                if (SOAPBindingUtil.isSOAPAddress(el)) {
128                    SoapAddress add = SOAPBindingUtil.getSoapAddress(el);
129                    add.setLocationURI(baseUri);
130                }
131                if (el instanceof AddressType) {
132                    AddressType add = (AddressType) el;
133                    add.setLocation(baseUri);
134                }
135            }
136        }
137    
138    }