1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet;
16  
17  import com.liferay.portal.kernel.portlet.Route;
18  import com.liferay.portal.kernel.util.HttpUtil;
19  import com.liferay.portal.kernel.util.MapUtil;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  /**
29   * <a href="RouteImpl.java.html"><b><i>View Source</i></b></a>
30   *
31   * @author Connor McKay
32   * @author Brian Wing Shun Chan
33   */
34  public class RouteImpl implements Route {
35  
36      public RouteImpl(String pattern) {
37          _urlPattern = pattern;
38  
39          String regex = escapeRegex(pattern);
40  
41          Matcher matcher = _fragmentPattern.matcher(pattern);
42  
43          while (matcher.find()) {
44              String fragment = matcher.group();
45  
46              RoutePart routePart = new RoutePart(fragment);
47  
48              _routeParts.add(routePart);
49  
50              _urlPattern = _urlPattern.replace(
51                  fragment, routePart.getFragmentName());
52  
53              regex = regex.replace(
54                  escapeRegex(fragment), "(" + routePart.getPattern() + ")");
55          }
56  
57          _regexPattern = Pattern.compile(regex);
58      }
59  
60      public void addDefaultParameter(String name, String value) {
61          _defaultParameters.put(name, value);
62      }
63  
64      public Map<String, String> getDefaultParameters() {
65          return _defaultParameters;
66      }
67  
68      public String parametersToUrl(Map<String, ?> parameters) {
69          List<String> names = new ArrayList<String>();
70  
71          if (!_defaultParameters.isEmpty()) {
72              for (Map.Entry<String, String> entry :
73                      _defaultParameters.entrySet()) {
74  
75                  String name = entry.getKey();
76                  String value = entry.getValue();
77  
78                  if (!value.equals(MapUtil.getString(parameters, name))) {
79                      return null;
80                  }
81  
82                  names.add(name);
83              }
84          }
85  
86          String url = _urlPattern;
87  
88          for (RoutePart routePart : _routeParts) {
89              if (!routePart.matches(parameters)) {
90                  return null;
91              }
92  
93              String name = routePart.getName();
94  
95              names.add(name);
96  
97              String value = MapUtil.getString(parameters, name);
98  
99              value = HttpUtil.encodeURL(value);
100 
101             url = url.replace(routePart.getFragmentName(), value);
102         }
103 
104         for (String name : names) {
105             parameters.remove(name);
106         }
107 
108         return url;
109     }
110 
111     public Map<String, String> urlToParameters(String url) {
112         Matcher matcher = _regexPattern.matcher(url);
113 
114         if (!matcher.matches()) {
115             return null;
116         }
117 
118         Map<String, String> parameters = new HashMap<String, String>(
119             _defaultParameters);
120 
121         for (int i = 1; i <= _routeParts.size(); i++) {
122             RoutePart routePart = _routeParts.get(i - 1);
123 
124             String value = matcher.group(i);
125 
126             parameters.put(routePart.getName(), value);
127         }
128 
129         return parameters;
130     }
131 
132     protected String escapeRegex(String s) {
133         Matcher matcher = _escapeRegexPattern.matcher(s);
134 
135         return matcher.replaceAll("\\\\$0");
136     }
137 
138     private static Pattern _escapeRegexPattern = Pattern.compile(
139         "[\\{\\}\\(\\)\\[\\]\\*\\+\\?\\$\\^\\.\\#\\\\]");
140     private static Pattern _fragmentPattern = Pattern.compile("\\{.+?\\}");
141 
142     private Map<String, String> _defaultParameters =
143         new HashMap<String, String>();
144     private Pattern _regexPattern;
145     private List<RoutePart> _routeParts = new ArrayList<RoutePart>();
146     private String _urlPattern;
147 
148 }