PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/ocpsoft-pretty-faces-1.2/src/main/java/com/ocpsoft/pretty/util/UrlPatternParser.java

http://prettyfaces.googlecode.com/
Java | 225 lines | 142 code | 22 blank | 61 comment | 28 complexity | 533590bb519b22c7ed31144683949486 MD5 | raw file
Possible License(s): LGPL-3.0
  1. package com.ocpsoft.pretty.util;
  2. /*
  3. * PrettyFaces is an OpenSource JSF library to create bookmarkable URLs.
  4. * Copyright (C) 2009 - Lincoln Baxter, III <lincoln@ocpsoft.com> This program
  5. * is free software: you can redistribute it and/or modify it under the terms of
  6. * the GNU Lesser General Public License as published by the Free Software
  7. * Foundation, either version 3 of the License, or (at your option) any later
  8. * version. This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  11. * for more details. You should have received a copy of the GNU Lesser General
  12. * Public License along with this program. If not, see the file COPYING.LESSER
  13. * or visit the GNU website at <http://www.gnu.org/licenses/>.
  14. */
  15. import java.util.ArrayList;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.regex.Matcher;
  21. import java.util.regex.Pattern;
  22. import com.ocpsoft.pretty.PrettyException;
  23. import com.ocpsoft.pretty.config.mapping.PathParameter;
  24. import com.ocpsoft.pretty.util.el.ExpressionProcessor;
  25. public class UrlPatternParser
  26. {
  27. private String originalPattern;
  28. private String urlPattern;
  29. private final List<String> expressions = new ArrayList<String>();
  30. private List<PathParameter> pathParams = new ArrayList<PathParameter>();
  31. public UrlPatternParser(final String pattern)
  32. {
  33. setUrlPattern(pattern);
  34. }
  35. /**
  36. * Return true of this parser matches the given URL, otherwise, return
  37. * false.
  38. */
  39. public boolean matches(final String url)
  40. {
  41. return Pattern.compile(urlPattern).matcher(url).matches();
  42. }
  43. /**
  44. * Builds a Map of Expression,Value pairs for this UrlPattern, extracted
  45. * from the provided URL string. This does not return duplicate entries,
  46. * hence, if an el expression is used twice in the same patter, those two or
  47. * more entries will be stored as one entry in this Map.
  48. */
  49. public Map<String, String> getMappedParameters(final String url)
  50. {
  51. Map<String, String> result = new HashMap<String, String>();
  52. Matcher matcher = Pattern.compile(urlPattern).matcher(url);
  53. if (matcher.matches())
  54. {
  55. for (int i = 0; i < expressions.size(); i++)
  56. {
  57. String el = expressions.get(i);
  58. String value = matcher.group(i + 1);
  59. result.put(el, value);
  60. }
  61. }
  62. return result;
  63. }
  64. /**
  65. * @param params
  66. * Array of Object parameters, in order, to be substituted for el
  67. * expressions. This method will call the toString() method on
  68. * each object provided.
  69. * <p>
  70. * If only one param is specified and it is an instance of List,
  71. * the list items will be used as parameters instead. An empty
  72. * list or a single null parameter are both treated as if no
  73. * parameters were specified.
  74. * </p>
  75. * E.g: getMappedUrl(12,55,"foo","bar") for a pattern of
  76. * /#{el.one}/#{el.two}/#{el.three}/#{el.four}/ will return the
  77. * String: "/12/55/foo/bar/"
  78. * @return A URL based on this object's urlPatten, with values substituted
  79. * for el expressions in the order provided
  80. */
  81. public String getMappedUrl(final Object... params)
  82. {
  83. StringBuffer result = new StringBuffer();
  84. if (params != null)
  85. {
  86. Matcher matcher = FacesElUtils.elPattern.matcher(originalPattern);
  87. Object[] parameters = params;
  88. if ((params.length == 1) && (params[0] != null) && (params[0] instanceof List<?>))
  89. {
  90. List<?> list = ((List<?>) params[0]);
  91. if (list.size() == 0)
  92. {
  93. parameters = new Object[0];
  94. }
  95. else
  96. {
  97. parameters = list.toArray(params);
  98. }
  99. }
  100. else if ((params.length == 1) && (params[0] == null))
  101. {
  102. parameters = new Object[0];
  103. }
  104. int i = 0;
  105. if (getParameterCount() != parameters.length)
  106. {
  107. throw new PrettyException("Invalid number of parameters supplied for pattern: " + originalPattern
  108. + ", expected <" + getParameterCount() + ">, got <" + parameters.length + ">");
  109. }
  110. while (matcher.find())
  111. {
  112. matcher.appendReplacement(result, parameters[i].toString());
  113. i++;
  114. }
  115. matcher.appendTail(result);
  116. }
  117. else if (getParameterCount() > 0)
  118. {
  119. throw new PrettyException("Invalid number of parameters supplied: " + originalPattern + ", expected <"
  120. + getParameterCount() + ">, got <0>");
  121. }
  122. return result.toString();
  123. }
  124. /**
  125. * Builds a list of PathParameters for this UrlPattern, extracted from the
  126. * provided URL string (assuming a match is found). This list excludes
  127. * duplicate named parameters.
  128. */
  129. public List<PathParameter> parse(final String url)
  130. {
  131. List<PathParameter> result = new ArrayList<PathParameter>();
  132. Matcher matcher = Pattern.compile(urlPattern).matcher(url);
  133. if (matcher.matches())
  134. {
  135. PathParameter template;
  136. PathParameter parm;
  137. for (int i = 0; i < pathParams.size(); i++)
  138. {
  139. template = pathParams.get(i);
  140. parm = new PathParameter();
  141. if (i != template.getPosition())
  142. {
  143. throw new PrettyException("Error parsing url: <" + url
  144. + ">, parameter order did not match compiled order.");
  145. }
  146. parm.setPosition(i);
  147. parm.setExpression(template.getExpression());
  148. parm.setName(template.getName());
  149. parm.setValue(matcher.group(i + 1));
  150. result.add(parm);
  151. }
  152. }
  153. return result;
  154. }
  155. /**
  156. * Set the pattern for which this parser will match. Find and replace all el
  157. * expressions with regular expressions to extract values from parsed URLs
  158. *
  159. * @param urlPattern
  160. * Pattern to use as a parse template
  161. */
  162. public void setUrlPattern(final String urlPattern)
  163. {
  164. originalPattern = urlPattern;
  165. String temp = urlPattern;
  166. expressions.clear();
  167. List<PathParameter> pathParams = new ArrayList<PathParameter>();
  168. Matcher matcher = FacesElUtils.elPattern.matcher(urlPattern);
  169. int i = 0;
  170. while (matcher.find())
  171. {
  172. String expression = matcher.group(0);
  173. expressions.add(expression);
  174. PathParameter param = ExpressionProcessor.process(ExpressionProcessor.processors, expression);
  175. if (param != null)
  176. {
  177. param.setPosition(i);
  178. pathParams.add(param);
  179. }
  180. i++;
  181. }
  182. temp = ExpressionProcessor.removeEl(ExpressionProcessor.processors, temp);
  183. this.urlPattern = temp;
  184. this.pathParams = Collections.unmodifiableList(pathParams);
  185. }
  186. /**
  187. * Get the number of URL parameters that this parser expects to find in any
  188. * given input string
  189. *
  190. * @return Number of parameters
  191. */
  192. public int getParameterCount()
  193. {
  194. return expressions.size();
  195. }
  196. /**
  197. * Return the list of parameters specified by this pattern.
  198. */
  199. public List<PathParameter> getPathParameters()
  200. {
  201. return pathParams;
  202. }
  203. }