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.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.portlet.Route;
20  import com.liferay.portal.kernel.portlet.RouteNotFoundException;
21  import com.liferay.portal.kernel.portlet.Router;
22  import com.liferay.portal.kernel.util.HttpUtil;
23  import com.liferay.portal.kernel.util.MapUtil;
24  import com.liferay.portal.kernel.util.StringBundler;
25  import com.liferay.portal.kernel.util.StringPool;
26  
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  
33  /**
34   * <a href="RouterImpl.java.html"><b><i>View Source</i></b></a>
35   *
36   * @author Connor McKay
37   * @author Brian Wing Shun Chan
38   */
39  public class RouterImpl implements Router {
40  
41      public Route addRoute(String pattern) {
42          Route route = new RouteImpl(pattern);
43  
44          _routes.add(route);
45  
46          return route;
47      }
48  
49      public String parametersToUrl(Map<String, ?> parameters)
50          throws RouteNotFoundException {
51  
52          for (Route route : _routes) {
53              String url = route.parametersToUrl(parameters);
54  
55              if (url != null) {
56                  if (!parameters.isEmpty()) {
57                      url = url.concat(StringPool.QUESTION).concat(
58                          parametersToQueryString(parameters));
59                  }
60  
61                  return url;
62              }
63          }
64  
65          throw new RouteNotFoundException(
66              "No route could be found to use for parameters " +
67                  MapUtil.toString(parameters));
68      }
69  
70      public Map<String, String> urlToParameters(String url)
71          throws RouteNotFoundException {
72  
73          Map<String, String> queryParameters = new HashMap<String, String>();
74  
75          String[] urlParts = url.split("\\?", 2);
76  
77          if (urlParts.length > 1) {
78              String query = urlParts[1];
79  
80              url = urlParts[0];
81  
82              try {
83                  queryStringToParameters(query, queryParameters);
84              }
85              catch (Exception e) {
86                  if (_log.isWarnEnabled()) {
87                      _log.warn(e, e);
88                  }
89              }
90          }
91  
92          for (Route route : _routes) {
93              Map<String, String> parameters = route.urlToParameters(url);
94  
95              if (parameters != null) {
96                  queryParameters.putAll(parameters);
97  
98                  return queryParameters;
99              }
100         }
101 
102         throw new RouteNotFoundException(
103             "No route could be found to match url " + url);
104     }
105 
106     protected String parametersToQueryString(Map<String, ?> parameters) {
107         StringBundler sb = new StringBundler(parameters.size() * 4 - 1);
108 
109         Iterator<String> itr = parameters.keySet().iterator();
110 
111         while (itr.hasNext()) {
112             String name = itr.next();
113 
114             String value = MapUtil.getString(parameters, name);
115 
116             sb.append(HttpUtil.encodeURL(name));
117             sb.append(StringPool.EQUAL);
118             sb.append(HttpUtil.encodeURL(value));
119 
120             if (itr.hasNext()) {
121                 sb.append(StringPool.AMPERSAND);
122             }
123         }
124 
125         return sb.toString();
126     }
127 
128     protected void queryStringToParameters(
129         String queryString, Map<String, String> parameters) {
130 
131         String[] parametersArray = queryString.split(StringPool.AMPERSAND);
132 
133         for (String parameterString : parametersArray) {
134             String[] parameterArray = parameterString.split(StringPool.EQUAL);
135 
136             if (parameterArray.length != 2) {
137                 throw new IllegalArgumentException(
138                     "Invalid query string " + queryString);
139             }
140 
141             String name = parameterArray[0];
142             String value = parameterArray[1];
143 
144             parameters.put(HttpUtil.decodeURL(name), HttpUtil.decodeURL(value));
145         }
146     }
147 
148     private static Log _log = LogFactoryUtil.getLog(Router.class);
149 
150     private List<Route> _routes = new ArrayList<Route>();
151 
152 }