001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.portlet.bind; 018 019import javax.portlet.PortletRequest; 020 021/** 022 * Parameter extraction methods, for an approach distinct from data binding, 023 * in which parameters of specific types are required. 024 * 025 * <p>This approach is very useful for simple submissions, where binding 026 * request parameters to a command object would be overkill. 027 * 028 * @author Juergen Hoeller 029 * @author Keith Donald 030 * @author John A. Lewis 031 * @since 2.0 032 */ 033public abstract class PortletRequestUtils { 034 035 private static final IntParser INT_PARSER = new IntParser(); 036 037 private static final LongParser LONG_PARSER = new LongParser(); 038 039 private static final FloatParser FLOAT_PARSER = new FloatParser(); 040 041 private static final DoubleParser DOUBLE_PARSER = new DoubleParser(); 042 043 private static final BooleanParser BOOLEAN_PARSER = new BooleanParser(); 044 045 private static final StringParser STRING_PARSER = new StringParser(); 046 047 048 /** 049 * Get an Integer parameter, or {@code null} if not present. 050 * Throws an exception if it the parameter value isn't a number. 051 * @param request current portlet request 052 * @param name the name of the parameter 053 * @return the Integer value, or {@code null} if not present 054 * @throws PortletRequestBindingException a subclass of PortletException, 055 * so it doesn't need to be caught 056 */ 057 public static Integer getIntParameter(PortletRequest request, String name) 058 throws PortletRequestBindingException { 059 060 if (request.getParameter(name) == null) { 061 return null; 062 } 063 return getRequiredIntParameter(request, name); 064 } 065 066 /** 067 * Get an int parameter, with a fallback value. Never throws an exception. 068 * Can pass a distinguished value as default to enable checks of whether it was supplied. 069 * @param request current portlet request 070 * @param name the name of the parameter 071 * @param defaultVal the default value to use as fallback 072 */ 073 public static int getIntParameter(PortletRequest request, String name, int defaultVal) { 074 if (request.getParameter(name) == null) { 075 return defaultVal; 076 } 077 try { 078 return getRequiredIntParameter(request, name); 079 } 080 catch (PortletRequestBindingException ex) { 081 return defaultVal; 082 } 083 } 084 085 /** 086 * Get an array of int parameters, return an empty array if not found. 087 * @param request current portlet request 088 * @param name the name of the parameter with multiple possible values 089 */ 090 public static int[] getIntParameters(PortletRequest request, String name) { 091 try { 092 return getRequiredIntParameters(request, name); 093 } 094 catch (PortletRequestBindingException ex) { 095 return new int[0]; 096 } 097 } 098 099 /** 100 * Get an int parameter, throwing an exception if it isn't found or isn't a number. 101 * @param request current portlet request 102 * @param name the name of the parameter 103 * @throws PortletRequestBindingException a subclass of PortletException, 104 * so it doesn't need to be caught 105 */ 106 public static int getRequiredIntParameter(PortletRequest request, String name) 107 throws PortletRequestBindingException { 108 109 return INT_PARSER.parseInt(name, request.getParameter(name)); 110 } 111 112 /** 113 * Get an array of int parameters, throwing an exception if not found or one is not a number.. 114 * @param request current portlet request 115 * @param name the name of the parameter with multiple possible values 116 * @throws PortletRequestBindingException a subclass of PortletException, 117 * so it doesn't need to be caught 118 */ 119 public static int[] getRequiredIntParameters(PortletRequest request, String name) 120 throws PortletRequestBindingException { 121 122 return INT_PARSER.parseInts(name, request.getParameterValues(name)); 123 } 124 125 126 /** 127 * Get a Long parameter, or {@code null} if not present. 128 * Throws an exception if it the parameter value isn't a number. 129 * @param request current portlet request 130 * @param name the name of the parameter 131 * @return the Long value, or {@code null} if not present 132 * @throws PortletRequestBindingException a subclass of PortletException, 133 * so it doesn't need to be caught 134 */ 135 public static Long getLongParameter(PortletRequest request, String name) 136 throws PortletRequestBindingException { 137 138 if (request.getParameter(name) == null) { 139 return null; 140 } 141 return getRequiredLongParameter(request, name); 142 } 143 144 /** 145 * Get a long parameter, with a fallback value. Never throws an exception. 146 * Can pass a distinguished value as default to enable checks of whether it was supplied. 147 * @param request current portlet request 148 * @param name the name of the parameter 149 * @param defaultVal the default value to use as fallback 150 */ 151 public static long getLongParameter(PortletRequest request, String name, long defaultVal) { 152 if (request.getParameter(name) == null) { 153 return defaultVal; 154 } 155 try { 156 return getRequiredLongParameter(request, name); 157 } 158 catch (PortletRequestBindingException ex) { 159 return defaultVal; 160 } 161 } 162 163 /** 164 * Get an array of long parameters, return an empty array if not found. 165 * @param request current portlet request 166 * @param name the name of the parameter with multiple possible values 167 */ 168 public static long[] getLongParameters(PortletRequest request, String name) { 169 try { 170 return getRequiredLongParameters(request, name); 171 } 172 catch (PortletRequestBindingException ex) { 173 return new long[0]; 174 } 175 } 176 177 /** 178 * Get a long parameter, throwing an exception if it isn't found or isn't a number. 179 * @param request current portlet request 180 * @param name the name of the parameter 181 * @throws PortletRequestBindingException a subclass of PortletException, 182 * so it doesn't need to be caught 183 */ 184 public static long getRequiredLongParameter(PortletRequest request, String name) 185 throws PortletRequestBindingException { 186 187 return LONG_PARSER.parseLong(name, request.getParameter(name)); 188 } 189 190 /** 191 * Get an array of long parameters, throwing an exception if not found or one is not a number. 192 * @param request current portlet request 193 * @param name the name of the parameter with multiple possible values 194 * @throws PortletRequestBindingException a subclass of PortletException, 195 * so it doesn't need to be caught 196 */ 197 public static long[] getRequiredLongParameters(PortletRequest request, String name) 198 throws PortletRequestBindingException { 199 200 return LONG_PARSER.parseLongs(name, request.getParameterValues(name)); 201 } 202 203 204 /** 205 * Get a Float parameter, or {@code null} if not present. 206 * Throws an exception if it the parameter value isn't a number. 207 * @param request current portlet request 208 * @param name the name of the parameter 209 * @return the Float value, or {@code null} if not present 210 * @throws PortletRequestBindingException a subclass of PortletException, 211 * so it doesn't need to be caught 212 */ 213 public static Float getFloatParameter(PortletRequest request, String name) 214 throws PortletRequestBindingException { 215 216 if (request.getParameter(name) == null) { 217 return null; 218 } 219 return getRequiredFloatParameter(request, name); 220 } 221 222 /** 223 * Get a float parameter, with a fallback value. Never throws an exception. 224 * Can pass a distinguished value as default to enable checks of whether it was supplied. 225 * @param request current portlet request 226 * @param name the name of the parameter 227 * @param defaultVal the default value to use as fallback 228 */ 229 public static float getFloatParameter(PortletRequest request, String name, float defaultVal) { 230 if (request.getParameter(name) == null) { 231 return defaultVal; 232 } 233 try { 234 return getRequiredFloatParameter(request, name); 235 } 236 catch (PortletRequestBindingException ex) { 237 return defaultVal; 238 } 239 } 240 241 /** 242 * Get an array of float parameters, return an empty array if not found. 243 * @param request current portlet request 244 * @param name the name of the parameter with multiple possible values 245 */ 246 public static float[] getFloatParameters(PortletRequest request, String name) { 247 try { 248 return getRequiredFloatParameters(request, name); 249 } 250 catch (PortletRequestBindingException ex) { 251 return new float[0]; 252 } 253 } 254 255 /** 256 * Get a float parameter, throwing an exception if it isn't found or isn't a number. 257 * @param request current portlet request 258 * @param name the name of the parameter 259 * @throws PortletRequestBindingException a subclass of PortletException, 260 * so it doesn't need to be caught 261 */ 262 public static float getRequiredFloatParameter(PortletRequest request, String name) 263 throws PortletRequestBindingException { 264 265 return FLOAT_PARSER.parseFloat(name, request.getParameter(name)); 266 } 267 268 /** 269 * Get an array of float parameters, throwing an exception if not found or one is not a number. 270 * @param request current portlet request 271 * @param name the name of the parameter with multiple possible values 272 * @throws PortletRequestBindingException a subclass of PortletException, 273 * so it doesn't need to be caught 274 */ 275 public static float[] getRequiredFloatParameters(PortletRequest request, String name) 276 throws PortletRequestBindingException { 277 278 return FLOAT_PARSER.parseFloats(name, request.getParameterValues(name)); 279 } 280 281 282 /** 283 * Get a Double parameter, or {@code null} if not present. 284 * Throws an exception if it the parameter value isn't a number. 285 * @param request current portlet request 286 * @param name the name of the parameter 287 * @return the Double value, or {@code null} if not present 288 * @throws PortletRequestBindingException a subclass of PortletException, 289 * so it doesn't need to be caught 290 */ 291 public static Double getDoubleParameter(PortletRequest request, String name) 292 throws PortletRequestBindingException { 293 294 if (request.getParameter(name) == null) { 295 return null; 296 } 297 return getRequiredDoubleParameter(request, name); 298 } 299 300 /** 301 * Get a double parameter, with a fallback value. Never throws an exception. 302 * Can pass a distinguished value as default to enable checks of whether it was supplied. 303 * @param request current portlet request 304 * @param name the name of the parameter 305 * @param defaultVal the default value to use as fallback 306 */ 307 public static double getDoubleParameter(PortletRequest request, String name, double defaultVal) { 308 if (request.getParameter(name) == null) { 309 return defaultVal; 310 } 311 try { 312 return getRequiredDoubleParameter(request, name); 313 } 314 catch (PortletRequestBindingException ex) { 315 return defaultVal; 316 } 317 } 318 319 /** 320 * Get an array of double parameters, return an empty array if not found. 321 * @param request current portlet request 322 * @param name the name of the parameter with multiple possible values 323 */ 324 public static double[] getDoubleParameters(PortletRequest request, String name) { 325 try { 326 return getRequiredDoubleParameters(request, name); 327 } 328 catch (PortletRequestBindingException ex) { 329 return new double[0]; 330 } 331 } 332 333 /** 334 * Get a double parameter, throwing an exception if it isn't found or isn't a number. 335 * @param request current portlet request 336 * @param name the name of the parameter 337 * @throws PortletRequestBindingException a subclass of PortletException, 338 * so it doesn't need to be caught 339 */ 340 public static double getRequiredDoubleParameter(PortletRequest request, String name) 341 throws PortletRequestBindingException { 342 343 return DOUBLE_PARSER.parseDouble(name, request.getParameter(name)); 344 } 345 346 /** 347 * Get an array of double parameters, throwing an exception if not found or one is not a number. 348 * @param request current portlet request 349 * @param name the name of the parameter with multiple possible values 350 * @throws PortletRequestBindingException a subclass of PortletException, 351 * so it doesn't need to be caught 352 */ 353 public static double[] getRequiredDoubleParameters(PortletRequest request, String name) 354 throws PortletRequestBindingException { 355 356 return DOUBLE_PARSER.parseDoubles(name, request.getParameterValues(name)); 357 } 358 359 360 /** 361 * Get a Boolean parameter, or {@code null} if not present. 362 * Throws an exception if it the parameter value isn't a boolean. 363 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 364 * treats every other non-empty value as false (i.e. parses leniently). 365 * @param request current portlet request 366 * @param name the name of the parameter 367 * @return the Boolean value, or {@code null} if not present 368 * @throws PortletRequestBindingException a subclass of PortletException, 369 * so it doesn't need to be caught 370 */ 371 public static Boolean getBooleanParameter(PortletRequest request, String name) 372 throws PortletRequestBindingException { 373 374 if (request.getParameter(name) == null) { 375 return null; 376 } 377 return (getRequiredBooleanParameter(request, name)); 378 } 379 380 /** 381 * Get a boolean parameter, with a fallback value. Never throws an exception. 382 * Can pass a distinguished value as default to enable checks of whether it was supplied. 383 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 384 * treats every other non-empty value as false (i.e. parses leniently). 385 * @param request current portlet request 386 * @param name the name of the parameter 387 * @param defaultVal the default value to use as fallback 388 */ 389 public static boolean getBooleanParameter(PortletRequest request, String name, boolean defaultVal) { 390 if (request.getParameter(name) == null) { 391 return defaultVal; 392 } 393 try { 394 return getRequiredBooleanParameter(request, name); 395 } 396 catch (PortletRequestBindingException ex) { 397 return defaultVal; 398 } 399 } 400 401 /** 402 * Get an array of boolean parameters, return an empty array if not found. 403 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 404 * treats every other non-empty value as false (i.e. parses leniently). 405 * @param request current portlet request 406 * @param name the name of the parameter with multiple possible values 407 */ 408 public static boolean[] getBooleanParameters(PortletRequest request, String name) { 409 try { 410 return getRequiredBooleanParameters(request, name); 411 } 412 catch (PortletRequestBindingException ex) { 413 return new boolean[0]; 414 } 415 } 416 417 /** 418 * Get a boolean parameter, throwing an exception if it isn't found 419 * or isn't a boolean. 420 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 421 * treats every other non-empty value as false (i.e. parses leniently). 422 * @param request current portlet request 423 * @param name the name of the parameter 424 * @throws PortletRequestBindingException a subclass of PortletException, 425 * so it doesn't need to be caught 426 */ 427 public static boolean getRequiredBooleanParameter(PortletRequest request, String name) 428 throws PortletRequestBindingException { 429 430 return BOOLEAN_PARSER.parseBoolean(name, request.getParameter(name)); 431 } 432 433 /** 434 * Get an array of boolean parameters, throwing an exception if not found 435 * or one isn't a boolean. 436 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 437 * treats every other non-empty value as false (i.e. parses leniently). 438 * @param request current portlet request 439 * @param name the name of the parameter 440 * @throws PortletRequestBindingException a subclass of PortletException, 441 * so it doesn't need to be caught 442 */ 443 public static boolean[] getRequiredBooleanParameters(PortletRequest request, String name) 444 throws PortletRequestBindingException { 445 446 return BOOLEAN_PARSER.parseBooleans(name, request.getParameterValues(name)); 447 } 448 449 450 /** 451 * Get a String parameter, or {@code null} if not present. 452 * Throws an exception if it the parameter value is empty. 453 * @param request current portlet request 454 * @param name the name of the parameter 455 * @return the String value, or {@code null} if not present 456 * @throws PortletRequestBindingException a subclass of PortletException, 457 * so it doesn't need to be caught 458 */ 459 public static String getStringParameter(PortletRequest request, String name) 460 throws PortletRequestBindingException { 461 462 if (request.getParameter(name) == null) { 463 return null; 464 } 465 return getRequiredStringParameter(request, name); 466 } 467 468 /** 469 * Get a String parameter, with a fallback value. Never throws an exception. 470 * Can pass a distinguished value to default to enable checks of whether it was supplied. 471 * @param request current portlet request 472 * @param name the name of the parameter 473 * @param defaultVal the default value to use as fallback 474 */ 475 public static String getStringParameter(PortletRequest request, String name, String defaultVal) { 476 String val = request.getParameter(name); 477 return (val != null ? val : defaultVal); 478 } 479 480 /** 481 * Get an array of String parameters, return an empty array if not found. 482 * @param request current portlet request 483 * @param name the name of the parameter with multiple possible values 484 */ 485 public static String[] getStringParameters(PortletRequest request, String name) { 486 try { 487 return getRequiredStringParameters(request, name); 488 } 489 catch (PortletRequestBindingException ex) { 490 return new String[0]; 491 } 492 } 493 494 /** 495 * Get a String parameter, throwing an exception if it isn't found or is empty. 496 * @param request current portlet request 497 * @param name the name of the parameter 498 * @throws PortletRequestBindingException a subclass of PortletException, 499 * so it doesn't need to be caught 500 */ 501 public static String getRequiredStringParameter(PortletRequest request, String name) 502 throws PortletRequestBindingException { 503 504 return STRING_PARSER.validateRequiredString(name, request.getParameter(name)); 505 } 506 507 /** 508 * Get an array of String parameters, throwing an exception if not found or one is empty. 509 * @param request current portlet request 510 * @param name the name of the parameter 511 * @throws PortletRequestBindingException a subclass of PortletException, 512 * so it doesn't need to be caught 513 */ 514 public static String[] getRequiredStringParameters(PortletRequest request, String name) 515 throws PortletRequestBindingException { 516 517 return STRING_PARSER.validateRequiredStrings(name, request.getParameterValues(name)); 518 } 519 520 521 private abstract static class ParameterParser<T> { 522 523 protected final T parse(String name, String parameter) throws PortletRequestBindingException { 524 validateRequiredParameter(name, parameter); 525 try { 526 return doParse(parameter); 527 } 528 catch (NumberFormatException ex) { 529 throw new PortletRequestBindingException( 530 "Required " + getType() + " parameter '" + name + "' with value of '" + 531 parameter + "' is not a valid number", ex); 532 } 533 } 534 535 protected final void validateRequiredParameter(String name, Object parameter) 536 throws PortletRequestBindingException { 537 538 if (parameter == null) { 539 throw new MissingPortletRequestParameterException(name, getType()); 540 } 541 } 542 543 protected abstract String getType(); 544 545 protected abstract T doParse(String parameter) throws NumberFormatException; 546 } 547 548 549 private static class IntParser extends ParameterParser<Integer> { 550 551 @Override 552 protected String getType() { 553 return "int"; 554 } 555 556 @Override 557 protected Integer doParse(String s) throws NumberFormatException { 558 return Integer.valueOf(s); 559 } 560 561 public int parseInt(String name, String parameter) throws PortletRequestBindingException { 562 return parse(name, parameter); 563 } 564 565 public int[] parseInts(String name, String[] values) throws PortletRequestBindingException { 566 validateRequiredParameter(name, values); 567 int[] parameters = new int[values.length]; 568 for (int i = 0; i < values.length; i++) { 569 parameters[i] = parseInt(name, values[i]); 570 } 571 return parameters; 572 } 573 } 574 575 576 private static class LongParser extends ParameterParser<Long> { 577 578 @Override 579 protected String getType() { 580 return "long"; 581 } 582 583 @Override 584 protected Long doParse(String parameter) throws NumberFormatException { 585 return Long.valueOf(parameter); 586 } 587 588 public long parseLong(String name, String parameter) throws PortletRequestBindingException { 589 return parse(name, parameter); 590 } 591 592 public long[] parseLongs(String name, String[] values) throws PortletRequestBindingException { 593 validateRequiredParameter(name, values); 594 long[] parameters = new long[values.length]; 595 for (int i = 0; i < values.length; i++) { 596 parameters[i] = parseLong(name, values[i]); 597 } 598 return parameters; 599 } 600 } 601 602 603 private static class FloatParser extends ParameterParser<Float> { 604 605 @Override 606 protected String getType() { 607 return "float"; 608 } 609 610 @Override 611 protected Float doParse(String parameter) throws NumberFormatException { 612 return Float.valueOf(parameter); 613 } 614 615 public float parseFloat(String name, String parameter) throws PortletRequestBindingException { 616 return parse(name, parameter); 617 } 618 619 public float[] parseFloats(String name, String[] values) throws PortletRequestBindingException { 620 validateRequiredParameter(name, values); 621 float[] parameters = new float[values.length]; 622 for (int i = 0; i < values.length; i++) { 623 parameters[i] = parseFloat(name, values[i]); 624 } 625 return parameters; 626 } 627 } 628 629 630 private static class DoubleParser extends ParameterParser<Double> { 631 632 @Override 633 protected String getType() { 634 return "double"; 635 } 636 637 @Override 638 protected Double doParse(String parameter) throws NumberFormatException { 639 return Double.valueOf(parameter); 640 } 641 642 public double parseDouble(String name, String parameter) throws PortletRequestBindingException { 643 return parse(name, parameter); 644 } 645 646 public double[] parseDoubles(String name, String[] values) throws PortletRequestBindingException { 647 validateRequiredParameter(name, values); 648 double[] parameters = new double[values.length]; 649 for (int i = 0; i < values.length; i++) { 650 parameters[i] = parseDouble(name, values[i]); 651 } 652 return parameters; 653 } 654 } 655 656 657 private static class BooleanParser extends ParameterParser<Boolean> { 658 659 @Override 660 protected String getType() { 661 return "boolean"; 662 } 663 664 @Override 665 protected Boolean doParse(String parameter) throws NumberFormatException { 666 return (parameter.equalsIgnoreCase("true") || parameter.equalsIgnoreCase("on") || 667 parameter.equalsIgnoreCase("yes") || parameter.equals("1")); 668 } 669 670 public boolean parseBoolean(String name, String parameter) throws PortletRequestBindingException { 671 return parse(name, parameter); 672 } 673 674 public boolean[] parseBooleans(String name, String[] values) throws PortletRequestBindingException { 675 validateRequiredParameter(name, values); 676 boolean[] parameters = new boolean[values.length]; 677 for (int i = 0; i < values.length; i++) { 678 parameters[i] = parseBoolean(name, values[i]); 679 } 680 return parameters; 681 } 682 } 683 684 685 private static class StringParser extends ParameterParser<String> { 686 687 @Override 688 protected String getType() { 689 return "string"; 690 } 691 692 @Override 693 protected String doParse(String parameter) throws NumberFormatException { 694 return parameter; 695 } 696 697 public String validateRequiredString(String name, String value) throws PortletRequestBindingException { 698 validateRequiredParameter(name, value); 699 return value; 700 } 701 702 public String[] validateRequiredStrings(String name, String[] values) throws PortletRequestBindingException { 703 validateRequiredParameter(name, values); 704 for (String value : values) { 705 validateRequiredParameter(name, value); 706 } 707 return values; 708 } 709 } 710 711}