Changeset 3937
- Timestamp:
- Nov 2, 2010, 12:46:02 PM (13 years ago)
- Location:
- trunk/client/servlet/src/org/proteios
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/servlet/src/org/proteios/action/ProteiosAction.java
r3918 r3937 1 1 /* 2 $Id$3 4 Copyright (C) 2006 Gregory Vincic5 Copyright (C) 2007 Gregory Vincic, Olle Mansson6 7 Files are copyright by their respective authors. The contributions to8 files where copyright is not explicitly stated can be traced with the9 source code revision system.10 11 This file is part of Proteios.12 Available at http://www.proteios.org/13 14 Proteios-2.x is free software; you can redistribute it and/or15 modify it under the terms of the GNU General Public License16 as published by the Free Software Foundation; either version 217 of the License, or (at your option) any later version.18 19 Proteios is distributed in the hope that it will be useful,20 but WITHOUT ANY WARRANTY; without even the implied warranty of21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the22 GNU General Public License for more details.23 24 You should have received a copy of the GNU General Public License25 along with this program; if not, write to the Free Software26 Foundation, Inc., 59 Temple Place - Suite 330,27 Boston, MA 02111-1307, USA.28 2 $Id$ 3 4 Copyright (C) 2006 Gregory Vincic 5 Copyright (C) 2007 Gregory Vincic, Olle Mansson 6 7 Files are copyright by their respective authors. The contributions to 8 files where copyright is not explicitly stated can be traced with the 9 source code revision system. 10 11 This file is part of Proteios. 12 Available at http://www.proteios.org/ 13 14 Proteios-2.x is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License 16 as published by the Free Software Foundation; either version 2 17 of the License, or (at your option) any later version. 18 19 Proteios is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 GNU General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place - Suite 330, 27 Boston, MA 02111-1307, USA. 28 */ 29 29 package org.proteios.action; 30 30 31 import java.text.ParseException; 32 import java.util.ArrayList; 33 import java.util.Date; 34 import java.util.Enumeration; 35 import java.util.HashMap; 36 import java.util.Iterator; 37 import java.util.List; 38 import javax.servlet.http.HttpServletRequest; 31 39 import org.apache.log4j.Level; 32 40 import org.proteios.AbstractLink; … … 35 43 import org.proteios.Localizer; 36 44 import org.proteios.Registry; 45 import org.proteios.action.execute.ViewLoginForm; 37 46 import org.proteios.action.read.PermissionDeniedView; 38 import org.proteios.action.execute.ViewLoginForm;39 47 import org.proteios.core.BaseException; 40 48 import org.proteios.core.ClassMetadataExposed; … … 54 62 import org.proteios.gui.GUIFactory; 55 63 import org.proteios.gui.GUIParameterValidator; 56 import org.proteios.gui.form.Form; 57 import org.proteios.gui.form.FormFactory; 64 import org.proteios.gui.form.*; 58 65 import org.proteios.gui.layout.LayoutFactory; 59 66 import org.proteios.gui.layout.RowLayout; … … 62 69 import org.proteios.gui.table.Row; 63 70 import org.proteios.gui.table.Table; 71 import org.proteios.gui.table.TableFactory2; 64 72 import org.proteios.gui.table.TableFactory; 65 import org.proteios.gui.table.TableFactory2;66 67 73 import se.lu.thep.waf.AbstractAction; 68 74 import se.lu.thep.waf.ActionException; 75 import se.lu.thep.waf.Event.State; 69 76 import se.lu.thep.waf.Event; 70 77 import se.lu.thep.waf.Layout; 71 import se.lu.thep.waf.Event.State;72 78 import se.lu.thep.waf.constraints.InvalidParameterValue; 73 79 import se.lu.thep.waf.constraints.ParameterValidator2; … … 80 86 import se.lu.thep.waf.constraints.VString; 81 87 82 import java.text.ParseException;83 import java.util.ArrayList;84 import java.util.Date;85 import java.util.Enumeration;86 import java.util.HashMap;87 import java.util.List;88 89 88 /** 90 *This class should be used as the super class of all proteios actions. The91 *{@link org.proteios.action.ActionFactory} is responsible for initiating this92 *class properly. Subclasses should implement {@link #runMe()}. Use the93 *{@link #setForwardTo(Class)} method to chain actions together.94 *<p>95 *More information about exception handling is found at {@link #runMe()}.96 *</p>97 *98 *@author gregory99 89 This class should be used as the super class of all proteios actions. The 90 {@link org.proteios.action.ActionFactory} is responsible for initiating this 91 class properly. Subclasses should implement {@link #runMe()}. Use the 92 {@link #setForwardTo(Class)} method to chain actions together. 93 <p> 94 More information about exception handling is found at {@link #runMe()}. 95 </p> 96 97 @author gregory 98 */ 100 99 public abstract class ProteiosAction<E extends ProteiosAction<?>> 101 102 100 extends AbstractAction 101 implements ConvertableElement 103 102 { 104 /** 105 * Logged in user. Disconnected from any DbControl. 106 */ 107 private User owner = null; 108 /** 109 * SessionControl used for this request. 110 */ 111 private SessionControl sc = null; 112 /** 113 * Layout factory responsible for generating layouts. 114 */ 115 private LayoutFactory layoutFactory = null; 116 /** 117 * The ActionFactory responsible for this action. 118 */ 119 private ActionFactory actionFactory = null; 120 /** 121 * GUIFactory used in this application to generate various forms of 122 * GUIElements. 123 */ 124 private GUIFactory guiFactory = null; 125 /** 126 * FormFactory used to generate forms used in this application. 127 */ 128 private FormFactory formFactory = null; 129 /** 130 * Validator used to validate input from the gui in each request. 131 */ 132 private GUIParameterValidator validator = null; 133 /** 134 * QueryFactory used to build queries 135 */ 136 private QueryFactory queryFactory = null; 137 /** 138 * ItemFactory used to create new items 139 */ 140 private ItemFactory itemFactory = null; 141 /** 142 * TableFactory used to create graphical tables 143 */ 144 private TableFactory tableFactory = null; 145 /** 146 * Current language used 147 */ 148 private Localizer locale = null; 149 /** 150 * The registry that contains information related to context. 151 */ 152 private Registry registry = null; 153 /** 154 * True if the previous called action failed with an InvalidParameterValue 155 */ 156 private Boolean previousActionFailed = false; 157 /** 158 * Tool for converting a string into a specific type 159 */ 160 private StringConverter convert = null; 161 /** 162 * Tool for validating values against their constraints 163 */ 164 private ParameterValidator2 paramValidator = null; 165 /** 166 * Factory for creating tables 167 */ 168 private TableFactory2 tableFactory2 = null; 169 /** 170 * Tool for throwing exceptions with standardized messages. 171 */ 172 protected ExceptionThrower throwException = null; 173 174 175 public ItemFactory getItemFactory() 176 { 177 return itemFactory; 178 } 179 180 181 public ItemFactory getItemFactory(DbControl dc) 182 { 183 itemFactory.setDc(dc); 184 return itemFactory; 185 } 186 187 188 public void setItemFactory(ItemFactory itemFactory) 189 { 190 this.itemFactory = itemFactory; 191 } 192 193 194 public GUIParameterValidator getValidator() 195 { 196 return validator; 197 } 198 199 200 void setValidator(GUIParameterValidator validator) 201 { 202 this.validator = validator; 203 } 204 205 206 public FormFactory getFormFactory() 207 { 208 return formFactory; 209 } 210 211 212 void setFormFactory(FormFactory formFactory) 213 { 214 this.formFactory = formFactory; 215 } 216 217 218 public GUIFactory getGuiFactory() 219 { 220 return this.guiFactory; 221 } 222 223 224 void setGuiFactory(GUIFactory guiFactory) 225 { 226 this.guiFactory = guiFactory; 227 } 228 229 230 public LayoutFactory getLayoutFactory() 231 { 232 return layoutFactory; 233 } 234 235 236 void setLayoutFactory(LayoutFactory layoutFactory) 237 { 238 this.layoutFactory = layoutFactory; 239 } 240 241 242 void setSessionControl(SessionControl sc) 243 { 244 if (this.sc == null) 245 this.sc = sc; 246 } 247 248 249 public SessionControl getSessionControl() 250 { 251 return sc; 252 } 253 254 private List<DbControl> dbCache = null; 255 256 257 /** 258 * Convinience method for creating new DbControls 259 * 260 * @return DbControl if session control is not null, otherwize null 261 */ 262 public DbControl newDbControl() 263 { 264 if (sc == null) 265 { 266 log.error("SessionControl was nerver set."); 267 return null; 268 } 269 if (dbCache == null) 270 dbCache = new ArrayList<DbControl>(); 271 DbControl dc = sc.newDbControl(); 272 dbCache.add(dc); 273 return dc; 274 } 275 276 277 protected void close(DbControl dc) 278 { 279 if (dc != null && !dc.isClosed()) 280 dc.close(); 281 } 282 283 284 public User getOwner() 285 { 286 return owner; 287 } 288 289 290 /** 291 * Package private so that only the ActionFactory may set owner. 292 * 293 * @param owner 294 */ 295 void setOwner(User owner) 296 { 297 if (this.owner == null) 298 this.owner = owner; 299 } 300 301 302 @Override 303 public final void init() 304 throws ActionException 305 { 306 super.init(); 307 String cname = this.getClass().getName(); 308 if (actionId == null) 309 throw new ActionException( 310 "actionId must be set in AbstractCoreAction. Make sure your ActionFactory initiated '" + cname + "' properly."); 311 } 312 313 314 /** 315 * This method executes an action and handles several general exceptions. If 316 * an InvalidParameterValue, PermissionDeniedException or 317 * ItemNotFoundException is thrown and the client is forwarded to the 318 * previous action. BaseExceptions are wrapped in an ActionException. 319 * 320 * @see se.lu.thep.waf.AbstractAction#run() 321 */ 322 @Override 323 public void run() 324 throws ActionException 325 { 326 try 327 { 328 runMe(); 329 if (getForwardTo() == null && getLayout() == null) 330 { 331 log.debug("Action didn't set forwardTo nor a layout"); 332 if(!getResponse().isCommitted()) 333 { 334 log.debug("Action faild, let's try to reuse the last action"); 335 setForwardTo(actionFactory.getLastAction(getEvent())); 336 } 337 } 338 } 339 catch (ItemNotFoundException e) 340 { 341 log.warn(e.getMessage()); 342 setError(e.getMessage()); 343 setForwardTo(actionFactory.getLastAction(getEvent())); 344 } 345 catch (PermissionDeniedException e) 346 { 347 String msg; 348 msg = e.getMessage(); 349 log.warn(msg,e); 350 setError(msg); 351 setForwardTo(PermissionDeniedView.class); 352 } 353 catch (InvalidParameterValue e) 354 { 355 if (log.getLevel() != null && log.getLevel().equals(Level.DEBUG)) 356 { 357 log.debug(e.getMessage(), e); 358 } 359 else 360 { 361 log.debug("e.getParam() = " + e.getParam()); 362 if (e.getParam() != null) 363 { 364 log.warn(e.getMessage() + e.getParam().toString()); 365 } 366 else 367 { 368 log.warn(e.getMessage()); 369 } 370 } 371 if (e.getParam() != null) 372 { 373 setError(e.getParam().getName() + " : " + e.getMessage()); 374 } 375 else 376 { 377 setError(e.getMessage()); 378 } 379 ProteiosAction action = actionFactory.getLastAction(getEvent()); 380 action.previousActionFailed = true; 381 setForwardTo(action); 382 } 383 catch (InvalidDataException e) 384 { 385 setError(e.getMessage()); 386 ProteiosAction action = actionFactory.getLastAction(getEvent()); 387 action.previousActionFailed = true; 388 setForwardTo(action); 389 } 390 catch (DatabaseException e) 391 { 392 // For mysql this should work 393 if (e.getMessage().startsWith("Duplicate entry")) 394 { 395 log.debug(e.getMessage(), e); 396 ClassMetadataExposed meta = e.getMetaData(); 397 log.warn("Error in " + meta.getEntityName()); 398 // Let's try to find out exactly what went wrong 399 String msg = e.getMessage(); 400 String[] words = msg.split(" "); 401 String key = words[words.length - 1]; 402 Integer i = Integer.parseInt(key) - 1; 403 String property = meta.getPropertyNames()[i]; 404 setError("Duplicate '" + property + "'"); 405 // If you make sure that the valid parameters have the same 406 // names as the attributes then our forms get nice error 407 // messages next to the corresponding field 408 setAttribute("error." + property, "Enter a unique value"); 409 } 410 else 411 { 412 setError(e.getMessage()); 413 } 414 setForwardTo(actionFactory.getLastAction(getEvent())); 415 } 416 catch (BaseException e) 417 { 418 clearDbCache(); 419 log.error(e.getMessage(), e); 420 throw new ActionException(e); 421 } 422 finally 423 { 424 clearDbCache(); 425 } 426 } 427 428 429 /** 430 * Actions that extends this ProteiosAction do not need to worry about 431 * closing their connections. They are closed automatically, though closing 432 * them manually does not affect the automatic procedure. Commits must be 433 * made manually if changes are to be saved. 434 */ 435 private void clearDbCache() 436 { 437 if (dbCache != null) 438 { 439 for (DbControl dc : dbCache) 440 { 441 close(dc); 442 } 443 } 444 } 445 446 447 /** 448 * @throws ActionException if something went wrong that shouldn't have 449 * @throws InvalidParameterValue if one or more parameters are invalid. 450 */ 451 protected abstract void runMe() 452 throws ActionException, InvalidParameterValue; 453 454 455 /** 456 * Sets a 'message' attribute in the current request. Used to notify the 457 * user of positive actions. To set an error use setError(message). 458 * 459 * @param message 460 */ 461 protected void setMessage(String message) 462 { 463 getRequest().setAttribute("message", message); 464 } 465 466 467 /** 468 * Sets a 'error' attribute in the current request. Used to notify the user 469 * when something went wrong. E.g. failing to save an item when some form 470 * fields are missing. 471 * 472 * @param error 473 */ 474 protected void setError(String error) 475 { 476 getRequest().setAttribute("error", error); 477 } 478 479 480 /** 481 * Validates a form against the current request. 482 * 483 * @param form to validate 484 * @throws InvalidParameterValue if one or more values in the form are 485 * invalid. 486 */ 487 public void verifyParameters(Form form) 488 throws InvalidParameterValue 489 { 490 boolean isMultipart = this.getEvent().isMultipart(); 491 log.debug("Verifying form [isMultipart=" + isMultipart + "]"); 492 validator.verifyParameters(form, isMultipart); 493 } 494 495 496 public void verifyParameters(VParameter... parameters) 497 throws InvalidParameterValue 498 { 499 validator.verifyParameters(parameters); 500 } 501 502 503 /** 504 * Stores a valid Boolean for this request. 505 * 506 * @param param valid Boolean definition 507 * @param value 508 */ 509 protected final void setAttribute(VBoolean param, Boolean value) 510 { 511 getRequest().setAttribute(param.getName(), value); 512 } 513 514 515 /** 516 * Stores a valid Integer for this request. 517 * 518 * @param param valid Integer definition 519 * @param value 520 */ 521 protected final void setAttribute(VInteger param, Integer value) 522 { 523 getRequest().setAttribute(param.getName(), value); 524 } 525 526 527 /** 528 * Stores a valid Float for this request. 529 * 530 * @param param valid Float definition 531 * @param value 532 */ 533 protected final void setAttribute(VFloat param, Float value) 534 { 535 getRequest().setAttribute(param.getName(), value); 536 } 537 538 539 /** 540 * Stores a valid String for this request. 541 * 542 * @param param valid String definition 543 * @param value 544 */ 545 protected final void setAttribute(VString param, String value) 546 { 547 getRequest().setAttribute(param.getName(), value); 548 } 549 550 551 /** 552 * Stores a valid Date for this request. 553 * 554 * @param param valid Date definition 555 * @param value 556 */ 557 protected final void setAttribute(VDate param, Date value) 558 { 559 getRequest().setAttribute(param.getName(), value); 560 } 561 562 563 /** 564 * Stores an error attribute for this request. Each error is a concatenation 565 * of 'error.' and param.getName() 566 * 567 * @param param where the error occured 568 * @param message on what went wrong 569 */ 570 protected final void setErrorAttribute(VParameter param, String message) 571 { 572 setAttribute("error." + param.getName(), message); 573 } 574 575 576 /** 577 * Stores an error attribute for this request using the message in an 578 * Exception. 579 * 580 * @param param where the error occured 581 * @param e Exception that was thrown 582 */ 583 protected final void setErrorAttribute(VParameter param, Exception e) 584 { 585 setErrorAttribute(param, e.getMessage()); 586 } 587 588 589 /** 590 * Returns a String value from the parameters posted. 591 * 592 * @param param 593 * @return a String value matching the param name or null if none is found. 594 */ 595 protected String getValue(VParameter param) 596 { 597 String value = null; 598 setErrorAttribute(param, ""); 599 if (getEvent().isMultipart()) 600 { 601 HashMap parameters = (HashMap) getRequest().getAttribute( 602 "multipart.parameters"); 603 value = (String) parameters.get(param.getName()); 604 } 605 else 606 { 607 value = getRequest().getParameter(param.getName()); 608 } 609 return value; 610 } 611 612 613 /** 614 * Returnes a String value from the parameters posted. 615 * 616 * @param param valid String definition 617 * @return a String object or null 618 * @throws InvalidParameterValue 619 */ 620 protected String getString(VString param) 621 throws InvalidParameterValue 622 { 623 return getValidString(param); 624 } 625 626 627 /** 628 * Returnes an Float value from the parameters posted. 629 * 630 * @param param valid Float definition 631 * @return a Float object or null 632 * @throws InvalidParameterValue 633 */ 634 protected final Float getFloat(VFloat param) 635 throws InvalidParameterValue 636 { 637 return getValidFloat(param); 638 } 639 640 641 /** 642 * Returnes an Integer value from the parameters posted. 643 * 644 * @param param valid Integer definition 645 * @return a Integer object or null 646 * @throws InvalidParameterValue 647 */ 648 protected final Integer getInteger(VInteger param) 649 throws InvalidParameterValue 650 { 651 return getValidInteger(param); 652 } 653 654 655 /*************************************************************************** 656 * Valid values section 657 */ 658 /** 659 * If there is no valid string value the error is set as an attribute. 660 * 661 * @param param Valid string 662 * @return String if the param is valid, otherwise null 663 * @throws InvalidParameterValue 664 */ 665 protected final String getValidString(VString param) 666 throws InvalidParameterValue 667 { 668 String value = null; 669 String key = param.getName(); 670 // First try to get the attribute 671 Object obj = getRequest().getAttribute(key); 672 try 673 { 674 if (obj != null) 675 value = (String) obj; 676 } 677 catch (ClassCastException e) 678 { 679 throw new InvalidParameterValue( 680 key + " should be String but is " + obj.getClass() 681 .getSimpleName()); 682 } 683 // If no attribute is available try getting a parameter 684 if (value == null) 685 { 686 String str = getValue(param); 687 value = str; 688 } 689 log.debug("String[" + key + "=" + value + "]"); // TODO this will actually output passwords in clear text 690 paramValidator.validate(param, value); 691 setErrorAttribute(param, ""); 692 // Make potentially harmful HTML code inactive by escaping '<' and '>' 693 if (value != null) 694 { 695 value = value.replace("<", "‹"); 696 value = value.replace(">", "›"); 697 } 698 return value; 699 } 700 701 702 /** 703 * @param param specifying a valid date 704 * @return Date obj or null 705 * @throws InvalidParameterValue if constraints are not met 706 */ 707 protected final Date getValidDate(VDate param) 708 throws InvalidParameterValue 709 { 710 Date value = null; 711 String key = param.getName(); 712 // First try to get the attribute 713 Object obj = getRequest().getAttribute(key); 714 try 715 { 716 if (obj != null) 717 value = (Date) obj; 718 } 719 catch (ClassCastException e) 720 { 721 throw new InvalidParameterValue( 722 key + " should be Date but is " + obj.getClass() 723 .getSimpleName()); 724 } 725 // If no attribute is available try getting a parameter 726 if (value == null) 727 { 728 String str = getValue(param); 729 try 730 { 731 /* 732 * Part of the validation is actually done when converting the 733 * string here. 734 */ 735 value = convert.toDate(str, param.getFormats()); 736 } 737 catch (ParseException e) 738 { 739 throw new InvalidParameterValue(e.getMessage()); 740 } 741 } 742 paramValidator.validate(param, value); 743 log.debug("Date[" + key + "=" + value + "]"); 744 return value; 745 } 746 747 748 /** 749 * Returns a valid Boolean according to the VBoolean specification. This 750 * method first checks the request attribute map and then the parameter 751 * list. 752 * 753 * @param param Valid boolean 754 * @return true if param exists, otherwise null 755 * @throws InvalidParameterValue when the value doesn't follow the VBoolean 756 * specification 757 */ 758 protected final Boolean getValidBoolean(VBoolean param) 759 throws InvalidParameterValue 760 { 761 Boolean value = null; 762 String key = param.getName(); 763 Object obj = getRequest().getAttribute(key); 764 try 765 { 766 if (obj != null) 767 value = (Boolean) obj; 768 } 769 catch (ClassCastException e) 770 { 771 throw new InvalidParameterValue( 772 key + " should be Boolean but is " + obj.getClass() 773 .getSimpleName()); 774 } 775 if (value == null) 776 { 777 String str = getValue(param); 778 value = convert.toBoolean(str); 779 } 780 log.debug("Boolean[" + key + "=" + value + "]"); 781 paramValidator.validate(param, value); 782 return value; 783 } 784 785 786 /** 787 * @param param Valid integer 788 * @return Integer if the param is valid, otherwise null 789 * @throws InvalidParameterValue 790 */ 791 protected final Float getValidFloat(VFloat param) 792 throws InvalidParameterValue 793 { 794 Float value = null; 795 String key = param.getName(); 796 Object obj = getRequest().getAttribute(key); 797 try 798 { 799 if (obj != null) 800 value = (Float) obj; 801 } 802 catch (ClassCastException e) 803 { 804 throw new InvalidParameterValue( 805 key + " should be Float but is " + obj.getClass() 806 .getSimpleName()); 807 } 808 if (value == null) 809 { 810 String str = getValue(param); 811 value = convert.toFloat(str); 812 } 813 log.debug("Float[" + key + "=" + value + "]"); 814 paramValidator.validate(param, value); 815 return value; 816 } 817 818 819 /** 820 * @param param Valid integer 821 * @return Integer if the param is valid, otherwise null 822 * @throws InvalidParameterValue 823 */ 824 protected final Integer getValidInteger(VInteger param) 825 throws InvalidParameterValue 826 { 827 Integer value = null; 828 String key = param.getName(); 829 Object obj = getRequest().getAttribute(key); 830 try 831 { 832 if (obj != null) 833 value = (Integer) obj; 834 } 835 catch (ClassCastException e) 836 { 837 throw new InvalidParameterValue( 838 key + " should be Integer but is " + obj.getClass() 839 .getSimpleName() + "[" + obj + "]"); 840 } 841 if (value == null) 842 { 843 String str = getValue(param); 844 value = convert.toInteger(str); 845 } 846 log.debug("Integer[" + key + "=" + value + "]"); 847 paramValidator.validate(param, value); 848 return value; 849 } 850 851 852 protected final ArrayList<Integer> getValidIntegerList(VInteger param) 853 throws InvalidParameterValue 854 { 855 ArrayList<Integer> valid = null; 856 String key = param.getName(); 857 Object obj = getRequest().getAttribute(key); 858 if (obj != null) 859 { 860 ArrayList<?> raw = (ArrayList<?>) obj; 861 valid = new ArrayList<Integer>(raw.size()); 862 for (Object o : raw) 863 { 864 try 865 { 866 Integer tmp = (Integer) o; 867 valid.add(tmp); 868 valid.add(tmp); 869 } 870 catch (ClassCastException e) 871 { 872 throw new InvalidParameterValue( 873 "[" + o + "] is not an Integer. Make sure " + key + " is an ArrayList<Integer>"); 874 } 875 } 876 } 877 if (obj == null) 878 { 879 String[] strings = getRequest().getParameterValues(param.getName()); 880 try 881 { 882 if (strings != null) 883 { 884 valid = new ArrayList<Integer>(); 885 for (String str : strings) 886 { 887 Integer value = convert.toInteger(str); 888 paramValidator.validate(param, value); 889 valid.add(value); 890 } 891 } 892 } 893 catch (InvalidParameterValue e) 894 { 895 log.error(e.getMessage(), e); 896 } 897 } 898 if (valid != null) 899 { 900 for (Integer i : valid) 901 { 902 log.debug("List<Integer>[" + param.getName() + "=" + i + "]"); 903 } 904 } 905 return valid; 906 } 907 908 909 protected final ArrayList<String> getValidStringList(VString param) 910 throws InvalidParameterValue 911 { 912 ArrayList<String> valid = null; 913 String key = param.getName(); 914 Object obj = getRequest().getAttribute(key); 915 if (obj != null) 916 { 917 ArrayList<?> raw = (ArrayList<?>) obj; 918 valid = new ArrayList<String>(raw.size()); 919 for (Object o : raw) 920 { 921 try 922 { 923 String tmp = String.class.cast(o); 924 valid.add(tmp); 925 } 926 catch (ClassCastException e) 927 { 928 throw new InvalidParameterValue( 929 "[" + o + "] is not an String. Make sure " + key + " is an ArrayList<String>"); 930 } 931 } 932 } 933 if (valid == null) 934 { 935 String[] values = getRequest().getParameterValues(param.getName()); 936 try 937 { 938 if (values != null) 939 { 940 valid = new ArrayList<String>(); 941 for (String value : values) 942 { 943 paramValidator.validate(param, value); 944 valid.add(value); 945 } 946 return valid; 947 } 948 } 949 catch (InvalidParameterValue e) 950 { 951 log.error(e.getMessage(), e); 952 } 953 } 954 if (valid != null) { 955 for (String v : valid) 956 { 957 log.debug("List<String>[" + param.getName() + "=" + v + "]"); 958 } 959 } 960 return valid; 961 } 962 963 964 public ActionFactory getActionFactory() 965 { 966 return actionFactory; 967 } 968 969 970 void setActionFactory(ActionFactory actionFactory) 971 { 972 this.actionFactory = actionFactory; 973 } 974 975 976 public <D extends Object> D convert(AbstractGUIConverter<D> converter) 977 { 978 return converter.convert(this, this.getClass()); 979 } 980 981 982 /** 983 * Populates the form with values from current request. Useful if you want 984 * to redisplay the form as it was filled out. 985 * 986 * @param form to populate 987 */ 988 protected final void populateForm(Form form) 989 { 990 formFactory.populateForm(form, getRequest()); 991 } 992 993 994 /** 995 * @return ActionLink to add to history bar. Override this method to add 996 * links to the history bar. 997 */ 998 public AbstractLink getHistoryAction() 999 { 1000 return null; 1001 } 1002 1003 1004 /** 1005 * Forwards this request to the specified action 1006 * 1007 * @param actionClass to forward to 1008 */ 1009 protected final <D extends ProteiosAction<?>> void setForwardTo( 1010 Class<D> actionClass) 1011 { 1012 ProteiosAction action = actionFactory.getAbstractAction(actionClass, 1013 getEvent()); 1014 if (action != null) 1015 super.setForwardTo(action); 1016 } 1017 1018 1019 protected final void setForwardTo(String actionId) 1020 { 1021 ProteiosAction action = actionFactory.getAbstractAction(actionId, 1022 getEvent()); 1023 if (action != null) 1024 super.setForwardTo(action); 1025 } 1026 1027 1028 public void verifySessionAttributes(VParameter... parameters) 1029 throws InvalidParameterValue 1030 { 1031 validator.verifySessionAttributes(parameters); 1032 } 1033 1034 1035 protected final void setSessionAttribute(VParameter param, Object value) 1036 { 1037 super.setSessionAttribute(param.getName(), value); 1038 if (sc != null) 1039 sc.setSessionSetting(param.getName(), value); 1040 } 1041 1042 1043 /** 1044 * @param dc 1045 * @return activ project if any 1046 * @throws ActionException if no active project exists 1047 */ 1048 final protected Project isProjectActive(DbControl dc) 1049 throws ActionException 1050 { 1051 Integer projectId = getSessionControl().getActiveProjectId(); 1052 if (projectId == null) 1053 throw new ActionException("No active project"); 1054 Project project = Project.getById(dc, projectId); 1055 return project; 1056 } 1057 1058 1059 /** 1060 * @param dc 1061 * @return activ project if any 1062 */ 1063 final protected Project getActiveProject(DbControl dc) 1064 { 1065 Integer projectId = getSessionControl().getActiveProjectId(); 1066 if (projectId != null && projectId > 0) 1067 return Project.getById(dc, projectId); 1068 return null; 1069 } 1070 1071 1072 /** 1073 * Used as a convinience method to store validate parameters to session 1074 * 1075 * @param param 1076 * @throws InvalidParameterValue 1077 */ 1078 protected final void saveToSession(VString param) 1079 throws InvalidParameterValue 1080 { 1081 setSessionAttribute(param, getValidString(param)); 1082 } 1083 1084 1085 /** 1086 * Used as a convinience method to store validate parameters to session 1087 * 1088 * @param param 1089 * @throws InvalidParameterValue 1090 */ 1091 protected final void saveToSession(VInteger param) 1092 throws InvalidParameterValue 1093 { 1094 setSessionAttribute(param, getValidInteger(param)); 1095 } 1096 1097 1098 /** 1099 * QueryFactory used in this ProteiosAction. Can only be set once. 1100 */ 1101 public void setQueryFactory(QueryFactory qf) 1102 { 1103 if (this.queryFactory == null) 1104 this.queryFactory = qf; 1105 } 1106 1107 1108 public QueryFactory getQueryFactory() 1109 { 1110 return queryFactory; 1111 } 1112 1113 1114 /** 1115 * TableFactory used in this ProteiosAction. Can only be set once. 1116 */ 1117 public void setTableFactory(TableFactory tableFactory) 1118 { 1119 if (this.tableFactory == null) 1120 this.tableFactory = tableFactory; 1121 } 1122 1123 1124 public TableFactory getTableFactory() 1125 { 1126 return tableFactory; 1127 } 1128 1129 1130 protected TableFactory2 getTableFactory2() 1131 { 1132 return tableFactory2; 1133 } 1134 1135 1136 /** 1137 * Locale used in this ProteiosAction. Can only be set once. 1138 */ 1139 public void setLocale(Localizer locale) 1140 { 1141 if (this.locale == null) 1142 this.locale = locale; 1143 } 1144 1145 1146 public Localizer getLocale() 1147 { 1148 return locale; 1149 } 1150 1151 1152 protected Registry getRegistry() 1153 { 1154 return registry; 1155 } 1156 1157 1158 protected void setRegistry(Registry registry) 1159 { 1160 this.registry = registry; 1161 } 1162 1163 1164 public Boolean getPreviousActionFailed() 1165 { 1166 return previousActionFailed; 1167 } 1168 1169 1170 public <F extends ProteiosAction> ActionLink getActionLink(Class<F> action, 1171 String label) 1172 { 1173 return actionFactory.getActionLink(action, label); 1174 } 1175 1176 // Used for debuging a string. returns "null", "one value" or "[val1, val2, ..., valX]" 103 /** 104 Logged in user. Disconnected from any DbControl. 105 */ 106 private User owner = null; 107 /** 108 SessionControl used for this request. 109 */ 110 private SessionControl sc = null; 111 /** 112 Layout factory responsible for generating layouts. 113 */ 114 private LayoutFactory layoutFactory = null; 115 /** 116 The ActionFactory responsible for this action. 117 */ 118 private ActionFactory actionFactory = null; 119 /** 120 GUIFactory used in this application to generate various forms of 121 GUIElements. 122 */ 123 private GUIFactory guiFactory = null; 124 /** 125 FormFactory used to generate forms used in this application. 126 */ 127 private FormFactory formFactory = null; 128 /** 129 Validator used to validate input from the gui in each request. 130 */ 131 private GUIParameterValidator validator = null; 132 /** 133 QueryFactory used to build queries 134 */ 135 private QueryFactory queryFactory = null; 136 /** 137 ItemFactory used to create new items 138 */ 139 private ItemFactory itemFactory = null; 140 /** 141 TableFactory used to create graphical tables 142 */ 143 private TableFactory tableFactory = null; 144 /** 145 Current language used 146 */ 147 private Localizer locale = null; 148 /** 149 The registry that contains information related to context. 150 */ 151 private Registry registry = null; 152 /** 153 True if the previous called action failed with an InvalidParameterValue 154 */ 155 private Boolean previousActionFailed = false; 156 /** 157 Tool for converting a string into a specific type 158 */ 159 private StringConverter convert = null; 160 /** 161 Tool for validating values against their constraints 162 */ 163 private ParameterValidator2 paramValidator = null; 164 /** 165 Factory for creating tables 166 */ 167 private TableFactory2 tableFactory2 = null; 168 /** 169 Tool for throwing exceptions with standardized messages. 170 */ 171 protected ExceptionThrower throwException = null; 172 173 public ItemFactory getItemFactory() 174 { 175 return itemFactory; 176 } 177 178 public ItemFactory getItemFactory(DbControl dc) 179 { 180 itemFactory.setDc(dc); 181 return itemFactory; 182 } 183 184 public void setItemFactory(ItemFactory itemFactory) 185 { 186 this.itemFactory = itemFactory; 187 } 188 189 public GUIParameterValidator getValidator() 190 { 191 return validator; 192 } 193 194 void setValidator(GUIParameterValidator validator) 195 { 196 this.validator = validator; 197 } 198 199 public FormFactory getFormFactory() 200 { 201 return formFactory; 202 } 203 204 void setFormFactory(FormFactory formFactory) 205 { 206 this.formFactory = formFactory; 207 } 208 209 public GUIFactory getGuiFactory() 210 { 211 return this.guiFactory; 212 } 213 214 void setGuiFactory(GUIFactory guiFactory) 215 { 216 this.guiFactory = guiFactory; 217 } 218 219 public LayoutFactory getLayoutFactory() 220 { 221 return layoutFactory; 222 } 223 224 void setLayoutFactory(LayoutFactory layoutFactory) 225 { 226 this.layoutFactory = layoutFactory; 227 } 228 229 void setSessionControl(SessionControl sc) 230 { 231 if (this.sc == null) 232 this.sc = sc; 233 } 234 235 public SessionControl getSessionControl() 236 { 237 return sc; 238 } 239 240 private List<DbControl> dbCache = null; 241 242 /** 243 Convinience method for creating new DbControls 244 245 @return DbControl if session control is not null, otherwize null 246 */ 247 public DbControl newDbControl() 248 { 249 if (sc == null) 250 { 251 log.error("SessionControl was nerver set."); 252 return null; 253 } 254 if (dbCache == null) 255 dbCache = new ArrayList<DbControl>(); 256 DbControl dc = sc.newDbControl(); 257 dbCache.add(dc); 258 return dc; 259 } 260 261 protected void close(DbControl dc) 262 { 263 if (dc != null && !dc.isClosed()) 264 dc.close(); 265 } 266 267 public User getOwner() 268 { 269 return owner; 270 } 271 272 /** 273 Package private so that only the ActionFactory may set owner. 274 275 @param owner 276 */ 277 void setOwner(User owner) 278 { 279 if (this.owner == null) 280 this.owner = owner; 281 } 282 283 @Override 284 public final void init() 285 throws ActionException 286 { 287 super.init(); 288 String cname = this.getClass().getName(); 289 if (actionId == null) 290 throw new ActionException( 291 "actionId must be set in AbstractCoreAction. Make sure your ActionFactory initiated '" + cname + "' properly."); 292 } 293 294 /** 295 This method executes an action and handles several general exceptions. If 296 an InvalidParameterValue, PermissionDeniedException or 297 ItemNotFoundException is thrown and the client is forwarded to the 298 previous action. BaseExceptions are wrapped in an ActionException. 299 300 @see se.lu.thep.waf.AbstractAction#run() 301 */ 302 @Override 303 public void run() 304 throws ActionException 305 { 306 try 307 { 308 runMe(); 309 if (getForwardTo() == null && getLayout() == null) 310 { 311 log.debug("Action didn't set forwardTo nor a layout"); 312 if(!getResponse().isCommitted()) 313 { 314 log.debug("Action faild, let's try to reuse the last action"); 315 setForwardTo(actionFactory.getLastAction(getEvent())); 316 } 317 } 318 } 319 catch (ItemNotFoundException e) 320 { 321 log.warn(e.getMessage()); 322 setError(e.getMessage()); 323 setForwardTo(actionFactory.getLastAction(getEvent())); 324 } 325 catch (PermissionDeniedException e) 326 { 327 String msg; 328 msg = e.getMessage(); 329 log.warn(msg,e); 330 setError(msg); 331 setForwardTo(PermissionDeniedView.class); 332 } 333 catch (InvalidParameterValue e) 334 { 335 if (log.getLevel() != null && log.getLevel().equals(Level.DEBUG)) 336 { 337 log.debug(e.getMessage(), e); 338 } 339 else 340 { 341 log.debug("e.getParam() = " + e.getParam()); 342 if (e.getParam() != null) 343 { 344 log.warn(e.getMessage() + e.getParam().toString()); 345 } 346 else 347 { 348 log.warn(e.getMessage()); 349 } 350 } 351 if (e.getParam() != null) 352 { 353 setError(e.getParam().getName() + " : " + e.getMessage()); 354 } 355 else 356 { 357 setError(e.getMessage()); 358 } 359 ProteiosAction action = actionFactory.getLastAction(getEvent()); 360 action.previousActionFailed = true; 361 setForwardTo(action); 362 } 363 catch (InvalidDataException e) 364 { 365 setError(e.getMessage()); 366 ProteiosAction action = actionFactory.getLastAction(getEvent()); 367 action.previousActionFailed = true; 368 setForwardTo(action); 369 } 370 catch (DatabaseException e) 371 { 372 // For mysql this should work 373 if (e.getMessage().startsWith("Duplicate entry")) 374 { 375 log.debug(e.getMessage(), e); 376 ClassMetadataExposed meta = e.getMetaData(); 377 log.warn("Error in " + meta.getEntityName()); 378 // Let's try to find out exactly what went wrong 379 String msg = e.getMessage(); 380 String[] words = msg.split(" "); 381 String key = words[words.length - 1]; 382 Integer i = Integer.parseInt(key) - 1; 383 String property = meta.getPropertyNames()[i]; 384 setError("Duplicate '" + property + "'"); 385 // If you make sure that the valid parameters have the same 386 // names as the attributes then our forms get nice error 387 // messages next to the corresponding field 388 setAttribute("error." + property, "Enter a unique value"); 389 } 390 else 391 { 392 setError(e.getMessage()); 393 } 394 setForwardTo(actionFactory.getLastAction(getEvent())); 395 } 396 catch (BaseException e) 397 { 398 clearDbCache(); 399 log.error(e.getMessage(), e); 400 throw new ActionException(e); 401 } 402 finally 403 { 404 clearDbCache(); 405 } 406 } 407 408 /** 409 Actions that extends this ProteiosAction do not need to worry about 410 closing their connections. They are closed automatically, though closing 411 them manually does not affect the automatic procedure. Commits must be 412 made manually if changes are to be saved. 413 */ 414 private void clearDbCache() 415 { 416 if (dbCache != null) 417 { 418 for (DbControl dc : dbCache) 419 { 420 close(dc); 421 } 422 } 423 } 424 425 /** 426 @throws ActionException if something went wrong that shouldn't have 427 @throws InvalidParameterValue if one or more parameters are invalid. 428 */ 429 protected abstract void runMe() 430 throws ActionException, InvalidParameterValue; 431 432 /** 433 Sets a 'message' attribute in the current request. Used to notify the 434 user of positive actions. To set an error use setError(message). 435 436 @param message 437 */ 438 protected void setMessage(String message) 439 { 440 getRequest().setAttribute("message", message); 441 } 442 443 /** 444 Sets a 'error' attribute in the current request. Used to notify the user 445 when something went wrong. E.g. failing to save an item when some form 446 fields are missing. 447 448 @param error 449 */ 450 protected void setError(String error) 451 { 452 getRequest().setAttribute("error", error); 453 } 454 455 /** 456 Validates a form against the current request. 457 458 @param form to validate 459 @throws InvalidParameterValue if one or more values in the form are 460 invalid. 461 */ 462 public void verifyParameters(Form form) 463 throws InvalidParameterValue 464 { 465 boolean isMultipart = this.getEvent().isMultipart(); 466 log.debug("Verifying form [isMultipart=" + isMultipart + "]"); 467 validator.verifyParameters(form, isMultipart); 468 } 469 470 public void verifyParameters(VParameter... parameters) 471 throws InvalidParameterValue 472 { 473 validator.verifyParameters(parameters); 474 } 475 476 /** 477 Stores a valid Boolean for this request. 478 479 @param param valid Boolean definition 480 @param value 481 */ 482 protected final void setAttribute(VBoolean param, Boolean value) 483 { 484 getRequest().setAttribute(param.getName(), value); 485 } 486 487 /** 488 Stores a valid Integer for this request. 489 490 @param param valid Integer definition 491 @param value 492 */ 493 protected final void setAttribute(VInteger param, Integer value) 494 { 495 getRequest().setAttribute(param.getName(), value); 496 } 497 498 /** 499 Stores a valid Float for this request. 500 501 @param param valid Float definition 502 @param value 503 */ 504 protected final void setAttribute(VFloat param, Float value) 505 { 506 getRequest().setAttribute(param.getName(), value); 507 } 508 509 /** 510 Stores a valid String for this request. 511 512 @param param valid String definition 513 @param value 514 */ 515 protected final void setAttribute(VString param, String value) 516 { 517 getRequest().setAttribute(param.getName(), value); 518 } 519 520 /** 521 Stores a valid Date for this request. 522 523 @param param valid Date definition 524 @param value 525 */ 526 protected final void setAttribute(VDate param, Date value) 527 { 528 getRequest().setAttribute(param.getName(), value); 529 } 530 531 /** 532 Stores an error attribute for this request. Each error is a concatenation 533 of 'error.' and param.getName() 534 535 @param param where the error occured 536 @param message on what went wrong 537 */ 538 protected final void setErrorAttribute(VParameter param, String message) 539 { 540 setAttribute("error." + param.getName(), message); 541 } 542 543 /** 544 Stores an error attribute for this request using the message in an 545 Exception. 546 547 @param param where the error occured 548 @param e Exception that was thrown 549 */ 550 protected final void setErrorAttribute(VParameter param, Exception e) 551 { 552 setErrorAttribute(param, e.getMessage()); 553 } 554 555 /** 556 Returns a String value from the parameters posted. 557 558 @param param 559 @return a String value matching the param name or null if none is found. 560 */ 561 protected String getValue(VParameter param) 562 { 563 String value = null; 564 setErrorAttribute(param, ""); 565 if (getEvent().isMultipart()) 566 { 567 HashMap parameters = (HashMap) getRequest().getAttribute( 568 "multipart.parameters"); 569 value = (String) parameters.get(param.getName()); 570 } 571 else 572 { 573 value = getRequest().getParameter(param.getName()); 574 } 575 return value; 576 } 577 578 /** 579 Returnes a String value from the parameters posted. 580 581 @param param valid String definition 582 @return a String object or null 583 @throws InvalidParameterValue 584 */ 585 protected String getString(VString param) 586 throws InvalidParameterValue 587 { 588 return getValidString(param); 589 } 590 591 /** 592 Returnes an Float value from the parameters posted. 593 594 @param param valid Float definition 595 @return a Float object or null 596 @throws InvalidParameterValue 597 */ 598 protected final Float getFloat(VFloat param) 599 throws InvalidParameterValue 600 { 601 return getValidFloat(param); 602 } 603 604 /** 605 Returnes an Integer value from the parameters posted. 606 607 @param param valid Integer definition 608 @return a Integer object or null 609 @throws InvalidParameterValue 610 */ 611 protected final Integer getInteger(VInteger param) 612 throws InvalidParameterValue 613 { 614 return getValidInteger(param); 615 } 616 617 /*************************************************************************** 618 Valid values section 619 */ 620 /** 621 If there is no valid string value the error is set as an attribute. 622 623 @param param Valid string 624 @return String if the param is valid, otherwise null 625 @throws InvalidParameterValue 626 */ 627 protected final String getValidString(VString param) 628 throws InvalidParameterValue 629 { 630 String value = null; 631 String key = param.getName(); 632 // First try to get the attribute 633 Object obj = getRequest().getAttribute(key); 634 try 635 { 636 if (obj != null) 637 value = (String) obj; 638 } 639 catch (ClassCastException e) 640 { 641 throw new InvalidParameterValue( 642 key + " should be String but is " + obj.getClass() 643 .getSimpleName()); 644 } 645 // If no attribute is available try getting a parameter 646 if (value == null) 647 { 648 String str = getValue(param); 649 value = str; 650 } 651 log.debug("String[" + key + "=" + value + "]"); // TODO this will actually output passwords in clear text 652 paramValidator.validate(param, value); 653 setErrorAttribute(param, ""); 654 // Make potentially harmful HTML code inactive by escaping '<' and '>' 655 if (value != null) 656 { 657 value = value.replace("<", "‹"); 658 value = value.replace(">", "›"); 659 } 660 return value; 661 } 662 663 /** 664 @param param specifying a valid date 665 @return Date obj or null 666 @throws InvalidParameterValue if constraints are not met 667 */ 668 protected final Date getValidDate(VDate param) 669 throws InvalidParameterValue 670 { 671 Date value = null; 672 String key = param.getName(); 673 // First try to get the attribute 674 Object obj = getRequest().getAttribute(key); 675 try 676 { 677 if (obj != null) 678 value = (Date) obj; 679 } 680 catch (ClassCastException e) 681 { 682 throw new InvalidParameterValue( 683 key + " should be Date but is " + obj.getClass() 684 .getSimpleName()); 685 } 686 // If no attribute is available try getting a parameter 687 if (value == null) 688 { 689 String str = getValue(param); 690 try 691 { 692 /* 693 Part of the validation is actually done when converting the 694 string here. 695 */ 696 value = convert.toDate(str, param.getFormats()); 697 } 698 catch (ParseException e) 699 { 700 throw new InvalidParameterValue(e.getMessage()); 701 } 702 } 703 paramValidator.validate(param, value); 704 log.debug("Date[" + key + "=" + value + "]"); 705 return value; 706 } 707 708 /** 709 Returns a valid Boolean according to the VBoolean specification. This 710 method first checks the request attribute map and then the parameter 711 list. 712 713 @param param Valid boolean 714 @return true if param exists, otherwise null 715 @throws InvalidParameterValue when the value doesn't follow the VBoolean 716 specification 717 */ 718 protected final Boolean getValidBoolean(VBoolean param) 719 throws InvalidParameterValue 720 { 721 Boolean value = null; 722 String key = param.getName(); 723 Object obj = getRequest().getAttribute(key); 724 try 725 { 726 if (obj != null) 727 value = (Boolean) obj; 728 } 729 catch (ClassCastException e) 730 { 731 throw new InvalidParameterValue( 732 key + " should be Boolean but is " + obj.getClass() 733 .getSimpleName()); 734 } 735 if (value == null) 736 { 737 String str = getValue(param); 738 value = convert.toBoolean(str); 739 } 740 log.debug("Boolean[" + key + "=" + value + "]"); 741 paramValidator.validate(param, value); 742 return value; 743 } 744 745 /** 746 @param param Valid integer 747 @return Integer if the param is valid, otherwise null 748 @throws InvalidParameterValue 749 */ 750 protected final Float getValidFloat(VFloat param) 751 throws InvalidParameterValue 752 { 753 Float value = null; 754 String key = param.getName(); 755 Object obj = getRequest().getAttribute(key); 756 try 757 { 758 if (obj != null) 759 value = (Float) obj; 760 } 761 catch (ClassCastException e) 762 { 763 throw new InvalidParameterValue( 764 key + " should be Float but is " + obj.getClass() 765 .getSimpleName()); 766 } 767 if (value == null) 768 { 769 String str = getValue(param); 770 value = convert.toFloat(str); 771 } 772 log.debug("Float[" + key + "=" + value + "]"); 773 paramValidator.validate(param, value); 774 return value; 775 } 776 777 /** 778 @param param Valid integer 779 @return Integer if the param is valid, otherwise null 780 @throws InvalidParameterValue 781 */ 782 protected final Integer getValidInteger(VInteger param) 783 throws InvalidParameterValue 784 { 785 Integer value = null; 786 String key = param.getName(); 787 Object obj = getRequest().getAttribute(key); 788 try 789 { 790 if (obj != null) 791 value = (Integer) obj; 792 } 793 catch (ClassCastException e) 794 { 795 throw new InvalidParameterValue( 796 key + " should be Integer but is " + obj.getClass() 797 .getSimpleName() + "[" + obj + "]"); 798 } 799 if (value == null) 800 { 801 String str = getValue(param); 802 value = convert.toInteger(str); 803 } 804 log.debug("Integer[" + key + "=" + value + "]"); 805 paramValidator.validate(param, value); 806 return value; 807 } 808 809 protected final ArrayList<Integer> getValidIntegerList(VInteger param) 810 throws InvalidParameterValue 811 { 812 ArrayList<Integer> valid = null; 813 String key = param.getName(); 814 Object obj = getRequest().getAttribute(key); 815 if (obj != null) 816 { 817 ArrayList<?> raw = (ArrayList<?>) obj; 818 valid = new ArrayList<Integer>(raw.size()); 819 for (Object o : raw) 820 { 821 try 822 { 823 Integer tmp = (Integer) o; 824 valid.add(tmp); 825 valid.add(tmp); 826 } 827 catch (ClassCastException e) 828 { 829 throw new InvalidParameterValue( 830 "[" + o + "] is not an Integer. Make sure " + key + " is an ArrayList<Integer>"); 831 } 832 } 833 } 834 if (obj == null) 835 { 836 String[] strings = getRequest().getParameterValues(param.getName()); 837 try 838 { 839 if (strings != null) 840 { 841 valid = new ArrayList<Integer>(); 842 for (String str : strings) 843 { 844 Integer value = convert.toInteger(str); 845 paramValidator.validate(param, value); 846 valid.add(value); 847 } 848 } 849 } 850 catch (InvalidParameterValue e) 851 { 852 log.error(e.getMessage(), e); 853 } 854 } 855 if (valid != null) 856 { 857 for (Integer i : valid) 858 { 859 log.debug("List<Integer>[" + param.getName() + "=" + i + "]"); 860 } 861 } 862 return valid; 863 } 864 865 protected final ArrayList<String> getValidStringList(VString param) 866 throws InvalidParameterValue 867 { 868 ArrayList<String> valid = null; 869 String key = param.getName(); 870 Object obj = getRequest().getAttribute(key); 871 if (obj != null) 872 { 873 ArrayList<?> raw = (ArrayList<?>) obj; 874 valid = new ArrayList<String>(raw.size()); 875 for (Object o : raw) 876 { 877 try 878 { 879 String tmp = String.class.cast(o); 880 valid.add(tmp); 881 } 882 catch (ClassCastException e) 883 { 884 throw new InvalidParameterValue( 885 "[" + o + "] is not an String. Make sure " + key + " is an ArrayList<String>"); 886 } 887 } 888 } 889 if (valid == null) 890 { 891 String[] values = getRequest().getParameterValues(param.getName()); 892 try 893 { 894 if (values != null) 895 { 896 valid = new ArrayList<String>(); 897 for (String value : values) 898 { 899 paramValidator.validate(param, value); 900 valid.add(value); 901 } 902 return valid; 903 } 904 } 905 catch (InvalidParameterValue e) 906 { 907 log.error(e.getMessage(), e); 908 } 909 } 910 if (valid != null) { 911 for (String v : valid) 912 { 913 log.debug("List<String>[" + param.getName() + "=" + v + "]"); 914 } 915 } 916 return valid; 917 } 918 919 public ActionFactory getActionFactory() 920 { 921 return actionFactory; 922 } 923 924 void setActionFactory(ActionFactory actionFactory) 925 { 926 this.actionFactory = actionFactory; 927 } 928 929 public <D extends Object> D convert(AbstractGUIConverter<D> converter) 930 { 931 return converter.convert(this, this.getClass()); 932 } 933 934 /** 935 Populates the form with values from current request. Useful if you want 936 to redisplay the form as it was filled out. 937 938 @param form to populate 939 */ 940 @SuppressWarnings("unchecked") 941 protected final void populateForm(Form form) 942 { 943 HttpServletRequest request = getRequest(); 944 StringConverter convert = new StringConverter(); 945 for (Fieldset fs : form.getFieldsets()) 946 { 947 for (Iterator iter = fs.getFields().iterator(); iter.hasNext();) 948 { 949 Field f = (Field) iter.next(); 950 VParameter param = f.getParam(); 951 String value = null; 952 if (param != null) 953 { 954 value = request.getParameter(param.getName()); 955 if (value == null) 956 { 957 // Try the attributes 958 value = (String) request.getAttribute(param 959 .getName()); 960 } 961 } 962 if (f instanceof TextField) 963 { 964 TextField textField = (TextField) f; 965 if(param instanceof VString) 966 { 967 textField.setValue(value); 968 } 969 else if ( param instanceof VInteger ) 970 { 971 textField.setValue(convert.toInteger(value)); 972 } 973 else if ( param instanceof VFloat ) 974 { 975 textField.setValue(convert.toFloat(value)); 976 } 977 else if ( param instanceof VDate ) 978 { 979 VDate tmp = (VDate) param; 980 try 981 { 982 textField.setValue(convert.toDate(value, tmp.getFormats())); 983 } 984 catch(java.text.ParseException e) 985 { 986 log.debug(e.getMessage()); 987 } 988 } 989 else if ( param instanceof VBoolean ) 990 { 991 textField.setValue(convert.toBoolean(value)); 992 } 993 continue; 994 } 995 if (f instanceof TextArea) 996 { 997 TextArea textArea = (TextArea) f; 998 textArea.setValue(value); 999 continue; 1000 } 1001 if (f instanceof Checkbox) 1002 { 1003 if (value != null && value.equals(((Checkbox) f) 1004 .getValue())) 1005 ((Checkbox) f).isChecked(true); 1006 } 1007 if (f instanceof Select) 1008 { 1009 Select tmp = (Select) f; 1010 List<Option> options = tmp.getOptions(); 1011 for (Option o : options) 1012 { 1013 if (value != null && value.equals(o.getValue())) 1014 { 1015 o.setSelected(true); 1016 break; 1017 } 1018 o.setSelected(false); 1019 } 1020 continue; 1021 } 1022 } 1023 } 1024 } 1025 1026 /** 1027 @return ActionLink to add to history bar. Override this method to add 1028 links to the history bar. 1029 */ 1030 public AbstractLink getHistoryAction() 1031 { 1032 return null; 1033 } 1034 1035 /** 1036 Forwards this request to the specified action 1037 1038 @param actionClass to forward to 1039 */ 1040 protected final <D extends ProteiosAction<?>> void setForwardTo( 1041 Class<D> actionClass) 1042 { 1043 ProteiosAction action = actionFactory.getAbstractAction(actionClass, 1044 getEvent()); 1045 if (action != null) 1046 super.setForwardTo(action); 1047 } 1048 1049 protected final void setForwardTo(String actionId) 1050 { 1051 ProteiosAction action = actionFactory.getAbstractAction(actionId, 1052 getEvent()); 1053 if (action != null) 1054 super.setForwardTo(action); 1055 } 1056 1057 public void verifySessionAttributes(VParameter... parameters) 1058 throws InvalidParameterValue 1059 { 1060 validator.verifySessionAttributes(parameters); 1061 } 1062 1063 protected final void setSessionAttribute(VParameter param, Object value) 1064 { 1065 super.setSessionAttribute(param.getName(), value); 1066 if (sc != null) 1067 sc.setSessionSetting(param.getName(), value); 1068 } 1069 1070 /** 1071 @param dc 1072 @return activ project if any 1073 @throws ActionException if no active project exists 1074 */ 1075 final protected Project isProjectActive(DbControl dc) 1076 throws ActionException 1077 { 1078 Integer projectId = getSessionControl().getActiveProjectId(); 1079 if (projectId == null) 1080 throw new ActionException("No active project"); 1081 Project project = Project.getById(dc, projectId); 1082 return project; 1083 } 1084 1085 /** 1086 @param dc 1087 @return activ project if any 1088 */ 1089 final protected Project getActiveProject(DbControl dc) 1090 { 1091 Integer projectId = getSessionControl().getActiveProjectId(); 1092 if (projectId != null && projectId > 0) 1093 return Project.getById(dc, projectId); 1094 return null; 1095 } 1096 1097 /** 1098 Used as a convinience method to store validate parameters to session 1099 1100 @param param 1101 @throws InvalidParameterValue 1102 */ 1103 protected final void saveToSession(VString param) 1104 throws InvalidParameterValue 1105 { 1106 setSessionAttribute(param, getValidString(param)); 1107 } 1108 1109 /** 1110 Used as a convinience method to store validate parameters to session 1111 1112 @param param 1113 @throws InvalidParameterValue 1114 */ 1115 protected final void saveToSession(VInteger param) 1116 throws InvalidParameterValue 1117 { 1118 setSessionAttribute(param, getValidInteger(param)); 1119 } 1120 1121 /** 1122 QueryFactory used in this ProteiosAction. Can only be set once. 1123 */ 1124 public void setQueryFactory(QueryFactory qf) 1125 { 1126 if (this.queryFactory == null) 1127 this.queryFactory = qf; 1128 } 1129 1130 public QueryFactory getQueryFactory() 1131 { 1132 return queryFactory; 1133 } 1134 1135 /** 1136 TableFactory used in this ProteiosAction. Can only be set once. 1137 */ 1138 public void setTableFactory(TableFactory tableFactory) 1139 { 1140 if (this.tableFactory == null) 1141 this.tableFactory = tableFactory; 1142 } 1143 1144 public TableFactory getTableFactory() 1145 { 1146 return tableFactory; 1147 } 1148 1149 protected TableFactory2 getTableFactory2() 1150 { 1151 return tableFactory2; 1152 } 1153 1154 /** 1155 Locale used in this ProteiosAction. Can only be set once. 1156 */ 1157 public void setLocale(Localizer locale) 1158 { 1159 if (this.locale == null) 1160 this.locale = locale; 1161 } 1162 1163 public Localizer getLocale() 1164 { 1165 return locale; 1166 } 1167 1168 protected Registry getRegistry() 1169 { 1170 return registry; 1171 } 1172 1173 protected void setRegistry(Registry registry) 1174 { 1175 this.registry = registry; 1176 } 1177 1178 public Boolean getPreviousActionFailed() 1179 { 1180 return previousActionFailed; 1181 } 1182 1183 public <F extends ProteiosAction> ActionLink getActionLink(Class<F> action, 1184 String label) 1185 { 1186 return actionFactory.getActionLink(action, label); 1187 } 1188 1189 // Used for debuging a string. returns "null", "one value" or "[val1, val2, ..., valX]" 1177 1190 private String convertToString(String[] values) 1178 { 1179 if(values == null) { return "null"; } 1180 String value = null; 1181 if (values != null && values.length > 1) 1182 { 1183 1184 StringBuilder sb = new StringBuilder(); 1185 sb.append("["); 1186 for (int i = 0; i < values.length; i++) 1187 { 1188 sb.append(values[i]); 1189 if(i<values.length-1) 1190 { 1191 sb.append(","); 1192 } 1193 } 1194 sb.append("]"); 1195 value = sb.toString(); 1196 } else { 1197 value = values[0]; 1198 } 1199 return value; 1200 } 1201 1202 @Override 1203 public Layout getLayout() 1204 { 1205 /* 1206 * If we are in a debug mode lets add some information about this 1207 * request to the layout. Currently we only add debug info if the layout 1208 * is a RowLayout. 1209 */ 1210 Layout layout = super.getLayout(); 1211 Event event = getEvent(); 1212 if (event.getState().equals(State.NO_MORE_ACTIONS)) 1213 { 1214 if (layout instanceof RowLayout) 1215 { 1216 String debugMode = Config.getString("debug.mode"); 1217 if (debugMode != null && debugMode.equals("on")) 1218 { 1219 // Add parameters 1220 Enumeration parameterNames = getRequest() 1221 .getParameterNames(); 1222 Table tbl = new Table("RequestParameters"); 1223 tbl.setTitle("Parameters"); 1224 List<Column> header = new ArrayList<Column>(2); 1225 header.add(new Column<String>("Name")); 1226 header.add(new Column<String>("Value")); 1227 tbl.setHeader(header); 1228 while (parameterNames.hasMoreElements()) 1229 { 1230 String name = (String) parameterNames.nextElement(); 1231 Row row = new Row(""); 1232 Cell<String> nameC = new Cell<String>(name); 1233 row.addCell(nameC); 1234 // HERE 1235 String[] values = getRequest().getParameterValues(name); 1236 String value = convertToString(values); 1237 Cell<String> valueC = new Cell<String>(value); 1238 row.addCell(valueC); 1239 tbl.addRow(row); 1240 } 1241 ((RowLayout) layout).add(tbl); 1242 // Add session attributes 1243 Enumeration attributeNames = getRequest().getSession() 1244 .getAttributeNames(); 1245 Table tbl1 = new Table("SessionAttributes"); 1246 tbl1.setTitle("SessionAttributes"); 1247 tbl1.setHeader(header); 1248 while (attributeNames.hasMoreElements()) 1249 { 1250 String name = (String) attributeNames.nextElement(); 1251 Row row = new Row(""); 1252 Cell<String> nameC = new Cell<String>(name); 1253 row.addCell(nameC); 1254 // 1255 Cell<String> valueC = new Cell<String>(getRequest() 1256 .getSession().getAttribute(name).toString()); 1257 row.addCell(valueC); 1258 tbl1.addRow(row); 1259 } 1260 ((RowLayout) layout).add(tbl1); 1261 // Add attributes 1262 attributeNames = getRequest().getAttributeNames(); 1263 Table tbl2 = new Table("Attributes"); 1264 tbl2.setTitle("Attributes"); 1265 tbl2.setHeader(header); 1266 while (attributeNames.hasMoreElements()) 1267 { 1268 String name = (String) attributeNames.nextElement(); 1269 Row row = new Row(""); 1270 Cell<String> nameC = new Cell<String>(name); 1271 row.addCell(nameC); 1272 // 1273 Cell<String> valueC = new Cell<String>(getRequest() 1274 .getAttribute(name).toString()); 1275 row.addCell(valueC); 1276 tbl2.addRow(row); 1277 } 1278 ((RowLayout) layout).add(tbl2); 1279 } 1280 } 1281 } 1282 return layout; 1283 } 1284 1285 1286 public void setParamValidator(ParameterValidator2 paramValidator) 1287 { 1288 this.paramValidator = paramValidator; 1289 } 1290 1291 1292 public void setPreviousActionFailed(Boolean previousActionFailed) 1293 { 1294 this.previousActionFailed = previousActionFailed; 1295 } 1296 1297 1298 public void setConvert(StringConverter convert) 1299 { 1300 this.convert = convert; 1301 } 1302 1303 1304 public StringConverter getStringConverter() 1305 { 1306 return convert; 1307 } 1308 1309 1310 public ParameterValidator2 getParameterValidator() 1311 { 1312 return paramValidator; 1313 } 1314 1315 1316 public void setTableFactory2(TableFactory2 tableFactory2) 1317 { 1318 this.tableFactory2 = tableFactory2; 1319 } 1320 1321 1322 public void setThrowException(ExceptionThrower throwException) 1323 { 1324 this.throwException = throwException; 1325 } 1326 1327 1328 public ExceptionThrower getThrowException() 1329 { 1330 return throwException; 1331 } 1332 } 1191 { 1192 if(values == null) { return "null"; } 1193 String value = null; 1194 if (values != null && values.length > 1) 1195 { 1196 1197 StringBuilder sb = new StringBuilder(); 1198 sb.append("["); 1199 for (int i = 0; i < values.length; i++) 1200 { 1201 sb.append(values[i]); 1202 if(i<values.length-1) 1203 { 1204 sb.append(","); 1205 } 1206 } 1207 sb.append("]"); 1208 value = sb.toString(); 1209 } else { 1210 value = values[0]; 1211 } 1212 return value; 1213 } 1214 1215 @Override 1216 public Layout getLayout() 1217 { 1218 /* 1219 If we are in a debug mode lets add some information about this 1220 request to the layout. Currently we only add debug info if the layout 1221 is a RowLayout. 1222 */ 1223 Layout layout = super.getLayout(); 1224 Event event = getEvent(); 1225 if (event.getState().equals(State.NO_MORE_ACTIONS)) 1226 { 1227 if (layout instanceof RowLayout) 1228 { 1229 String debugMode = Config.getString("debug.mode"); 1230 if (debugMode != null && debugMode.equals("on")) 1231 { 1232 // Add parameters 1233 Enumeration parameterNames = getRequest() 1234 .getParameterNames(); 1235 Table tbl = new Table("RequestParameters"); 1236 tbl.setTitle("Parameters"); 1237 List<Column> header = new ArrayList<Column>(2); 1238 header.add(new Column<String>("Name")); 1239 header.add(new Column<String>("Value")); 1240 tbl.setHeader(header); 1241 while (parameterNames.hasMoreElements()) 1242 { 1243 String name = (String) parameterNames.nextElement(); 1244 Row row = new Row(""); 1245 Cell<String> nameC = new Cell<String>(name); 1246 row.addCell(nameC); 1247 // HERE 1248 String[] values = getRequest().getParameterValues(name); 1249 String value = convertToString(values); 1250 Cell<String> valueC = new Cell<String>(value); 1251 row.addCell(valueC); 1252 tbl.addRow(row); 1253 } 1254 ((RowLayout) layout).add(tbl); 1255 // Add session attributes 1256 Enumeration attributeNames = getRequest().getSession() 1257 .getAttributeNames(); 1258 Table tbl1 = new Table("SessionAttributes"); 1259 tbl1.setTitle("SessionAttributes"); 1260 tbl1.setHeader(header); 1261 while (attributeNames.hasMoreElements()) 1262 { 1263 String name = (String) attributeNames.nextElement(); 1264 Row row = new Row(""); 1265 Cell<String> nameC = new Cell<String>(name); 1266 row.addCell(nameC); 1267 // 1268 Cell<String> valueC = new Cell<String>(getRequest() 1269 .getSession().getAttribute(name).toString()); 1270 row.addCell(valueC); 1271 tbl1.addRow(row); 1272 } 1273 ((RowLayout) layout).add(tbl1); 1274 // Add attributes 1275 attributeNames = getRequest().getAttributeNames(); 1276 Table tbl2 = new Table("Attributes"); 1277 tbl2.setTitle("Attributes"); 1278 tbl2.setHeader(header); 1279 while (attributeNames.hasMoreElements()) 1280 { 1281 String name = (String) attributeNames.nextElement(); 1282 Row row = new Row(""); 1283 Cell<String> nameC = new Cell<String>(name); 1284 row.addCell(nameC); 1285 // 1286 Cell<String> valueC = new Cell<String>(getRequest() 1287 .getAttribute(name).toString()); 1288 row.addCell(valueC); 1289 tbl2.addRow(row); 1290 } 1291 ((RowLayout) layout).add(tbl2); 1292 } 1293 } 1294 } 1295 return layout; 1296 } 1297 1298 public void setParamValidator(ParameterValidator2 paramValidator) 1299 { 1300 this.paramValidator = paramValidator; 1301 } 1302 1303 public void setPreviousActionFailed(Boolean previousActionFailed) 1304 { 1305 this.previousActionFailed = previousActionFailed; 1306 } 1307 1308 public void setConvert(StringConverter convert) 1309 { 1310 this.convert = convert; 1311 } 1312 1313 public StringConverter getStringConverter() 1314 { 1315 return convert; 1316 } 1317 1318 public ParameterValidator2 getParameterValidator() 1319 { 1320 return paramValidator; 1321 } 1322 1323 public void setTableFactory2(TableFactory2 tableFactory2) 1324 { 1325 this.tableFactory2 = tableFactory2; 1326 } 1327 1328 public void setThrowException(ExceptionThrower throwException) 1329 { 1330 this.throwException = throwException; 1331 } 1332 1333 public ExceptionThrower getThrowException() 1334 { 1335 return throwException; 1336 } 1337 } -
trunk/client/servlet/src/org/proteios/gui/form/FormFactory.java
r3936 r3937 454 454 } 455 455 456 @SuppressWarnings("unchecked")457 public void populateForm(Form form, HttpServletRequest request2)458 {459 if (request2 != null)460 {461 for (Fieldset fs : form.getFieldsets())462 {463 for (Iterator iter = fs.getFields().iterator(); iter.hasNext();)464 {465 Field f = (Field) iter.next();466 VParameter param = f.getParam();467 String value = null;468 if (param != null)469 {470 value = request.getParameter(param.getName());471 if (value == null)472 {473 // Try the attributes474 value = (String) request.getAttribute(param475 .getName());476 }477 }478 if (f instanceof TextField)479 {480 TextField<String> textField = (TextField<String>) f;481 // FIXME implement methods to check if field contains482 // String, Float or other483 textField.setValue(value);484 continue;485 }486 if (f instanceof TextArea)487 {488 TextArea textArea = (TextArea) f;489 textArea.setValue(value);490 continue;491 }492 if (f instanceof Checkbox)493 {494 if (value != null && value.equals(((Checkbox) f)495 .getValue()))496 ((Checkbox) f).isChecked(true);497 }498 if (f instanceof Select)499 {500 Select tmp = (Select) f;501 List<Option> options = tmp.getOptions();502 for (Option o : options)503 {504 if (value != null && value.equals(o.getValue()))505 {506 o.setSelected(true);507 break;508 }509 o.setSelected(false);510 }511 continue;512 }513 }514 }515 }516 }517 456 518 457 public <D extends BasicItem<?>, E extends ProteiosAction<?>> Form getAnnotationsForm( … … 1747 1686 outputDirNameF.setLabel("OutputDirectoryName"); 1748 1687 sampleOutputFS.add(outputDirNameF); 1749 //1750 /*1751 Checkbox<VBoolean> overwriteExistingSampleDataCB = new Checkbox<VBoolean>(1752 SpectrumFileSampleDataAdder.VOVERWRITEEXISTINGSAMPLEDATAFLAG);1753 overwriteExistingSampleDataCB.setLabel("OverwriteExistingSampleData");1754 overwriteExistingSampleDataCB.setValue("true");1755 overwriteExistingSampleDataCB.isChecked(true);1756 sampleOutputFS.add(overwriteExistingSampleDataCB);1757 */1758 1688 // 1759 1689 return form;
Note: See TracChangeset
for help on using the changeset viewer.