1 package org.tigris.scarab.actions; 2 3 48 49 import java.util.ArrayList ; 50 import java.util.HashMap ; 51 import java.util.HashSet ; 52 import java.util.Iterator ; 53 import java.util.List ; 54 import java.util.Map ; 55 import java.util.Set ; 56 import java.util.StringTokenizer ; 57 58 import org.apache.commons.collections.MapIterator; 59 import org.apache.commons.collections.map.LinkedMap; 60 import org.apache.fulcrum.intake.model.Field; 61 import org.apache.fulcrum.intake.model.Group; 62 import org.apache.fulcrum.parser.ParameterParser; 63 import org.apache.turbine.RunData; 64 import org.apache.turbine.TemplateContext; 65 import org.apache.turbine.tool.IntakeTool; 66 import org.tigris.scarab.actions.base.RequireLoginFirstAction; 67 import org.tigris.scarab.attribute.DateAttribute; 68 import org.tigris.scarab.attribute.OptionAttribute; 69 import org.tigris.scarab.attribute.UserAttribute; 70 import org.tigris.scarab.om.ActivitySet; 71 import org.tigris.scarab.om.Attachment; 72 import org.tigris.scarab.om.AttachmentManager; 73 import org.tigris.scarab.om.Attribute; 74 import org.tigris.scarab.om.AttributeValue; 75 import org.tigris.scarab.om.Condition; 76 import org.tigris.scarab.om.Issue; 77 import org.tigris.scarab.om.IssueType; 78 import org.tigris.scarab.om.Module; 79 import org.tigris.scarab.om.RModuleAttribute; 80 import org.tigris.scarab.om.RModuleIssueType; 81 import org.tigris.scarab.om.ScarabUser; 82 import org.tigris.scarab.services.security.ScarabSecurity; 83 import org.tigris.scarab.tools.ScarabLocalizationTool; 84 import org.tigris.scarab.tools.ScarabRequestTool; 85 import org.tigris.scarab.tools.localization.L10NKeySet; 86 import org.tigris.scarab.tools.localization.L10NMessage; 87 import org.tigris.scarab.util.IteratorWithSize; 88 import org.tigris.scarab.util.Log; 89 import org.tigris.scarab.util.ScarabConstants; 90 import org.tigris.scarab.util.word.ComplexQueryException; 91 import org.tigris.scarab.util.word.IssueSearch; 92 import org.tigris.scarab.util.word.IssueSearchFactory; 93 import org.tigris.scarab.util.word.MaxConcurrentSearchException; 94 import org.tigris.scarab.util.word.QueryResult; 95 96 102 public class ReportIssue extends RequireLoginFirstAction 103 { 104 private static final int MAX_RESULTS = 25; 105 106 109 public void doPerform(RunData data, TemplateContext context) 110 throws Exception 111 { 112 doCheckforduplicates(data, context); 113 } 114 115 private boolean checkIssueTypeStatus(RunData data, TemplateContext context) 116 throws Exception 117 { 118 ScarabRequestTool scarabR = getScarabRequestTool(context); 119 Issue issue = scarabR.getReportingIssue(); 120 Module module = issue.getModule(); 121 IssueType issueType = issue.getIssueType(); 122 boolean isValid = module != null && !module.getDeleted() && 123 issueType != null; 124 if (isValid) 125 { 126 RModuleIssueType rmit = module.getRModuleIssueType(issueType); 127 isValid = rmit != null && rmit.getActive(); 128 } 129 130 if (!isValid) 131 { 132 scarabR.setAlertMessage(L10NKeySet.IssueTypeUnavailable); 133 data.setTarget( ((ScarabUser)data.getUser()).getHomePage()); 134 cleanup(data, context); 135 } 136 return isValid; 137 } 138 139 public void doCheckforduplicates(RunData data, TemplateContext context) 140 throws Exception 141 { 142 if (checkIssueTypeStatus(data, context)) 143 { 144 checkForDuplicates(data, context); 145 } 146 } 147 148 public void checkForDuplicates(RunData data, TemplateContext context) 149 throws Exception 150 { 151 ScarabLocalizationTool l10n = getLocalizationTool(context); 152 IntakeTool intake = getIntakeTool(context); 153 ScarabRequestTool scarabR = getScarabRequestTool(context); 154 try 155 { 156 Issue issue = scarabR.getReportingIssue(); 157 LinkedMap avMap = issue.getModuleAttributeValuesMap(); 158 159 if (setAttributeValues(issue, intake, context, avMap)) 162 { 163 searchAndSetTemplate(data, context, 0, MAX_RESULTS, issue, 165 "entry,Wizard3.vm"); 166 } 167 } 168 catch (Exception e) 169 { 170 L10NMessage l10nMessage = new L10NMessage(L10NKeySet.ErrorExceptionMessage,e); 171 scarabR.setAlertMessage(l10nMessage); 172 Log.get().error("Error while checking for duplicates", e); 173 setTarget(data, "entry,Wizard1.vm"); 174 return; 175 } 176 177 data.getParameters() 181 .add(ScarabConstants.HISTORY_SCREEN, "entry,Wizard1.vm"); 182 } 183 184 203 private boolean searchAndSetTemplate(RunData data, 204 TemplateContext context, 205 int threshold, 206 int maxResults, 207 Issue issue, 208 String nextTemplate) 209 throws Exception 210 { 211 List attributeValues = issue.getAttributeValues(); 214 boolean hasSetValues = false; 215 for (Iterator itr = attributeValues.iterator(); 216 itr.hasNext() && !hasSetValues;) 217 { 218 AttributeValue attVal = (AttributeValue) itr.next(); 219 hasSetValues = attVal.isSet(); 220 } 221 if (!hasSetValues) 222 { 223 setTarget(data, nextTemplate); 224 return true; 225 } 226 227 IssueSearch search = null; 229 String template = null; 230 boolean dupThresholdExceeded = false; 231 try 232 { 233 search = IssueSearchFactory.INSTANCE.getInstance( 234 issue, (ScarabUser)data.getUser()); 235 for (Iterator textAVs = search.getTextAttributeValues().iterator(); 237 textAVs.hasNext();) 238 { 239 AttributeValue av = (AttributeValue)textAVs.next(); 240 if (av.getAttribute().getAttributeType().getName().equals("date")) 241 av.setValue(DateAttribute.internalDateFormat(av.getValue(), getLocalizationTool(context).get(L10NKeySet.ShortDatePattern))); 242 String s = av.getValue(); 243 if (s != null && s.length() > 0) 244 { 245 StringTokenizer tokens = new StringTokenizer (s, 246 ScarabConstants.INVALID_SEARCH_CHARACTERS); 247 StringBuffer query = new StringBuffer (s.length() + 10); 248 while (tokens.hasMoreTokens()) 249 { 250 query.append(' '); 251 query.append(tokens.nextToken()); 252 } 253 av.setValue(query.toString().toLowerCase()); 254 } 255 } 256 257 IteratorWithSize queryResults = search.getQueryResults(); 260 dupThresholdExceeded = (queryResults.size() > threshold); 261 if (dupThresholdExceeded) 262 { 263 List matchingIssueIds = new ArrayList (maxResults); 264 for (int i = 0; queryResults.hasNext() && i <= maxResults; i++) 266 { 267 matchingIssueIds.add( 268 ((QueryResult)queryResults.next()).getUniqueId()); 269 } 270 context.put("issueList", matchingIssueIds); 271 template = "entry,Wizard2.vm"; 272 } 273 else 274 { 275 template = nextTemplate; 276 } 277 } 278 catch (MaxConcurrentSearchException e) 279 { 280 getScarabRequestTool(context).setInfoMessage( 281 L10NKeySet.DupeCheckSkippedForLackOfResources); 282 } 283 catch (ComplexQueryException e) 284 { 285 getScarabRequestTool(context).setInfoMessage( 286 L10NKeySet.DupeCheckSkippedBecauseComplexity); 287 } 288 finally 289 { 290 if (search != null) 291 { 292 search.close(); 293 } 294 IssueSearchFactory.INSTANCE.notifyDone(); 295 } 296 297 setTarget(data, template); 298 return dupThresholdExceeded; 299 } 300 301 311 private void setRequiredFlags(Issue issue, IntakeTool intake, 312 LinkedMap avMap, TemplateContext context) 313 throws Exception 314 { 315 if (issue == null) 316 { 317 ScarabLocalizationTool l10n = getLocalizationTool(context); 318 throw new Exception (l10n.get("IssueNoLongerValid")); } 320 Set selectedOptions = new HashSet (); 321 Map conditionallyRequiredFields = new HashMap (); 322 IssueType issueType = issue.getIssueType(); 323 List requiredAttributes = issueType 324 .getRequiredAttributes(issue.getModule()); 325 for (MapIterator iter = avMap.mapIterator(); iter.hasNext();) 326 { 327 AttributeValue aval = (AttributeValue)avMap.get(iter.next()); 328 329 Group group = 330 intake.get("AttributeValue", aval.getQueryKey(), false); 331 if (group != null) 332 { 333 Field field = null; 334 if (aval instanceof OptionAttribute) 335 { 336 field = group.get("OptionId"); 337 Object fieldValue = field.getValue(); 339 if (null != fieldValue) 340 { 341 selectedOptions.add(fieldValue); 342 } 343 } 344 else if (aval instanceof UserAttribute) 345 { 346 field = group.get("UserId"); 347 } 348 else 349 { 350 field = group.get("Value"); 351 } 352 353 357 List conditions = aval.getRModuleAttribute().getConditions(); 358 if (conditions.size() > 0) 359 { 360 for (Iterator it = conditions.iterator(); it.hasNext(); ) 361 { 362 Condition cond = (Condition)it.next(); 363 Integer id = cond.getOptionId(); 364 List fields = (List )conditionallyRequiredFields.get(id); 365 if (fields == null) 366 { 367 fields = new ArrayList (); 368 } 369 fields.add(field); 370 conditionallyRequiredFields.put(id, fields); 371 } 372 } 373 374 for (int j=requiredAttributes.size()-1; j>=0; j--) 375 { 376 if (aval.getAttribute().getPrimaryKey().equals( 377 ((Attribute)requiredAttributes.get(j)).getPrimaryKey()) 378 && !aval.isSet()) 379 { 380 field.setRequired(true); 381 break; 382 } 383 } 384 } 385 } 386 390 for (Iterator requiredIds = conditionallyRequiredFields.keySet().iterator(); requiredIds.hasNext(); ) 391 { 392 Integer attributeId= (Integer )requiredIds.next(); 393 if (selectedOptions.contains(attributeId)) 394 { 395 List fields = (List )conditionallyRequiredFields.get(attributeId); 396 for (Iterator iter = fields.iterator(); iter.hasNext(); ) 397 { 398 Field field = (Field)iter.next(); 399 if (field.getValue().toString().length() == 0) 400 { 401 field.setRequired(true); 402 field.setMessage("ConditionallyRequiredAttribute"); 403 } 404 } 405 } 406 } 407 } 408 409 417 private boolean setAttributeValues(Issue issue, IntakeTool intake, 418 TemplateContext context, 419 LinkedMap avMap) 420 throws Exception 421 { 422 boolean success = false; 423 setRequiredFlags(issue, intake, avMap, context); 425 if (intake.isAllValid()) 426 { 427 for (MapIterator i = avMap.mapIterator();i.hasNext();) 428 { 429 AttributeValue aval = (AttributeValue)avMap.get(i.next()); 430 Group group = 431 intake.get("AttributeValue", aval.getQueryKey(), false); 432 if (group != null) 433 { 434 Field field = group.get(aval instanceof OptionAttribute ? 435 "OptionId" : "Value"); 436 String value = field.toString(); 437 438 if (value != null && value.length() > 0) 439 { 440 group.setProperties(aval); 441 } 442 } 443 } 444 success = true; 445 } 446 else 447 { 448 getScarabRequestTool(context).setAlertMessage(ERROR_MESSAGE); 449 } 450 return success; 451 } 452 453 456 public void doEnterissue(RunData data, TemplateContext context) 457 throws Exception 458 { 459 if (checkIssueTypeStatus(data, context)) 460 { 461 enterIssue(data, context); 462 } 463 } 464 465 468 private void enterIssue(RunData data, TemplateContext context) 469 throws Exception 470 { 471 IntakeTool intake = getIntakeTool(context); 472 ScarabRequestTool scarabR = getScarabRequestTool(context); 473 ScarabLocalizationTool l10n = getLocalizationTool(context); 474 Issue issue = scarabR.getReportingIssue(); 475 ScarabUser user = (ScarabUser)data.getUser(); 476 LinkedMap avMap = issue.getModuleAttributeValuesMap(); 477 478 if (setAttributeValues(issue, intake, context, avMap)) 480 { 481 DateAttribute.convertDateAttributes(issue.getAttributeValues(), getLocalizationTool(context).get("ShortDatePattern")); 482 if (issue.containsMinimumAttributeValues()) 483 { 484 boolean saveIssue = true; 488 Group reasonGroup = intake.get("Attachment", "_1", false); 489 Field reasonField = reasonGroup.get("Data"); 490 if (issue.getDefaultTextAttributeValue() == null) 491 { 492 reasonField.setRequired(true); 493 saveIssue = false; 494 } 495 496 String reasonString = reasonField.toString(); 498 if (reasonString != null && reasonString.length() > 254) 499 { 500 reasonField.setMessage("intake_ReasonMustBeLessThan256Characters"); 501 saveIssue = false; 502 } 503 if (reasonField.isValid() || saveIssue) 506 { 507 HashMap newValues = new HashMap (); 508 List modAttrs = issue.getModule() 509 .getRModuleAttributes(issue.getIssueType(), true, "all"); 510 511 for (int i = 0; i<modAttrs.size(); i++) 518 { 519 Attribute attr = ((RModuleAttribute)modAttrs.get(i)).getAttribute(); 520 String queryKey = "__" + attr.getAttributeId().toString(); 521 Group group = intake.get("AttributeValue", queryKey, false); 522 String newValue = ""; 523 524 if (group != null) 525 { 526 if (attr.isOptionAttribute()) 527 { 528 newValue = group.get("OptionId").toString(); 529 } 530 else 531 { 532 newValue = group.get("Value").toString(); 533 } 534 if (newValue.length() != 0) 535 { 536 newValues.put(attr.getAttributeId(), newValue); 537 } 538 } 539 } 540 541 ActivitySet activitySet = null; 543 Attachment reason = null; 544 try 545 { 546 reason = new Attachment(); 548 reasonField.setProperty(reason); 549 activitySet = issue 550 .setInitialAttributeValues(activitySet, reason, newValues, user); 551 } 552 catch (Exception se) 553 { 554 scarabR.setAlertMessage(l10n.getMessage(se)); 555 return; 556 } 557 558 activitySet = issue.doSaveFileAttachments(activitySet, user); 560 561 int templateCode = data.getParameters() 563 .getInt("template_code", 2); 564 565 int userPref = user.getEnterIssueRedirect(); 568 if (userPref == 0 || userPref != templateCode) 569 { 570 user.setEnterIssueRedirect(templateCode); 571 } 572 doRedirect(data, context, templateCode, issue); 573 574 try 576 { 577 activitySet.sendEmail(issue, "NewIssueNotification.vm"); 578 } 579 catch(Exception e) 580 { 581 L10NMessage l10nMessage = new L10NMessage(L10NKeySet.IssueSavedButEmailError,e); 582 scarabR.setInfoMessage(l10nMessage); 583 } 584 cleanup(data, context); 585 data.getParameters().add("id", issue.getUniqueId().toString()); 586 L10NMessage l10nMessage = 587 new L10NMessage(L10NKeySet.IssueAddedToModule, 588 issue.getUniqueId(), 589 getScarabRequestTool(context).getCurrentModule().getRealName()); 590 scarabR.setConfirmMessage(l10nMessage); 591 } 592 else 593 { 594 scarabR.setAlertMessage(ERROR_MESSAGE); 595 } 596 } 597 else 598 { 599 } 601 } 602 } 603 604 607 public void doAddfile(RunData data, TemplateContext context) 608 throws Exception 609 { 610 IntakeTool intake = getIntakeTool(context); 611 ScarabRequestTool scarabR = getScarabRequestTool(context); 612 Issue issue = scarabR.getReportingIssue(); 613 Attachment attachment = AttachmentManager.getInstance(); 614 Group group = intake.get("Attachment", 615 attachment.getQueryKey(), false); 616 617 ModifyIssue 618 .addFileAttachment(issue, group, attachment, scarabR, data, intake); 619 ScarabLocalizationTool l10n = getLocalizationTool(context); 620 if (scarabR.getAlertMessage() == null) 621 { 622 scarabR.setConfirmMessage(L10NKeySet.FileAdded); 623 } 624 625 LinkedMap avMap = issue.getModuleAttributeValuesMap(); 626 setAttributeValues(issue, intake, context, avMap); 628 doGotowizard3(data, context); 629 } 630 631 634 public void doRemovefile(RunData data, TemplateContext context) 635 throws Exception 636 { 637 ScarabRequestTool scarabR = getScarabRequestTool(context); 638 ScarabLocalizationTool l10n = getLocalizationTool(context); 639 Issue issue = scarabR.getReportingIssue(); 640 ParameterParser params = data.getParameters(); 641 Object [] keys = params.getKeys(); 642 String key; 643 String attachmentIndex; 644 boolean fileDeleted = false; 645 for (int i =0; i<keys.length; i++) 646 { 647 key = keys[i].toString(); 648 if (key.startsWith("file_delete_")) 649 { 650 attachmentIndex = key.substring(12); 651 issue.removeFile(attachmentIndex); 652 fileDeleted = true; 653 } 654 } 655 if (fileDeleted) 656 { 657 scarabR.setConfirmMessage(L10NKeySet.FileDeleted); 658 } 659 else 660 { 661 scarabR.setConfirmMessage(L10NKeySet.NoFilesChanged); 662 } 663 LinkedMap avMap = issue.getModuleAttributeValuesMap(); 664 setAttributeValues(issue, getIntakeTool(context), context, avMap); 666 doGotowizard3(data, context); 667 } 668 669 673 public void doAddcomment(RunData data, TemplateContext context) 674 throws Exception 675 { 676 ScarabLocalizationTool l10n = getLocalizationTool(context); 677 IntakeTool intake = getIntakeTool(context); 678 ScarabRequestTool scarabR = getScarabRequestTool(context); 679 Issue issue = scarabR.getReportingIssue(); 680 if (intake.isAllValid()) 681 { 682 Attachment attachment = new Attachment(); 683 Group group = intake.get("Attachment", 684 attachment.getQueryKey(), false); 685 if (group != null) 686 { 687 List issues = scarabR.getIssues(); 688 if (issues == null || issues.size() == 0) 689 { 690 scarabR.setAlertMessage(L10NKeySet.NoIssuesSelectedToAddComment); 691 searchAndSetTemplate(data, context, 0, MAX_RESULTS, issue, "entry,Wizard2.vm"); 692 return; 693 } 694 ActivitySet activitySet = null; 695 for (Iterator itr = issues.iterator(); itr.hasNext();) 696 { 697 Issue prevIssue = (Issue)itr.next(); 698 attachment = new Attachment(); 700 group.setProperties(attachment); 701 if (attachment.getData() != null 702 && attachment.getData().trim().length() > 0) 703 { 704 activitySet = 705 prevIssue.addComment(activitySet, attachment, 706 (ScarabUser)data.getUser()); 707 try 708 { 709 activitySet.sendEmail(prevIssue); 710 scarabR.setConfirmMessage(L10NKeySet.CommentAdded); 711 } 712 catch(Exception e) 713 { 714 L10NMessage l10nMessage = new L10NMessage(L10NKeySet.CommentAddedButEmailError,e); 715 scarabR.setInfoMessage(l10nMessage); 716 } 717 } 718 else 719 { 720 scarabR.setAlertMessage( 721 L10NKeySet.NoTextInCommentTextArea); 722 searchAndSetTemplate(data, context, 0, MAX_RESULTS, 723 issue, "entry,Wizard2.vm"); 724 return; 725 } 726 } 727 } 728 729 String nextTemplate = 732 ((ScarabUser)data.getUser()).getHomePage(); 733 if (! searchAndSetTemplate(data, context, 1, MAX_RESULTS, issue, nextTemplate)) 734 { 735 cleanup(data, context); 736 } 737 else 738 { 739 intake.remove(group); 740 } 741 return; 742 } 743 else 744 { 745 searchAndSetTemplate(data, context, 0, MAX_RESULTS, issue, "entry,Wizard2.vm"); 748 } 749 } 750 751 797 798 public void doGotowizard3(RunData data, TemplateContext context) 799 throws Exception 800 { 801 setTarget(data, "entry,Wizard3.vm"); 802 } 803 804 public void doUsetemplates(RunData data, TemplateContext context) 805 throws Exception 806 { 807 getIntakeTool(context).removeAll(); 808 String templateId = data.getParameters().getString("select_template_id"); 809 if (templateId != null && templateId.length() > 0) 810 { 811 data.getParameters().add("templateId", templateId); 812 } 813 } 814 815 private void cleanup(RunData data, TemplateContext context) 816 { 817 data.getParameters().remove(ScarabConstants.HISTORY_SCREEN); 818 String issueKey = data.getParameters() 819 .getString(ScarabConstants.REPORTING_ISSUE); 820 ((ScarabUser)data.getUser()).setReportingIssue(issueKey, null); 821 data.getParameters().remove(ScarabConstants.REPORTING_ISSUE); 822 getScarabRequestTool(context).setReportingIssue(null); 823 IntakeTool intake = getIntakeTool(context); 824 intake.removeAll(); 825 } 826 827 830 private void doRedirect(RunData data, TemplateContext context, 831 int templateCode, Issue issue) 832 throws Exception 833 { 834 ScarabUser user = (ScarabUser)data.getUser(); 835 ScarabRequestTool scarabR = getScarabRequestTool(context); 836 ScarabLocalizationTool l10n = getLocalizationTool(context); 837 String template = null; 838 switch (templateCode) 839 { 840 case 1: 841 if (user.hasPermission(ScarabSecurity.ISSUE__ENTER, 842 user.getCurrentModule())) 843 { 844 IssueType issueType = issue.getIssueType(); 845 template = scarabR.getNextEntryTemplate(issueType); 846 data.getParameters().setString( 847 ScarabConstants.CURRENT_ISSUE_TYPE, 848 issueType.getQueryKey()); 849 } 850 else 851 { 852 template = user.getHomePage(); 853 scarabR.setAlertMessage( 854 L10NKeySet.InsufficientPermissionsToEnterIssues); 855 } 856 break; 857 case 2: 858 if (user.hasPermission(ScarabSecurity.ISSUE__ASSIGN, 859 user.getCurrentModule())) 860 { 861 template = "AssignIssue.vm"; 862 data.getParameters().setString(ScarabConstants.CANCEL_TEMPLATE, 863 "ViewIssue.vm"); 864 data.getParameters().add("issue_ids", 865 issue.getUniqueId()); 866 getIntakeTool(context).removeAll(); 869 scarabR.resetAssociatedUsers(); 870 } 871 else 872 { 873 template = user.getHomePage(); 874 scarabR.setAlertMessage( 875 L10NKeySet.InsufficientPermissionsToAssignIssues); 876 } 877 break; 878 case 3: 879 if (user.hasPermission(ScarabSecurity.ISSUE__VIEW, 880 user.getCurrentModule())) 881 { 882 template = "ViewIssue.vm"; 883 data.getParameters() 884 .setString("id",issue.getUniqueId().toString()); 885 } 886 else 887 { 888 template = user.getHomePage(); 889 scarabR.setAlertMessage( 890 L10NKeySet.InsufficientPermissionsToViewIssues); 891 } 892 break; 893 case 4: 894 template = user.getHomePage(); 895 break; 896 case 5: 897 if (user.hasPermission(ScarabSecurity.ISSUE__VIEW, 898 user.getCurrentModule())) 899 { 900 template = "ViewIssue.vm"; 901 data.getParameters() 902 .setString("id",issue.getUniqueId().toString()); 903 data.getParameters() 904 .setString("tab","3"); data.getUser().setTemp(ScarabConstants.TAB_KEY, "3"); 906 } 907 else 908 { 909 template = user.getHomePage(); 910 scarabR.setAlertMessage( 911 L10NKeySet.InsufficientPermissionsToViewIssues); 912 } 913 break; 914 } 915 setTarget(data, template); 916 } 917 918 public void doStart(RunData data, TemplateContext context) 919 throws Exception 920 { 921 cleanOutStaleIssue(data, context); 922 } 923 924 927 static void cleanOutStaleIssue(RunData data, TemplateContext context) 928 throws Exception 929 { 930 String key = data.getParameters() 931 .getString(ScarabConstants.REPORTING_ISSUE); 932 ScarabUser user = (ScarabUser)data.getUser(); 933 if (key != null) 934 { 935 data.getParameters().remove(ScarabConstants.REPORTING_ISSUE); 936 user.setReportingIssue(key, null); 937 } 938 user.setHomePage("home,EnterNew.vm"); 939 } 940 } 941 | Popular Tags |