/config-servlet/src/main/java/org/ocpsoft/rewrite/servlet/config/RequestParameter.java

https://github.com/chkal/rewrite · Java · 273 lines · 171 code · 22 blank · 80 comment · 10 complexity · dc16cec35fa2ec3e1da516fd5d42a4c4 MD5 · raw file

  1. /*
  2. * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
  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. package org.ocpsoft.rewrite.servlet.config;
  17. import java.util.Arrays;
  18. import java.util.Enumeration;
  19. import java.util.LinkedHashSet;
  20. import java.util.Set;
  21. import javax.servlet.http.HttpServletRequest;
  22. import org.ocpsoft.common.util.Assert;
  23. import org.ocpsoft.rewrite.config.Condition;
  24. import org.ocpsoft.rewrite.config.ConfigurationRuleParameterBuilder;
  25. import org.ocpsoft.rewrite.context.EvaluationContext;
  26. import org.ocpsoft.rewrite.event.Rewrite;
  27. import org.ocpsoft.rewrite.param.ParameterStore;
  28. import org.ocpsoft.rewrite.param.Parameterized;
  29. import org.ocpsoft.rewrite.param.ParameterizedPattern;
  30. import org.ocpsoft.rewrite.param.ParameterizedPatternParser;
  31. import org.ocpsoft.rewrite.param.RegexParameterizedPatternParser;
  32. import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
  33. /**
  34. * A {@link Condition} that inspects values returned by {@link HttpServletRequest#getParameterMap()}
  35. *
  36. * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
  37. */
  38. public abstract class RequestParameter extends HttpCondition implements Parameterized
  39. {
  40. private final ParameterizedPatternParser name;
  41. private final ParameterizedPatternParser value;
  42. private RequestParameter(final String name, final String value)
  43. {
  44. Assert.notNull(name, "Header name pattern cannot be null.");
  45. Assert.notNull(value, "Header value pattern cannot be null.");
  46. this.name = new RegexParameterizedPatternParser(name);
  47. this.value = new RegexParameterizedPatternParser(value);
  48. }
  49. /**
  50. * Create a {@link Condition} that matches against both request parameter names and values.
  51. * <p>
  52. * Parameter name and value expressions may be parameterized:
  53. * <p>
  54. * <code>
  55. * RequestParameter.matches("username", "guest")<br/>
  56. * RequestParameter.matches("username", "{name}")<br/>
  57. * RequestParameter.matches("{anything}", "{value}")<br/>
  58. * </code>
  59. *
  60. * @param name {@link ParameterizedPattern} matching the request parameter name.
  61. * @param value {@link ParameterizedPattern} matching the request parameter value.
  62. *
  63. * @see ConfigurationRuleParameterBuilder#where(String) {@link HttpServletRequest#getParameterMap()}
  64. */
  65. public static RequestParameter matches(final String name, final String value)
  66. {
  67. return new RequestParameter(name, value) {
  68. @Override
  69. public String toString()
  70. {
  71. return "RequestParameter.matches(\"" + name + "\", \"" + value + "\")";
  72. }
  73. };
  74. }
  75. public static RequestParameter matchesAll(final String name, final String value)
  76. {
  77. return new AllRequestParameters(name, value) {
  78. @Override
  79. public String toString()
  80. {
  81. return "RequestParameter.matchesAll(\"" + name + "\", \"" + value + "\")";
  82. }
  83. };
  84. }
  85. /**
  86. * Creates a {@link RequestParameter} condition that will capture the value of the the given request parameter if it
  87. * exists so you can bind to it using <code>.where()</code>.
  88. *
  89. * @param name The name of the request parameter
  90. */
  91. public static RequestParameter captureValue(final String name)
  92. {
  93. return new RequestParameter(name, "{" + name + "}") {
  94. @Override
  95. public String toString()
  96. {
  97. return "RequestParameter.captureValue(\"" + name + "\")";
  98. }
  99. @Override
  100. public boolean evaluateHttp(HttpServletRewrite event, EvaluationContext context)
  101. {
  102. super.evaluateHttp(event, context);
  103. return true;
  104. }
  105. };
  106. }
  107. /**
  108. * Create a {@link Condition} that matches against the existence of a request parameter with a name matching the
  109. * given pattern. The parameter value is ignored.
  110. * <p>
  111. * Parameter name expressions may be parameterized:
  112. * <p>
  113. * <code>
  114. * RequestParameter.exists("username")<br/>
  115. * RequestParameter.exists("{name}")<br/>
  116. * ...
  117. * </code>
  118. *
  119. * @param name {@link ParameterizedPattern} matching the request parameter name.
  120. *
  121. * @see ConfigurationRuleParameterBuilder#where(String) {@link HttpServletRequest#getParameterMap()}
  122. */
  123. public static RequestParameter exists(final String name)
  124. {
  125. return new RequestParameter(name, "{" + RequestParameter.class.getName() + "_" + name + "_value}") {
  126. @Override
  127. public String toString()
  128. {
  129. return "RequestParameter.exists(\"" + name + "\")";
  130. }
  131. };
  132. }
  133. /**
  134. * Create a {@link Condition} that matches only against the existence of a request parameter value matching the given
  135. * pattern. The parameter name is ignored.
  136. * <p>
  137. * Parameter value expressions may be parameterized:
  138. * <p>
  139. * <code>
  140. * RequestParameter.valueExists("guest")<br/>
  141. * RequestParameter.valueExists("{username}")<br/>
  142. * ...
  143. * </code>
  144. *
  145. * @param name {@link ParameterizedPattern} matching the request parameter name.
  146. *
  147. * @see ConfigurationRuleParameterBuilder#where(String) {@link HttpServletRequest#getParameterMap()}
  148. */
  149. public static RequestParameter valueExists(final String value)
  150. {
  151. return new RequestParameter("{" + RequestParameter.class.getName() + "_" + value + "_name}", value) {
  152. @Override
  153. public String toString()
  154. {
  155. return "RequestParameter.valueExists(\"" + value + "\")";
  156. }
  157. };
  158. }
  159. @Override
  160. public boolean evaluateHttp(final HttpServletRewrite event, final EvaluationContext context)
  161. {
  162. HttpServletRequest request = event.getRequest();
  163. Enumeration<?> parameterNames = request.getParameterNames();
  164. while (parameterNames.hasMoreElements())
  165. {
  166. String parameter = parameterNames.nextElement().toString();
  167. if (name.parse(parameter).submit(event, context) && matchesValue(event, context, request, parameter))
  168. {
  169. return true;
  170. }
  171. }
  172. return false;
  173. }
  174. private boolean matchesValue(Rewrite event, EvaluationContext context, final HttpServletRequest request,
  175. final String parameterName)
  176. {
  177. for (String contents : Arrays.asList(request.getParameterValues(parameterName)))
  178. {
  179. if (value.parse(contents).submit(event, context))
  180. {
  181. return true;
  182. }
  183. }
  184. return false;
  185. }
  186. /**
  187. * Get the {@link ParameterizedPattern} of the request parameter name.
  188. */
  189. public ParameterizedPatternParser getNameExpression()
  190. {
  191. return name;
  192. }
  193. /**
  194. * Get the {@link ParameterizedPattern} of the request parameter value.
  195. */
  196. public ParameterizedPatternParser getValueExpression()
  197. {
  198. return value;
  199. }
  200. private abstract static class AllRequestParameters extends RequestParameter
  201. {
  202. public AllRequestParameters(String name, String value)
  203. {
  204. super(name, value);
  205. }
  206. @Override
  207. public boolean evaluateHttp(final HttpServletRewrite event, final EvaluationContext context)
  208. {
  209. HttpServletRequest request = event.getRequest();
  210. Enumeration<?> parameterNames = request.getParameterNames();
  211. while (parameterNames.hasMoreElements())
  212. {
  213. String name = parameterNames.nextElement().toString();
  214. if (getNameExpression().parse(name).submit(event, context))
  215. {
  216. if (matchesValues(event, context, request, name))
  217. {
  218. return true;
  219. }
  220. }
  221. }
  222. return false;
  223. }
  224. private boolean matchesValues(Rewrite event, EvaluationContext context, final HttpServletRequest request,
  225. final String name)
  226. {
  227. for (String contents : Arrays.asList(request.getParameterValues(name)))
  228. {
  229. if (!getValueExpression().parse(contents).submit(event, context))
  230. {
  231. return false;
  232. }
  233. }
  234. return true;
  235. }
  236. }
  237. @Override
  238. public Set<String> getRequiredParameterNames()
  239. {
  240. Set<String> result = new LinkedHashSet<String>();
  241. result.addAll(name.getRequiredParameterNames());
  242. result.addAll(value.getRequiredParameterNames());
  243. return result;
  244. }
  245. @Override
  246. public void setParameterStore(ParameterStore store)
  247. {
  248. name.setParameterStore(store);
  249. value.setParameterStore(store);
  250. }
  251. }