KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > portal > reading > ProxyReader


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.portal.reading;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.net.HttpURLConnection JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.avalon.framework.parameters.Parameters;
26 import org.apache.cocoon.ProcessingException;
27 import org.apache.cocoon.environment.ObjectModelHelper;
28 import org.apache.cocoon.environment.Request;
29 import org.apache.cocoon.environment.Response;
30 import org.apache.cocoon.environment.SourceResolver;
31 import org.apache.cocoon.portal.coplet.CopletInstanceData;
32 import org.apache.cocoon.portal.transformation.ProxyTransformer;
33 import org.apache.cocoon.reading.ServiceableReader;
34 import org.apache.cocoon.util.NetUtils;
35 import org.xml.sax.SAXException JavaDoc;
36
37 /**
38  * This reader is used to retrieve non XML content from external applications
39  * routet via the portal site. Requests from external resources are marked with
40  * a proxy prefix and have coplet id and portal name attached as request
41  * parameters. The portal name and coplet id are used to look up necessary
42  * connection data for the external request (like session id, cookies,
43  * document base, etc.) from the application coplet instance data.
44  *
45  * @author <a HREF="mailto:gernot.koller@rizit.at">Gernot Koller</a>
46  * @author <a HREF="mailto:friedrich.klenner@rzb.at">Friedrich Klenner</a>
47  *
48  * @version CVS $Id: ProxyReader.java 329454 2005-10-29 17:44:45Z cziegeler $
49  */

50 public class ProxyReader extends ServiceableReader {
51
52     /**
53      * The coplet instance data
54      */

55     protected CopletInstanceData copletInstanceData;
56
57     /**
58      * The HTTP response
59      */

60     protected Response response;
61
62     /**
63      * The origninal HTTP request
64      */

65     protected Request request;
66
67     /** The prefix */
68     protected String JavaDoc prefix;
69     
70     /**
71      * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(SourceResolver, Map, String, Parameters)
72      */

73     public void setup(SourceResolver resolver,
74                       Map JavaDoc objectModel,
75                       String JavaDoc src,
76                       Parameters par)
77     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
78         super.setup(resolver, objectModel, src, par);
79
80         request = ObjectModelHelper.getRequest(objectModel);
81         response = ObjectModelHelper.getResponse(objectModel);
82
83         String JavaDoc copletID = request.getParameter(ProxyTransformer.COPLETID);
84         String JavaDoc portalName = request.getParameter(ProxyTransformer.PORTALNAME);
85
86         copletInstanceData =
87             ProxyTransformer.getInstanceData(
88                 this.manager,
89                 copletID,
90                 portalName);
91         this.prefix = par.getParameter("prefix", ProxyTransformer.PROXY_PREFIX);
92     }
93
94     /**
95      * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
96      */

97     public void recycle() {
98         this.response = null;
99         this.request = null;
100         this.copletInstanceData = null;
101         super.recycle();
102     }
103
104     /**
105      * Send the request to the external WebServer
106      * @throws IOException on any exception that occures
107      * @see org.apache.cocoon.reading.Reader#generate()
108      */

109     public void generate() throws IOException JavaDoc {
110         String JavaDoc link = request.getRequestURI();
111         link = link.substring(link.indexOf(this.prefix) + this.prefix.length());
112
113         String JavaDoc documentBase =
114             (String JavaDoc) copletInstanceData.getAttribute(
115                 ProxyTransformer.DOCUMENT_BASE);
116         String JavaDoc remoteURI = null;
117
118         remoteURI = ProxyTransformer.resolveURI(link, documentBase);
119
120         HttpURLConnection JavaDoc connection = connect(request, remoteURI);
121         copyHeaderFields(connection, response);
122         sendData(connection.getInputStream());
123     }
124
125     /**
126      * Copy the data to the original response stream
127      * @param in the response from external request to read from
128      * @throws IOException on any exception
129      */

130     protected void sendData(InputStream JavaDoc in) throws IOException JavaDoc {
131         int length = -1;
132         byte[] buf = new byte[4096];
133
134         while ((length = in.read(buf)) > -1) {
135             out.write(buf, 0, length);
136         }
137         out.flush();
138         in.close();
139     }
140
141     /**
142      * Establish the HttpURLConnection to the given uri.
143      * @param request the original request
144      * @param uri the remote uri
145      * @return the established HttpURLConnection
146      * @throws IOException on any exception
147      */

148     protected HttpURLConnection JavaDoc connect(Request request, String JavaDoc uri)
149         throws IOException JavaDoc {
150         String JavaDoc cookie =
151             (String JavaDoc) copletInstanceData.getAttribute(ProxyTransformer.COOKIE);
152
153         Enumeration JavaDoc enumeration = request.getParameterNames();
154
155         boolean firstattribute = true;
156         StringBuffer JavaDoc query = new StringBuffer JavaDoc();
157
158         while (enumeration.hasMoreElements()) {
159             String JavaDoc paramName = (String JavaDoc) enumeration.nextElement();
160
161             if (!paramName.startsWith("cocoon-portal-")) {
162
163                 String JavaDoc[] paramValues = request.getParameterValues(paramName);
164
165                 for (int i = 0; i < paramValues.length; i++) {
166                     if (firstattribute) {
167                         query.append('?');
168                         firstattribute = false;
169                     }
170                     else {
171                         query.append('&');
172                     }
173
174                     query.append(NetUtils.encode(paramName, "utf-8"));
175                     query.append('=');
176                     query.append(NetUtils.encode(paramValues[i], "utf-8"));
177
178                 }
179             }
180         }
181
182         uri = uri + query.toString();
183
184         URL JavaDoc url = new URL JavaDoc(uri);
185         HttpURLConnection JavaDoc connection = (HttpURLConnection JavaDoc) url.openConnection();
186         connection.setInstanceFollowRedirects(true);
187
188         if (cookie != null) {
189             connection.setRequestProperty(ProxyTransformer.COOKIE, cookie);
190         }
191
192         connection.connect();
193
194         copletInstanceData.setAttribute(
195             ProxyTransformer.COOKIE,
196             connection.getHeaderField(ProxyTransformer.COOKIE));
197
198         return connection;
199     }
200
201     /**
202      * Copy header fields from external response to original response.
203      * @param connection the connection to the external resource
204      * @param response the original HTTP response.
205      */

206     private void copyHeaderFields(
207         HttpURLConnection JavaDoc connection,
208         Response response) {
209         String JavaDoc[] fieldNames =
210             new String JavaDoc[] {
211                 "Content-Range",
212                 "Accept-Ranges",
213                 "Content-Length",
214                 "Last-Modified",
215                 "Content-Type",
216                 "Expires" };
217         for (int i = 0; i < fieldNames.length; i++) {
218             String JavaDoc value = connection.getHeaderField(fieldNames[i]);
219             if (value != null) {
220                 response.setHeader(fieldNames[i], value);
221             }
222
223         }
224     }
225 }
226
Popular Tags