KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > web > VirtualServerPipeline


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.web;
25
26 import java.io.IOException JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.MalformedURLException JavaDoc;
32 import java.util.concurrent.ConcurrentLinkedQueue JavaDoc;
33
34 import javax.servlet.ServletException JavaDoc;
35 import javax.servlet.http.HttpServletRequest JavaDoc;
36 import javax.servlet.http.HttpServletResponse JavaDoc;
37
38 import org.apache.catalina.Request;
39 import org.apache.catalina.Response;
40 import org.apache.catalina.core.StandardPipeline;
41 import org.apache.catalina.util.StringManager;
42 import org.apache.tomcat.util.buf.UEncoder;
43 import org.apache.tomcat.util.buf.CharChunk;
44
45 import com.sun.logging.LogDomains;
46
47 /**
48  * Pipeline associated with a virtual server.
49  *
50  * This pipeline inherits the state (off/disabled) of its associated
51  * virtual server, and will abort execution and return an appropriate response
52  * error code if its associated virtual server is off or disabled.
53  */

54 public class VirtualServerPipeline extends StandardPipeline {
55
56     private static final StringManager sm =
57         StringManager.getManager("com.sun.enterprise.web");
58
59     private static final Logger JavaDoc logger =
60         LogDomains.getLogger(LogDomains.WEB_LOGGER);
61
62     private VirtualServer vs;
63
64     private boolean isOff;
65     private boolean isDisabled;
66
67     private ArrayList JavaDoc<RedirectParameters> redirects;
68
69     private ConcurrentLinkedQueue JavaDoc<CharChunk> locations;
70     private ConcurrentLinkedQueue JavaDoc<UEncoder> urlEncoders;
71
72     /**
73      * Constructor.
74      *
75      * @param vs Virtual server with which this VirtualServerPipeline is being
76      * associated
77      */

78     public VirtualServerPipeline(VirtualServer vs) {
79         super(vs);
80         this.vs = vs;
81         locations = new ConcurrentLinkedQueue JavaDoc<CharChunk>();
82         urlEncoders = new ConcurrentLinkedQueue JavaDoc<UEncoder>();
83     }
84
85     /**
86      * Processes the specified request, and produces the appropriate
87      * response, by invoking the first valve (if any) of this pipeline, or
88      * the pipeline's basic valve.
89      *
90      * @param request The request to process
91      * @param response The response to return
92      */

93     public void invoke(Request JavaDoc request, Response JavaDoc response)
94             throws IOException JavaDoc, ServletException JavaDoc {
95
96         if (isOff) {
97             String JavaDoc msg = sm.getString("virtualServerValve.vsOff",
98                                       vs.getName());
99             if (logger.isLoggable(Level.FINE)) {
100                 logger.fine(msg);
101             }
102             ((HttpServletResponse JavaDoc) response.getResponse()).sendError(
103                                             HttpServletResponse.SC_NOT_FOUND,
104                                             msg);
105         } else if (isDisabled) {
106             String JavaDoc msg = sm.getString("virtualServerValve.vsDisabled",
107                                       vs.getName());
108             if (logger.isLoggable(Level.FINE)) {
109                 logger.fine(msg);
110             }
111             ((HttpServletResponse JavaDoc) response.getResponse()).sendError(
112                                             HttpServletResponse.SC_FORBIDDEN,
113                                             msg);
114         } else {
115             boolean redirect = false;
116             if (redirects != null) {
117                 redirect = redirectIfNecessary(request, response);
118             }
119             if (!redirect) {
120                 doInvoke(request, response);
121             }
122         }
123     }
124
125
126     /**
127      * Sets the <code>disabled</code> state of this VirtualServerPipeline.
128      *
129      * @param isDisabled true if the associated virtual server has been
130      * disabled, false otherwise
131      */

132     void setIsDisabled(boolean isDisabled) {
133         this.isDisabled = isDisabled;
134     }
135
136
137     /**
138      * Sets the <code>off</code> state of this VirtualServerPipeline.
139      *
140      * @param isOff true if the associated virtual server is <code>off</code>,
141      * false otherwise
142      */

143     void setIsOff(boolean isOff) {
144         this.isOff = isOff;
145     }
146
147
148     /**
149      * Adds the given redirect instruction to this VirtualServerPipeline.
150      *
151      * @param from URI prefix to match
152      * @param url Redirect URL to return to the client
153      * @param urlPrefix New URL prefix to return to the client
154      * @param escape true if redirect URL returned to the client is to be
155      * escaped, false otherwise
156      */

157     void addRedirect(String JavaDoc from, String JavaDoc url, String JavaDoc urlPrefix,
158                      boolean escape) {
159
160         if (redirects == null) {
161             redirects = new ArrayList JavaDoc<RedirectParameters>();
162         }
163
164         redirects.add(new RedirectParameters(from, url, urlPrefix, escape));
165     }
166
167
168     /**
169      * Checks to see if the given request needs to be redirected.
170      *
171      * @param request The request to process
172      * @param response The response to return
173      *
174      * @return true if redirect has occurred, false otherwise
175      */

176     private boolean redirectIfNecessary(Request JavaDoc request, Response JavaDoc response)
177             throws IOException JavaDoc {
178
179         if (redirects == null) {
180             return false;
181         }
182    
183         HttpServletRequest JavaDoc hreq = (HttpServletRequest JavaDoc) request.getRequest();
184         HttpServletResponse JavaDoc hres = (HttpServletResponse JavaDoc) request.getResponse();
185         String JavaDoc requestURI = hreq.getRequestURI();
186         RedirectParameters redirectMatch = null;
187
188         // Determine the longest 'from' URI prefix match
189
int size = redirects.size();
190         for (int i=0; i<size; i++) {
191             RedirectParameters elem = redirects.get(i);
192             if (requestURI.startsWith(elem.from)) {
193                 if (redirectMatch != null) {
194                     if (elem.from.length() > redirectMatch.from.length()) {
195                         redirectMatch = elem;
196                     }
197                 } else {
198                     redirectMatch = elem;
199                 }
200             }
201         }
202
203         if (redirectMatch != null) {
204             // Redirect prefix match found, need to redirect
205
String JavaDoc location = null;
206             String JavaDoc uriSuffix = requestURI.substring(
207                             redirectMatch.from.length());
208             if ("/".equals(redirectMatch.from)) {
209                 uriSuffix = "/" + uriSuffix;
210             }
211             if (redirectMatch.urlPrefix != null) {
212                 // Replace 'from' URI prefix with URL prefix
213
location = redirectMatch.urlPrefix + uriSuffix;
214             } else {
215                 // Replace 'from' URI prefix with complete URL
216
location = redirectMatch.url;
217             }
218   
219             String JavaDoc queryString = hreq.getQueryString();
220             if (queryString != null) {
221                 location += queryString;
222             }
223      
224             CharChunk locationCC = null;
225             UEncoder urlEncoder = null;
226
227             if (redirectMatch.isEscape) {
228                 try {
229                     URL JavaDoc url = new URL JavaDoc(location);
230                     locationCC = locations.poll();
231                     if (locationCC == null) {
232                         locationCC = new CharChunk();
233                     }
234                     locationCC.append(url.getProtocol());
235                     locationCC.append("://");
236                     locationCC.append(url.getHost());
237                     if (url.getPort() != -1) {
238                         locationCC.append(":");
239                         locationCC.append(String.valueOf(url.getPort()));
240                     }
241                     urlEncoder = urlEncoders.poll();
242                     if (urlEncoder == null){
243                         urlEncoder = new UEncoder();
244                         urlEncoder.addSafeCharacter('/');
245                     }
246                     locationCC.append(urlEncoder.encodeURL(url.getPath()));
247                     location = locationCC.toString();
248                 } catch (MalformedURLException JavaDoc mue) {
249                     logger.log(Level.WARNING,
250                                "virtualServerPipeline.invalidRedirectLocation",
251                                location);
252                 } finally {
253                     if (urlEncoder != null) {
254                         urlEncoders.offer(urlEncoder);
255                     }
256                     if (locationCC != null) {
257                         locationCC.recycle();
258                         locations.offer(locationCC);
259                     }
260                 }
261             }
262
263             hres.sendRedirect(location);
264             return true;
265         }
266
267         return false;
268     }
269
270
271     /**
272      * Class representing redirect parameters
273      */

274     static class RedirectParameters {
275
276         private String JavaDoc from;
277         private String JavaDoc url;
278         private String JavaDoc urlPrefix;
279         private boolean isEscape;
280
281         RedirectParameters(String JavaDoc from, String JavaDoc url, String JavaDoc urlPrefix,
282                            boolean isEscape) {
283             this.from = from;
284             this.url = url;
285             this.urlPrefix = urlPrefix;
286             this.isEscape = isEscape;
287         }
288     }
289
290 }
291
Popular Tags