KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > core > urls > URLRewriterService


1 /*
2  * Copyright 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  * $Header:$
17  */

18 package org.apache.beehive.netui.core.urls;
19
20 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
21
22 import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
23 import org.apache.beehive.netui.util.logging.Logger;
24
25 import java.io.PrintStream JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import javax.servlet.ServletContext JavaDoc;
31 import javax.servlet.ServletRequest JavaDoc;
32 import javax.servlet.ServletResponse JavaDoc;
33
34
35 /**
36  * Methods for registering URL rewriters, adding URL rewriters
37  * to the chain, and for rewriting URLs using registered rewriters.
38  *
39  * <p> Note that when a URLRewriter is registered with this service
40  * it is added to a chain (a List) of rewriters. When rewriting
41  * occurs, we loop through each rewriter in the list. The only exception
42  * to this is when a rewriter that does not allow other rewriters
43  * to be used is registered. This then becomes the exclusive rewriter
44  * to use and no other rewriters can be registered. </p>
45  *
46  * <p> The final step of the full rewriting process should be to run the
47  * rewritten URI through the templated URL formatting process. See
48  * {@link #getTemplatedURL} </p>
49  *
50  * <p> Also note that this API allows a client to register their own templated
51  * URI formatter so they can manage their own templates and formatting. </p>
52  */

53 public class URLRewriterService
54 {
55     private static final Logger _log = Logger.getInstance( URLRewriterService.class );
56
57     private static final String JavaDoc URL_REWRITERS_KEY = "url_rewriters";
58     private static final String JavaDoc TEMPLATTED_URL_FORMATTER_KEY = "templated_url_formatter";
59     private static final DefaultTemplatedURLFormatter defaultFormatter = new DefaultTemplatedURLFormatter();
60
61     /**
62      * Get the prefix to use when rewriting a query parameter name.
63      * Loops through the list of registered URLRewriters to build up a the prefix.
64      *
65      * @param servletContext the current ServletContext.
66      * @param request the current ServletRequest.
67      * @param name the name of the query parameter.
68      * @return a prefix to use to rewrite a query parameter name.
69      */

70     public static String JavaDoc getNamePrefix( ServletContext JavaDoc servletContext, ServletRequest JavaDoc request, String JavaDoc name )
71     {
72         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
73
74         InternalStringBuilder prefix = new InternalStringBuilder();
75
76         if ( rewriters != null )
77         {
78             for ( Iterator JavaDoc i = rewriters.iterator(); i.hasNext(); )
79             {
80                 URLRewriter rewriter = ( URLRewriter ) i.next();
81                 String JavaDoc nextPrefix = rewriter.getNamePrefix( servletContext, request, name );
82                 if ( nextPrefix != null ) { prefix.append( nextPrefix ); }
83             }
84         }
85
86         return prefix.toString();
87     }
88
89     /**
90      * Rewrite the given URL, looping through the list of registered URLRewriters.
91      *
92      * <p> Once the MutableURI has been rewritten, and if it is an instance of
93      * {@link FreezableMutableURI}, then this method will set the URI to a frozen
94      * state. I.e. immutable. If a user then tries to use a setter method on the
95      * rewritten URI, the FreezableMutableURI will throw an IllegalStateException. </p>
96      *
97      * <p> Note that after the rewritting the caller should run the rewritten URI
98      * through the templated URI formatting process as the last step in rewriting.
99      * See {@link #getTemplatedURL} </p>
100      *
101      * @param servletContext the current ServletContext.
102      * @param request the current ServletRequest.
103      * @param response the current ServletResponse.
104      * @param url the URL to be rewritten.
105      * @param type the type of URL to be rewritten. This is one of the following values:
106      * <ul>
107      * <li><code>action</code>: a standard (non-resource) URL
108      * <li><code>resource</code>: a resource (e.g., image) URL
109      * </ul>
110      * @param needsToBeSecure a flag indicating whether the URL should be secure (SSL required) or not
111      * @see #registerURLRewriter
112      */

113     public static void rewriteURL( ServletContext JavaDoc servletContext, ServletRequest JavaDoc request,
114                                    ServletResponse JavaDoc response, MutableURI url, URLType type,
115                                    boolean needsToBeSecure )
116     {
117         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
118
119         if ( rewriters != null )
120         {
121             for ( Iterator JavaDoc i = rewriters.iterator(); i.hasNext(); )
122             {
123                 URLRewriter rewriter = ( URLRewriter ) i.next();
124                 rewriter.rewriteURL( servletContext, request, response, url, type, needsToBeSecure );
125             }
126         }
127
128         if ( url instanceof FreezableMutableURI )
129         {
130             ( ( FreezableMutableURI ) url ).setFrozen( true );
131         }
132     }
133
134     /**
135      * Get the unmodifiable list of URLRewriter objects in the request that will be used if
136      * {@link #rewriteURL} is called.
137      *
138      * @param request the current ServletRequest.
139      * @return an unmodifiable list of the URLRewriters that have been registered.
140      */

141     public static List JavaDoc/*< URLRewriter >*/ getURLRewriters( ServletRequest JavaDoc request )
142     {
143         return Collections.unmodifiableList( getRewriters( request ) );
144     }
145
146     /**
147      * Register a URLRewriter (add to a list) in the request. It will be added to the end
148      * of a list of URLRewriter objects and will be used if {@link #rewriteURL} is called.
149      *
150      * @param request the current ServletRequest.
151      * @param rewriter the URLRewriter to register.
152      * @return <code>false</code> if a URLRewriter has been registered
153      * that does not allow other rewriters. Otherwise, <code>true</code>
154      * if the URLRewriter was added to the chain or already exists in
155      * the chain.
156      */

157     public static boolean registerURLRewriter( ServletRequest JavaDoc request, URLRewriter rewriter )
158     {
159         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
160
161         if ( rewriters == null )
162         {
163             rewriters = new ArrayList JavaDoc/*< URLRewriter >*/();
164             rewriters.add( rewriter );
165             request.setAttribute( URL_REWRITERS_KEY, rewriters );
166         }
167         else
168         {
169             return addRewriter( rewriters, rewriter, rewriters.size() );
170         }
171
172         return true;
173     }
174
175     /**
176      * Register a URLRewriter (add to a list) in the request. It will be added at the
177      * specified position in this list of URLRewriter objects and will be used if
178      * {@link #rewriteURL} is called.
179      *
180      * @param index the place to insert the URLRewriter
181      * @param request the current ServletRequest.
182      * @param rewriter the URLRewriter to register.
183      * @return <code>false</code> if a URLRewriter has been registered
184      * that does not allow other rewriters. Otherwise, <code>true</code>
185      * if the URLRewriter was added to the chain or already exists in
186      * the chain.
187      */

188     public static boolean registerURLRewriter( int index, ServletRequest JavaDoc request, URLRewriter rewriter )
189     {
190         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
191
192         if ( rewriters == null )
193         {
194             rewriters = new ArrayList JavaDoc/*< URLRewriter >*/();
195             rewriters.add( rewriter );
196             request.setAttribute( URL_REWRITERS_KEY, rewriters );
197         }
198         else
199         {
200             return addRewriter( rewriters, rewriter, index );
201         }
202
203         return true;
204     }
205
206     private static ArrayList JavaDoc/*< URLRewriter >*/ getRewriters( ServletRequest JavaDoc request )
207     {
208         return ( ArrayList JavaDoc/*< URLRewriter >*/ ) ScopedServletUtils.getScopedRequestAttribute( URL_REWRITERS_KEY, request );
209     }
210     
211     private static boolean addRewriter( ArrayList JavaDoc/*< URLRewriter >*/ rewriters, URLRewriter rewriter, int index )
212     {
213         if ( otherRewritersAllowed( rewriters ) )
214         {
215             if ( !rewriters.contains( rewriter ) )
216             {
217                 if ( !rewriter.allowOtherRewriters() )
218                 {
219                     rewriters.clear();
220
221                     if ( rewriters.size() > 0 && _log.isInfoEnabled() )
222                     {
223                         InternalStringBuilder message = new InternalStringBuilder();
224                         message.append( "Register exclusive URLRewriter, \"");
225                         message.append( rewriter.getClass().getName() );
226                         message.append( "\". This removes any other URLRewriter objects already registered in the chain." );
227                         _log.info( message.toString() );
228                     }
229                 }
230                 rewriters.add( index, rewriter );
231             }
232         }
233         else
234         {
235             if ( _log.isInfoEnabled() )
236             {
237                 InternalStringBuilder message = new InternalStringBuilder();
238                 message.append( "Cannot register URLRewriter, \"");
239                 message.append( rewriter.getClass().getName() );
240                 message.append( "\". The URLRewriter, \"" );
241                 message.append( rewriters.get( 0 ).getClass().getName() );
242                 message.append( "\", is already registered and does not allow other rewriters." );
243                 _log.info( message.toString() );
244             }
245
246             return false;
247         }
248
249         return true;
250     }
251
252     private static boolean otherRewritersAllowed( ArrayList JavaDoc/*< URLRewriter >*/ rewriters )
253     {
254         if ( rewriters != null && rewriters.size() == 1 &&
255              ! ( ( URLRewriter ) rewriters.get( 0 ) ).allowOtherRewriters() )
256         {
257             return false;
258         }
259
260         return true;
261     }
262
263     /**
264      * Unregister the URLRewriter (remove from the list) from the request.
265      *
266      * @param request the current ServletRequest.
267      * @param rewriter the URLRewriter to unregister
268      * @see #registerURLRewriter
269      */

270     public static void unregisterURLRewriter( ServletRequest JavaDoc request, URLRewriter rewriter )
271     {
272         if ( rewriter == null ) { return; }
273
274         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
275
276         if ( rewriters == null )
277         {
278             return;
279         }
280         else
281         {
282             rewriters.remove( rewriter );
283
284             if ( rewriters.size() == 0 )
285             {
286                 request.removeAttribute( URL_REWRITERS_KEY );
287             }
288         }
289     }
290
291     /**
292      * Unregister the URLRewriter (remove from the list) from the request.
293      *
294      * @param request the current ServletRequest.
295      */

296     public static void unregisterAllURLRewriters( ServletRequest JavaDoc request )
297     {
298         request.removeAttribute( URL_REWRITERS_KEY );
299     }
300
301     /**
302      * Tell whether rewritten form actions should be allowed to have query parameters. If this returns
303      * <code>false</code>, then a form-tag implementation should render query parameters into hidden
304      * fields on the form instead of allowing them to remain in the URL.
305      */

306     public static boolean allowParamsOnFormAction( ServletContext JavaDoc servletContext, ServletRequest JavaDoc request )
307     {
308         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
309
310         if ( rewriters != null )
311         {
312             for ( Iterator JavaDoc i = rewriters.iterator(); i.hasNext(); )
313             {
314                 URLRewriter rewriter = ( URLRewriter ) i.next();
315                 if ( !rewriter.allowParamsOnFormAction( servletContext, request ) ) { return false; }
316             }
317         }
318
319         return true;
320     }
321
322     /**
323      * Print out information about the chain of URLRewriters in this request.
324      *
325      * @param request the current HttpServletRequest.
326      * @param output a PrintStream to output chain of URLRewriters in this request.
327      * If <code>null</null>, <code>System.err</code> is used.
328      */

329     public static void dumpURLRewriters( ServletRequest JavaDoc request, PrintStream JavaDoc output )
330     {
331         ArrayList JavaDoc/*< URLRewriter >*/ rewriters = getRewriters( request );
332
333         if ( output == null ) output = System.err;
334         output.println( "*** List of URLRewriter objects: " + rewriters );
335
336         if ( rewriters != null )
337         {
338             int count = 0;
339             for ( Iterator JavaDoc i = rewriters.iterator(); i.hasNext(); )
340             {
341                 URLRewriter rewriter = ( URLRewriter ) i.next();
342                 output.println( " " + count++ + ". " + rewriter.getClass().getName() );
343                 output.println( " allows other rewriters: " + rewriter.allowOtherRewriters() );
344                 output.println( " rewriter: " + rewriter );
345             }
346         }
347         else
348         {
349             output.println( " No URLRewriter objects are registered with this request." );
350         }
351     }
352
353     /**
354      * Format the given URI using a URL template, if defined in the URL template
355      * config file, WEB-INF/url-template-config.xml. The {@link URIContext}
356      * encapsulates some additional data needed to write out the string form.
357      * E.g. It defines if the &quot;&amp;amp;&quot; entity or the
358      * '&amp;' character should be used to separate quary parameters.
359      *
360      * @param request the current ServletRequest.
361      * @param uri the MutableURI to be formatted into a String.
362      * @param key the URL template type to use for formatting the URI
363      * @param uriContext data required to write out the string form.
364      * @return the URL as a <code>String</code>
365      */

366     public static String JavaDoc getTemplatedURL( ServletRequest JavaDoc request, MutableURI uri, String JavaDoc key, URIContext uriContext )
367     {
368         TemplatedURLFormatter formatter = getTemplatedURLFormatter( request );
369
370         if ( formatter != null )
371         {
372             return formatter.getTemplatedURL( request, uri, key, uriContext );
373         }
374
375         return defaultFormatter.getTemplatedURL( request, uri, key, uriContext );
376     }
377
378     private static TemplatedURLFormatter getTemplatedURLFormatter( ServletRequest JavaDoc request )
379     {
380         return ( TemplatedURLFormatter ) ScopedServletUtils.getScopedRequestAttribute( TEMPLATTED_URL_FORMATTER_KEY, request );
381     }
382
383     /**
384      * Register a TemplatedURLFormatter in the request.
385      *
386      * <p> The TemplatedURLFormatter should be used as a final step in the rewriting
387      * process to format the rewritten URL as defined by a template in the
388      * WEB-INF/url-template-config.xml. There can only be one TemplatedURLFormatter,
389      * not a chain as with the URLRewriters. </p>
390      *
391      * @param request the current ServletRequest.
392      * @param formatter the TemplatedURLFormatter to register.
393      */

394     public static void registerTemplatedURLFormatter( ServletRequest JavaDoc request, TemplatedURLFormatter formatter )
395     {
396         request.setAttribute( TEMPLATTED_URL_FORMATTER_KEY, formatter );
397     }
398
399     /**
400      * Unregister the TemplatedURLFormatter from the request.
401      *
402      * @param request the current ServletRequest.
403      */

404     public static void unregisterTemplatedURLFormatter( ServletRequest JavaDoc request )
405     {
406         request.removeAttribute( TEMPLATTED_URL_FORMATTER_KEY );
407     }
408 }
409
Popular Tags