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.transport.http;
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    import org.codehaus.activesoap.transport.Invocation;
023    import org.codehaus.activesoap.transport.TransportClientSupport;
024    
025    import java.io.BufferedReader;
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.io.InputStreamReader;
029    import java.io.OutputStreamWriter;
030    import java.io.Reader;
031    import java.io.StringReader;
032    import java.io.Writer;
033    import java.net.HttpURLConnection;
034    import java.net.MalformedURLException;
035    import java.net.URL;
036    
037    /**
038     * @version $Revision: 1.3 $
039     */
040    public class HttpTransportClient extends TransportClientSupport {
041        private static final Log log = LogFactory.getLog(HttpTransportClient.class);
042    
043        private URL url;
044    
045        public HttpTransportClient(URL url) {
046            this.url = url;
047        }
048    
049        public HttpTransportClient(String url) throws MalformedURLException {
050            this(new URL(url));
051        }
052    
053        public void invokeOneWay(Invocation invocation, Reader request) throws Exception {
054            invoke(invocation, request);
055        }
056    
057    
058        public Reader invokeRequest(Invocation invocation, Reader request) throws Exception {
059            String text = invoke(invocation, request);
060            if (log.isTraceEnabled()) {
061                log.trace("Received: " + text);
062            }
063            return new StringReader(text);
064        }
065    
066        public void close() throws Exception {
067        }
068    
069        // Properties
070        //-------------------------------------------------------------------------
071        public URL getUrl() {
072            return url;
073        }
074    
075        public void setUrl(URL url) {
076            this.url = url;
077        }
078    
079        // Implementation methods
080        //-------------------------------------------------------------------------
081        protected String invoke(Invocation invocation, Reader request) throws Exception {
082            HttpURLConnection connection = createConnection();
083            BufferedReader in = null;
084            Writer writer = null;
085            try {
086                writer = new OutputStreamWriter(connection.getOutputStream());
087                in = invocation.asBufferedReader(request);
088                while (true) {
089                    String line = in.readLine();
090                    if (line == null) {
091                        break;
092                    }
093                    writer.write(line);
094                    writer.write("\n");
095                }
096                in.close();
097                in = null;
098    
099                writer.flush();
100                int answer = connection.getResponseCode();
101                if (answer != HttpURLConnection.HTTP_OK) {
102                    throw new Exception("Failed to perform HTTP POST. Response: " + answer);
103                }
104    
105                return getText(connection.getInputStream());
106            }
107            finally {
108                if (in != null) {
109                    try {
110                        in.close();
111                    }
112                    catch (IOException e) {
113                        // ignore
114                    }
115                }
116                if (writer != null) {
117                    try {
118                        writer.close();
119                    }
120                    catch (IOException e) {
121                        // ignore
122                    }
123                }
124                connection.disconnect();
125            }
126        }
127    
128        protected String getText(InputStream inputStream) throws IOException {
129            StringBuffer buffer = new StringBuffer();
130            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
131            while (true) {
132                String line = in.readLine();
133                if (line == null) {
134                    break;
135                }
136                else {
137                    buffer.append(line);
138                    buffer.append("\n");
139                }
140            }
141            return buffer.toString();
142        }
143    
144        protected HttpURLConnection createConnection() throws IOException {
145            URL url = getUrl();
146            if (url == null) {
147                throw new IllegalArgumentException("No 'url' property configured. Cannot perform invocation");
148            }
149            HttpURLConnection answer = (HttpURLConnection) url.openConnection();
150            answer.setDoInput(true);
151            answer.setDoOutput(true);
152            answer.setRequestMethod("POST");
153            configureConnection(answer);
154            answer.connect();
155            return answer;
156        }
157    
158        /**
159         * A pluggable Strategy pattern allowing a connection to be configured
160         */
161        protected void configureConnection(HttpURLConnection connection) {
162        }
163    
164    }