Source Code Cross Referenced for WebRequestCodingStrategy.java in  » J2EE » wicket » wicket » protocol » http » request » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » wicket » wicket.protocol.http.request 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: WebRequestCodingStrategy.java,v 1.24 2006/02/15 02:00:30 jonathanlocke
003:         * Exp $ $Revision: 509689 $ $Date: 2007-02-20 18:57:33 +0100 (Tue, 20 Feb 2007) $
004:         * 
005:         * ==============================================================================
006:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007:         * use this file except in compliance with the License. You may obtain a copy of
008:         * the License at
009:         * 
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015:         * License for the specific language governing permissions and limitations under
016:         * the License.
017:         */
018:        package wicket.protocol.http.request;
019:
020:        import java.io.UnsupportedEncodingException;
021:        import java.net.URLEncoder;
022:        import java.util.Comparator;
023:        import java.util.Iterator;
024:        import java.util.Map;
025:        import java.util.SortedMap;
026:        import java.util.TreeMap;
027:        import java.util.Map.Entry;
028:
029:        import org.apache.commons.logging.Log;
030:        import org.apache.commons.logging.LogFactory;
031:
032:        import wicket.Application;
033:        import wicket.Component;
034:        import wicket.IRedirectListener;
035:        import wicket.IRequestTarget;
036:        import wicket.Page;
037:        import wicket.PageMap;
038:        import wicket.PageParameters;
039:        import wicket.Request;
040:        import wicket.RequestCycle;
041:        import wicket.RequestListenerInterface;
042:        import wicket.Session;
043:        import wicket.WicketRuntimeException;
044:        import wicket.protocol.http.WebRequest;
045:        import wicket.protocol.http.WebRequestCycle;
046:        import wicket.request.IRequestCodingStrategy;
047:        import wicket.request.IRequestTargetMountsInfo;
048:        import wicket.request.RequestParameters;
049:        import wicket.request.target.coding.IRequestTargetUrlCodingStrategy;
050:        import wicket.request.target.component.IBookmarkablePageRequestTarget;
051:        import wicket.request.target.component.IPageRequestTarget;
052:        import wicket.request.target.component.listener.IListenerInterfaceRequestTarget;
053:        import wicket.request.target.resource.ISharedResourceRequestTarget;
054:        import wicket.util.string.AppendingStringBuffer;
055:        import wicket.util.string.Strings;
056:
057:        /**
058:         * Request parameters factory implementation that uses http request parameters
059:         * and path info to construct the request parameters object.
060:         * 
061:         * @author Eelco Hillenius
062:         * @author Jonathan Locke
063:         */
064:        public class WebRequestCodingStrategy implements 
065:                IRequestCodingStrategy, IRequestTargetMountsInfo {
066:            /** Name of interface target query parameter */
067:            public static final String NAME_SPACE = "wicket:";
068:
069:            /** Name of interface target query parameter */
070:            public static final String INTERFACE_PARAMETER_NAME = NAME_SPACE
071:                    + "interface";
072:
073:            /** AJAX query parameter name */
074:            public static final String BEHAVIOR_ID_PARAMETER_NAME = NAME_SPACE
075:                    + "behaviorId";
076:
077:            /** Parameter name used all over the place */
078:            public static final String BOOKMARKABLE_PAGE_PARAMETER_NAME = NAME_SPACE
079:                    + "bookmarkablePage";
080:
081:            /** Pagemap parameter constant */
082:            public static final String PAGEMAP = NAME_SPACE + "pageMapName";
083:
084:            /**
085:             * Parameter name that tells decode to ignore this request if the
086:             * page+version encoded in the url is not on top of the stack. The value of
087:             * this parameter is not important, it simply has to be present to enable
088:             * the behavior
089:             */
090:            public static final String IGNORE_IF_NOT_ACTIVE_PARAMETER_NAME = NAME_SPACE
091:                    + "ignoreIfNotActive";
092:
093:            /** Comparator implementation that sorts longest strings first */
094:            private static final Comparator lengthComparator = new Comparator() {
095:                public int compare(Object o1, Object o2) {
096:                    // longer first
097:                    if (o1 == o2) {
098:                        return 0;
099:                    } else if (o1 == null) {
100:                        return 1;
101:                    } else if (o2 == null) {
102:                        return -1;
103:                    } else {
104:                        String lhs = (String) o1;
105:                        String rhs = (String) o2;
106:                        return 0 - lhs.compareTo(rhs);
107:                    }
108:                }
109:            };
110:
111:            /** log. */
112:            private static final Log log = LogFactory
113:                    .getLog(WebRequestCodingStrategy.class);
114:
115:            /**
116:             * map of path mounts for mount encoders on paths.
117:             * <p>
118:             * mountsOnPath is sorted by longest paths first to improve resolution of
119:             * possible path conflicts. <br />
120:             * For example: <br/> we mount Page1 on /page and Page2 on /page/test <br />
121:             * Page1 uses a parameters encoder that only encodes parameter values <br />
122:             * now suppose we want to access Page1 with a single paramter param="test".
123:             * we have a url collision since both pages can be access with /page/test
124:             * <br />
125:             * the sorting by longest path first guarantees that the iterator will
126:             * return the mount /page/test before it returns mount /page therefore
127:             * giving deterministic behavior to path resolution by always trying to
128:             * match the longest possible path first.
129:             * </p>
130:             */
131:            private final SortedMap/* <String,IRequestTargetUrlCodingStrategy> */mountsOnPath = new TreeMap(
132:                    lengthComparator);
133:
134:            /** cached url prefix. */
135:            private CharSequence urlPrefix;
136:
137:            /**
138:             * Construct.
139:             */
140:            public WebRequestCodingStrategy() {
141:            }
142:
143:            /**
144:             * @see wicket.request.IRequestCodingStrategy#decode(wicket.Request)
145:             */
146:            public final RequestParameters decode(final Request request) {
147:                final RequestParameters parameters = new RequestParameters();
148:                final String pathInfo = getRequestPath(request);
149:                parameters.setPath(pathInfo);
150:                parameters.setPageMapName(request.getParameter(PAGEMAP));
151:                addInterfaceParameters(request, parameters);
152:                addBookmarkablePageParameters(request, parameters);
153:                addResourceParameters(request, parameters);
154:                parameters.setBehaviorId(request
155:                        .getParameter(BEHAVIOR_ID_PARAMETER_NAME));
156:                if (request.getParameter(IGNORE_IF_NOT_ACTIVE_PARAMETER_NAME) != null) {
157:                    parameters.setOnlyProcessIfPathActive(true);
158:                }
159:
160:                Map map = request.getParameterMap();
161:                Iterator iterator = map.keySet().iterator();
162:                while (iterator.hasNext()) {
163:                    String key = (String) iterator.next();
164:                    if (key.startsWith(NAME_SPACE)) {
165:                        iterator.remove();
166:                    }
167:                }
168:                parameters.setParameters(map);
169:                return parameters;
170:            }
171:
172:            /**
173:             * Encode the given request target. If a mount is found, that mounted url
174:             * will be returned. Otherwise, one of the delegation methods will be
175:             * called. In case you are using custom targets that are not part of the
176:             * default target hierarchy, you need to override
177:             * {@link #doEncode(RequestCycle, IRequestTarget)}, which will be called
178:             * after the defaults have been tried. When that doesn't provide a url
179:             * either, and exception will be thrown saying that encoding could not be
180:             * done.
181:             * 
182:             * @see wicket.request.IRequestCodingStrategy#encode(wicket.RequestCycle,
183:             *      wicket.IRequestTarget)
184:             */
185:            public final CharSequence encode(final RequestCycle requestCycle,
186:                    final IRequestTarget requestTarget) {
187:                // first check whether the target was mounted
188:                CharSequence path = pathForTarget(requestTarget);
189:                if (path != null) {
190:                    CharSequence prefix = urlPrefix(requestCycle);
191:                    // special check if the prefix ends on '/' because a mount always
192:                    // starts with '/'
193:                    if (prefix.charAt(prefix.length() - 1) == '/')
194:                        prefix = prefix.subSequence(0, prefix.length() - 1);
195:                    final AppendingStringBuffer buffer = new AppendingStringBuffer(
196:                            prefix.length() + path.length());
197:                    buffer.append(prefix);
198:                    buffer.append(path);
199:                    return requestCycle.getOriginalResponse().encodeURL(buffer);
200:                }
201:
202:                // no mount found; go on with default processing
203:                if (requestTarget instanceof  IBookmarkablePageRequestTarget) {
204:                    return encode(requestCycle,
205:                            (IBookmarkablePageRequestTarget) requestTarget);
206:                } else if (requestTarget instanceof  ISharedResourceRequestTarget) {
207:                    return encode(requestCycle,
208:                            (ISharedResourceRequestTarget) requestTarget);
209:                } else if (requestTarget instanceof  IListenerInterfaceRequestTarget) {
210:                    return encode(requestCycle,
211:                            (IListenerInterfaceRequestTarget) requestTarget);
212:                } else if (requestTarget instanceof  IPageRequestTarget) {
213:                    return encode(requestCycle,
214:                            (IPageRequestTarget) requestTarget);
215:                }
216:
217:                // fallthough for non-default request targets
218:                String url = doEncode(requestCycle, requestTarget);
219:                if (url != null) {
220:                    return url;
221:                }
222:                // Just return null intead of throwing an exception. So that it can be
223:                // handled better
224:                return null;
225:            }
226:
227:            /**
228:             * @see wicket.request.IRequestTargetMountsInfo#listMounts()
229:             */
230:            public IRequestTargetUrlCodingStrategy[] listMounts() {
231:                return (IRequestTargetUrlCodingStrategy[]) mountsOnPath
232:                        .values()
233:                        .toArray(
234:                                new IRequestTargetUrlCodingStrategy[mountsOnPath
235:                                        .size()]);
236:            }
237:
238:            /**
239:             * @see wicket.request.IRequestTargetMounter#urlCodingStrategyForPath(java.lang.String)
240:             */
241:            public final IRequestTargetUrlCodingStrategy urlCodingStrategyForPath(
242:                    final String path) {
243:                if (path == null) {
244:                    return (IRequestTargetUrlCodingStrategy) mountsOnPath
245:                            .get(null);
246:                } else if (!path.equals("/")) // ignore root paths.. is this the right
247:                // path?
248:                {
249:                    for (final Iterator it = mountsOnPath.entrySet().iterator(); it
250:                            .hasNext();) {
251:                        final Map.Entry entry = (Entry) it.next();
252:                        final String key = (String) entry.getKey();
253:                        if (path.startsWith(key)) {
254:                            return (IRequestTargetUrlCodingStrategy) entry
255:                                    .getValue();
256:                        }
257:                    }
258:                }
259:                return null;
260:            }
261:
262:            /**
263:             * @see wicket.request.IRequestTargetMounter#mount(java.lang.String,
264:             *      wicket.request.target.coding.IRequestTargetUrlCodingStrategy)
265:             */
266:            public final void mount(String path,
267:                    IRequestTargetUrlCodingStrategy encoder) {
268:                if (path == null) {
269:                    throw new IllegalArgumentException(
270:                            "Argument path must be not-null");
271:                }
272:                if (path.equals("/")) {
273:                    throw new IllegalArgumentException(
274:                            "The mount path '/' is reserved for the application home page");
275:                }
276:                if (encoder == null) {
277:                    throw new IllegalArgumentException(
278:                            "Argument encoder must be not-null");
279:                }
280:
281:                // sanity check
282:                if (!path.startsWith("/")) {
283:                    path = "/" + path;
284:                }
285:
286:                if (mountsOnPath.containsKey(path)) {
287:                    throw new WicketRuntimeException(path
288:                            + " is already mounted for "
289:                            + mountsOnPath.get(path));
290:                }
291:                mountsOnPath.put(path, encoder);
292:            }
293:
294:            /**
295:             * @see wicket.request.IRequestCodingStrategy#pathForTarget(wicket.IRequestTarget)
296:             */
297:            public final CharSequence pathForTarget(IRequestTarget requestTarget) {
298:                // first check whether the target was mounted
299:                IRequestTargetUrlCodingStrategy encoder = getMountEncoder(requestTarget);
300:                if (encoder != null) {
301:                    return encoder.encode(requestTarget);
302:                }
303:                return null;
304:            }
305:
306:            /**
307:             * @see wicket.request.IRequestCodingStrategy#targetForRequest(wicket.request.RequestParameters)
308:             */
309:            public final IRequestTarget targetForRequest(
310:                    RequestParameters requestParameters) {
311:                IRequestTargetUrlCodingStrategy encoder = urlCodingStrategyForPath(requestParameters
312:                        .getPath());
313:                return (encoder != null) ? encoder.decode(requestParameters)
314:                        : null;
315:            }
316:
317:            /**
318:             * @see wicket.request.IRequestCodingStrategy#unmount(java.lang.String)
319:             */
320:            public final void unmount(String path) {
321:                if (path == null) {
322:                    throw new IllegalArgumentException(
323:                            "Argument path must be not-null");
324:                }
325:
326:                // sanity check
327:                if (!path.startsWith("/")) {
328:                    path = "/" + path;
329:                }
330:
331:                mountsOnPath.remove(path);
332:            }
333:
334:            /**
335:             * Adds bookmarkable page related parameters (page alias and optionally page
336:             * parameters). Any bookmarkable page alias mount will override this method;
337:             * hence if a mount is found, this method will not be called.
338:             * 
339:             * If you override this method to behave different then also
340:             * {@link #encode(RequestCycle, IBookmarkablePageRequestTarget)} should be
341:             * overridden to by in sync with that behaviour.
342:             * 
343:             * @param request
344:             *            the incoming request
345:             * @param parameters
346:             *            the parameters object to set the found values on
347:             */
348:            protected void addBookmarkablePageParameters(final Request request,
349:                    final RequestParameters parameters) {
350:                final String requestString = request
351:                        .getParameter(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME);
352:                if (requestString != null) {
353:                    final String[] components = Strings.split(requestString,
354:                            Component.PATH_SEPARATOR);
355:                    if (components.length != 2) {
356:                        throw new WicketRuntimeException(
357:                                "Invalid bookmarkablePage parameter: "
358:                                        + requestString
359:                                        + ", expected: 'pageMapName:pageClassName'");
360:                    }
361:
362:                    // Extract any pagemap name
363:                    final String pageMapName = components[0];
364:                    parameters
365:                            .setPageMapName(pageMapName.length() == 0 ? PageMap.DEFAULT_NAME
366:                                    : pageMapName);
367:
368:                    // Extract bookmarkable page class name
369:                    final String pageClassName = components[1];
370:                    parameters.setBookmarkablePageClass(pageClassName);
371:                }
372:            }
373:
374:            /**
375:             * Adds page related parameters (path and pagemap and optionally version and
376:             * interface).
377:             * 
378:             * If you override this method to behave different then also
379:             * {@link #encode(RequestCycle, IListenerInterfaceRequestTarget)} should be
380:             * overridden to by in sync with that behaviour.
381:             * 
382:             * @param request
383:             *            the incoming request
384:             * @param parameters
385:             *            the parameters object to set the found values on
386:             */
387:            protected void addInterfaceParameters(final Request request,
388:                    final RequestParameters parameters) {
389:                // Format of interface target parameter is
390:                // <page-map-name>:<path>:<version>:<interface>
391:                final String requestString = request
392:                        .getParameter(INTERFACE_PARAMETER_NAME);
393:                if (requestString != null) {
394:                    // Split into array of strings
395:                    String[] pathComponents = Strings.split(requestString,
396:                            Component.PATH_SEPARATOR);
397:
398:                    // There must be at least 4 components
399:                    if (pathComponents.length < 4) {
400:                        throw new WicketRuntimeException(
401:                                "Internal error parsing "
402:                                        + INTERFACE_PARAMETER_NAME + " = "
403:                                        + requestString);
404:                    }
405:
406:                    // Set pagemap name
407:                    final String pageMapName = pathComponents[0];
408:                    parameters
409:                            .setPageMapName(pageMapName.length() == 0 ? PageMap.DEFAULT_NAME
410:                                    : pageMapName);
411:
412:                    // Extract interface name after last colon
413:                    final String interfaceName = pathComponents[pathComponents.length - 1];
414:                    parameters
415:                            .setInterfaceName(interfaceName.length() != 0 ? interfaceName
416:                                    : IRedirectListener.INTERFACE.getName());
417:
418:                    // Extract version
419:                    final String versionNumberString = pathComponents[pathComponents.length - 2];
420:                    final int versionNumber = Strings
421:                            .isEmpty(versionNumberString) ? 0 : Integer
422:                            .parseInt(versionNumberString);
423:                    parameters.setVersionNumber(versionNumber);
424:
425:                    // Component path is everything after pageMapName and before version
426:                    final int start = pageMapName.length() + 1;
427:                    final int end = requestString.length()
428:                            - interfaceName.length()
429:                            - versionNumberString.length() - 2;
430:                    final String componentPath = requestString.substring(start,
431:                            end);
432:                    parameters.setComponentPath(componentPath);
433:                }
434:            }
435:
436:            /**
437:             * Adds (shared) resource related parameters (resource key). Any shared
438:             * resource key mount will override this method; hence if a mount is found,
439:             * this method will not be called.
440:             * 
441:             * If you override this method to behave different then also
442:             * {@link #encode(RequestCycle, ISharedResourceRequestTarget)} should be
443:             * overridden to by in sync with that behaviour.
444:             * 
445:             * @param request
446:             *            the incomming request
447:             * @param parameters
448:             *            the parameters object to set the found values on
449:             */
450:            protected void addResourceParameters(Request request,
451:                    RequestParameters parameters) {
452:                String pathInfo = request.getPath();
453:                if (pathInfo != null && pathInfo.startsWith("/resources/")) {
454:                    int ix = "/resources/".length();
455:                    if (pathInfo.length() > ix) {
456:                        StringBuffer path = new StringBuffer(pathInfo
457:                                .substring(ix));
458:                        int ixSemiColon = path.indexOf(";");
459:                        // strip off any jsession id
460:                        if (ixSemiColon != -1) {
461:                            int ixEnd = path.indexOf("?");
462:                            if (ixEnd == -1) {
463:                                ixEnd = path.length();
464:                            }
465:                            path.delete(ixSemiColon, ixEnd);
466:                        }
467:                        parameters.setResourceKey(path.toString());
468:                    }
469:                }
470:            }
471:
472:            /**
473:             * In case you are using custom targets that are not part of the default
474:             * target hierarchy, you need to override this method, which will be called
475:             * after the defaults have been tried. When this doesn't provide a url
476:             * either (returns null), an exception will be thrown by the encode method
477:             * saying that encoding could not be done.
478:             * 
479:             * @param requestCycle
480:             *            the current request cycle (for efficient access)
481:             * 
482:             * @param requestTarget
483:             *            the request target
484:             * @return the url to the provided target
485:             */
486:            protected String doEncode(RequestCycle requestCycle,
487:                    IRequestTarget requestTarget) {
488:                return null;
489:            }
490:
491:            /**
492:             * Encode a page class target.
493:             * 
494:             * If you override this method to behave different then also
495:             * {@link #addBookmarkablePageParameters(Request, RequestParameters)} should
496:             * be overridden to by in sync with that behaviour.
497:             * 
498:             * @param requestCycle
499:             *            the current request cycle
500:             * @param requestTarget
501:             *            the target to encode
502:             * @return the encoded url
503:             */
504:            protected CharSequence encode(RequestCycle requestCycle,
505:                    IBookmarkablePageRequestTarget requestTarget) {
506:                // Begin encoding URL
507:                final AppendingStringBuffer url = new AppendingStringBuffer(64);
508:                url.append(urlPrefix(requestCycle));
509:
510:                // Get page Class
511:                final Class pageClass = requestTarget.getPageClass();
512:                final Application application = Application.get();
513:
514:                // Find pagemap name
515:                String pageMapName = requestTarget.getPageMapName();
516:                if (pageMapName == null) {
517:                    IRequestTarget currentTarget = requestCycle
518:                            .getRequestTarget();
519:                    if (currentTarget instanceof  IPageRequestTarget) {
520:                        Page currentPage = ((IPageRequestTarget) currentTarget)
521:                                .getPage();
522:                        final PageMap pageMap = currentPage.getPageMap();
523:                        if (pageMap.isDefault()) {
524:                            pageMapName = "";
525:                        } else {
526:                            pageMapName = pageMap.getName();
527:                        }
528:                    } else {
529:                        pageMapName = "";
530:                    }
531:                }
532:
533:                boolean firstParameter = true;
534:                if (!application.getHomePage().equals(pageClass)
535:                        || !"".equals(pageMapName)) {
536:                    firstParameter = false;
537:                    url.append('?');
538:                    url
539:                            .append(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME);
540:                    url.append('=');
541:
542:                    // Add <page-map-name>:<bookmarkable-page-class>
543:                    String pageClassName = pageClass.getName();
544:                    /*
545:                     * Encode the url so it is correct even for class names containing
546:                     * non ASCII characters, like ä, æ, ø, å etc.
547:                     * 
548:                     * The reason for this is that when redirecting to these
549:                     * bookmarkable pages, we need to have the url encoded correctly
550:                     * because we can't rely on the browser to interpret the unencoded
551:                     * url correctly.
552:                     */
553:                    try {
554:                        pageClassName = URLEncoder.encode(pageClassName,
555:                                "UTF-8");
556:                    } catch (UnsupportedEncodingException e) {
557:                        throw new RuntimeException(e);
558:                    }
559:                    url.append(pageMapName + Component.PATH_SEPARATOR
560:                            + pageClassName);
561:                }
562:
563:                // Get page parameters
564:                final PageParameters parameters = requestTarget
565:                        .getPageParameters();
566:                if (parameters != null) {
567:                    for (final Iterator iterator = parameters.keySet()
568:                            .iterator(); iterator.hasNext();) {
569:                        final String key = (String) iterator.next();
570:                        final String value = parameters.getString(key);
571:                        if (value != null) {
572:                            String escapedValue = value;
573:                            try {
574:                                escapedValue = URLEncoder.encode(escapedValue,
575:                                        application.getRequestCycleSettings()
576:                                                .getResponseRequestEncoding());
577:                            } catch (UnsupportedEncodingException ex) {
578:                                log.error(ex.getMessage(), ex);
579:                            }
580:                            if (!firstParameter) {
581:                                url.append('&');
582:                            } else {
583:                                firstParameter = false;
584:                                url.append('?');
585:                            }
586:                            url.append(key);
587:                            url.append('=');
588:                            url.append(escapedValue);
589:                        }
590:                    }
591:                }
592:                return requestCycle.getOriginalResponse().encodeURL(url);
593:            }
594:
595:            /**
596:             * Encode a shared resource target.
597:             * 
598:             * If you override this method to behave different then also
599:             * {@link #addResourceParameters(Request, RequestParameters)} should be
600:             * overridden to by in sync with that behaviour.
601:             * 
602:             * @param requestCycle
603:             *            the current request cycle
604:             * @param requestTarget
605:             *            the target to encode
606:             * @return the encoded url
607:             */
608:            protected CharSequence encode(RequestCycle requestCycle,
609:                    ISharedResourceRequestTarget requestTarget) {
610:                final CharSequence prefix = urlPrefix(requestCycle);
611:                final String sharedResourceKey = requestTarget.getResourceKey();
612:                if ((sharedResourceKey == null)
613:                        || (sharedResourceKey.trim().length() == 0)) {
614:                    return prefix;
615:                } else {
616:                    final AppendingStringBuffer buffer = new AppendingStringBuffer(
617:                            sharedResourceKey.length() + prefix.length() + 11);
618:                    buffer.append(prefix);
619:                    if ((buffer.length() > 0)
620:                            && buffer.charAt(buffer.length() - 1) == '/') {
621:                        buffer.append("resources/");
622:                    } else {
623:                        buffer.append("/resources/");
624:                    }
625:                    buffer.append(sharedResourceKey);
626:                    Map map = requestTarget.getRequestParameters()
627:                            .getParameters();
628:                    if (map != null && map.size() > 0) {
629:                        buffer.append('?');
630:                        Iterator it = map.entrySet().iterator();
631:                        while (it.hasNext()) {
632:                            Map.Entry entry = (Entry) it.next();
633:                            buffer.append(entry.getKey());
634:                            buffer.append('=');
635:                            buffer.append(entry.getValue());
636:                            buffer.append('&');
637:                        }
638:                        buffer.setLength(buffer.length() - 1);
639:                    }
640:                    return requestCycle.getOriginalResponse().encodeURL(buffer);
641:                }
642:            }
643:
644:            /**
645:             * Encode a listener interface target.
646:             * 
647:             * If you override this method to behave different then also
648:             * {@link #addInterfaceParameters(Request, RequestParameters)} should be
649:             * overridden to by in sync with that behaviour.
650:             * 
651:             * @param requestCycle
652:             *            the current request cycle
653:             * @param requestTarget
654:             *            the target to encode
655:             * @return the encoded url
656:             */
657:            protected CharSequence encode(RequestCycle requestCycle,
658:                    IListenerInterfaceRequestTarget requestTarget) {
659:                final RequestListenerInterface rli = requestTarget
660:                        .getRequestListenerInterface();
661:
662:                // Start string buffer for url
663:                final AppendingStringBuffer url = new AppendingStringBuffer(64);
664:                url.append(urlPrefix(requestCycle));
665:                url.append('?');
666:                url.append(INTERFACE_PARAMETER_NAME);
667:                url.append('=');
668:
669:                // Get component and page for request target
670:                final Component component = requestTarget.getTarget();
671:                final Page page = component.getPage();
672:
673:                // Add pagemap
674:                final PageMap pageMap = page.getPageMap();
675:                if (!pageMap.isDefault()) {
676:                    url.append(pageMap.getName());
677:                }
678:                url.append(Component.PATH_SEPARATOR);
679:
680:                // Add path to component
681:                url.append(component.getPath());
682:                url.append(Component.PATH_SEPARATOR);
683:
684:                // Add version
685:                final int versionNumber = component.getPage()
686:                        .getCurrentVersionNumber();
687:                if (!rli.getRecordsPageVersion()) {
688:                    url.append(Page.LATEST_VERSION);
689:                } else if (versionNumber > 0) {
690:                    url.append(versionNumber);
691:                }
692:                url.append(Component.PATH_SEPARATOR);
693:
694:                // Add listener interface
695:                final String listenerName = rli.getName();
696:                if (!IRedirectListener.INTERFACE.getName().equals(listenerName)) {
697:                    url.append(listenerName);
698:                }
699:
700:                return requestCycle.getOriginalResponse().encodeURL(url);
701:            }
702:
703:            /**
704:             * Encode a page target.
705:             * 
706:             * @param requestCycle
707:             *            the current request cycle
708:             * @param requestTarget
709:             *            the target to encode
710:             * @return the encoded url
711:             */
712:            protected CharSequence encode(RequestCycle requestCycle,
713:                    IPageRequestTarget requestTarget) {
714:                // Get the page we want a url from:
715:                Page page = requestTarget.getPage();
716:
717:                // A url to a page is the IRedirectListener interface:
718:                CharSequence urlRedirect = page
719:                        .urlFor(IRedirectListener.INTERFACE);
720:
721:                // Touch the page once because it could be that it did go from stateless
722:                // to statefull or it was a internally made page where just a url must
723:                // be made for (frames)
724:                Session.get().touch(page);
725:                return urlRedirect;
726:            }
727:
728:            /**
729:             * Gets the mount encoder for the given request target if any.
730:             * 
731:             * @param requestTarget
732:             *            the request target to match
733:             * @return the mount encoder if any
734:             */
735:            protected IRequestTargetUrlCodingStrategy getMountEncoder(
736:                    IRequestTarget requestTarget) {
737:                // TODO Post 1.2: Performance: Optimize algorithm if possible and/ or
738:                // cache lookup results
739:                for (Iterator i = mountsOnPath.values().iterator(); i.hasNext();) {
740:                    IRequestTargetUrlCodingStrategy encoder = (IRequestTargetUrlCodingStrategy) i
741:                            .next();
742:                    if (encoder.matches(requestTarget)) {
743:                        return encoder;
744:                    }
745:                }
746:
747:                return null;
748:            }
749:
750:            /**
751:             * Gets the request info path. This is an overridable method in order to
752:             * provide users with a means to implement e.g. a path encryption scheme.
753:             * This method by default returns {@link Request#getPath()}.
754:             * 
755:             * @param request
756:             *            the request
757:             * @return the path info object, possibly processed
758:             */
759:            protected String getRequestPath(Request request) {
760:                return request.getPath();
761:            }
762:
763:            /**
764:             * Gets prefix.
765:             * 
766:             * @param requestCycle
767:             *            the request cycle
768:             * 
769:             * @return prefix
770:             */
771:            protected final CharSequence urlPrefix(
772:                    final RequestCycle requestCycle) {
773:                if (urlPrefix == null) {
774:                    final AppendingStringBuffer buffer = new AppendingStringBuffer();
775:                    final WebRequest request = ((WebRequestCycle) requestCycle)
776:                            .getWebRequest();
777:                    if (request != null) {
778:                        String contextPath = Application.get()
779:                                .getApplicationSettings().getContextPath();
780:                        if (contextPath == null) {
781:                            contextPath = ((WebRequestCycle) RequestCycle.get())
782:                                    .getWebRequest().getContextPath();
783:                            if (contextPath == null) {
784:                                contextPath = "";
785:                            }
786:                        }
787:                        if (!contextPath.equals("/")) {
788:                            buffer.append(contextPath);
789:                        }
790:                        String path = request.getServletPath();
791:                        if (path != null && !path.equals("")) {
792:                            if (!buffer.endsWith("/") && !path.startsWith("/"))
793:                                buffer.append("/");
794:                            buffer.append(path);
795:                        }
796:                    }
797:                    // special check, if everything is empty then we need to define '/'
798:                    // as urlPrefix
799:                    // else all urls get relative this is bad for mounts.
800:                    // Except for mounts who have to do a special check else mounts get:
801:                    // //mount
802:                    // see encode(RequestCycle,IRequestTarget) when a mount is found.
803:                    if (buffer.length() == 0) {
804:                        urlPrefix = "/";
805:                    } else {
806:                        /*
807:                         * make the urls consistent. if the mapping is /app/* wicket
808:                         * will switch off between /app/foo and /app?wicket:interface
809:                         * which messes with the path, appending / always to the end
810:                         * makes sure the base path is always /context/servletmapping/
811:                         */
812:                        if (!buffer.endsWith("/")) {
813:                            buffer.append("/");
814:                        }
815:                        urlPrefix = buffer;
816:                    }
817:                }
818:                return urlPrefix;
819:            }
820:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.