001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * 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.codehaus.activesoap;
019    
020    import org.codehaus.activesoap.soap.SoapVersion;
021    import org.codehaus.activesoap.transport.LocalTransportClient;
022    import org.codehaus.activesoap.transport.TransportClient;
023    import org.codehaus.activesoap.util.DocumentFilterXMLStreamWriter;
024    import org.codehaus.activesoap.util.DelegateXMLStreamWriter;
025    import org.codehaus.activesoap.util.LoggingXMLStreamWriter;
026    import org.codehaus.activesoap.util.NullXMLStreamWriter;
027    import org.codehaus.activesoap.handler.DefaultHandlerRegistry;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.xmlbeans.XmlObject;
031    
032    import javax.xml.stream.XMLStreamReader;
033    import javax.xml.stream.XMLStreamWriter;
034    import javax.xml.stream.XMLStreamException;
035    import java.util.ArrayList;
036    import java.util.Iterator;
037    import java.util.List;
038    import java.io.StringWriter;
039    
040    
041    /**
042     * Represents a SOAP client for invoking web services operations
043     *
044     * @version $Revision: 1.9 $
045     */
046    public class SoapClient extends RestClient {
047        private static final transient Log log = LogFactory.getLog(SoapClient.class);
048    
049        private SoapVersion soap;
050        private List headerHandlers = new ArrayList();
051    
052        /**
053         * Factory method to create a new client to an in memory SoapService
054         */
055        public static SoapClient newLocalClient(SoapService soapService) {
056            return new SoapClient(new LocalTransportClient(soapService), soapService);
057        }
058    
059        public SoapClient(TransportClient transport, SoapService service) {
060            super(transport, service);
061            this.soap = service.getSoapVersion();
062        }
063    
064        public void addHeaderHandler(Handler handler) {
065            headerHandlers.add(handler);
066        }
067    
068        public void removeHeaderHandler(Handler handler) {
069            headerHandlers.remove(handler);
070        }
071    
072        public Object parseResponse(XMLStreamReader in) throws Exception {
073            ResponseHandler responseHandler = new ResponseHandler();
074    
075            // lets create a temporary client side soap service to make a dummy invoke
076            DefaultHandlerRegistry registry = new DefaultHandlerRegistry(responseHandler);
077            SoapService service = new SoapService(registry);
078            service.invoke(in, NullXMLStreamWriter.getInstance());
079    
080            return responseHandler.body;
081        }
082    
083        // Implementation methods
084        //-------------------------------------------------------------------------
085        protected class ResponseHandler implements Handler {
086            public Object body;
087    
088            public void invoke(MessageExchange exchange) throws Exception {
089                XMLStreamReader in = exchange.getIn();
090                XMLStreamWriter out = exchange.getOut();
091                body = SoapClient.super.parseResponse(in);
092            }
093        }
094    
095        protected SoapService getSoapService() {
096            return (SoapService) getService();
097        }
098    
099        protected void processBody(MessageExchange exchange, XMLStreamWriter out, Handler generateBodyHandler) throws Exception {
100            out.setPrefix(soap.getPrefix(), soap.getNamespace());
101            soap.writeStartElement(out, "Envelope");
102            out.writeNamespace(soap.getPrefix(), soap.getNamespace());
103            processHeaders(exchange, out);
104            soap.writeStartElement(out, "Body");
105            XMLStreamWriter filter = new DocumentFilterXMLStreamWriter(out);
106            if (log.isDebugEnabled()) {
107                filter = new LoggingXMLStreamWriter(filter, log);
108            }
109            super.processBody(exchange, filter, generateBodyHandler);
110            out.writeEndElement();
111            out.writeEndElement();
112        }
113    
114        protected void processHeaders(MessageExchange exchange, XMLStreamWriter out) throws Exception {
115            if (!headerHandlers.isEmpty()) {
116                soap.writeStartElement(out, "Header");
117                for (Iterator iter = headerHandlers.iterator(); iter.hasNext();) {
118                    Handler handler = (Handler) iter.next();
119                    handler.invoke(exchange.newInstance(null, new DocumentFilterXMLStreamWriter(out)));
120                }
121                out.writeEndElement();
122            }
123        }
124    }