001 package org.hackystat.projectbrowser.page.trajectory; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 import java.util.Collections; 006 import java.util.Date; 007 import java.util.HashMap; 008 import java.util.List; 009 import java.util.Map; 010 import java.util.logging.Level; 011 import java.util.logging.Logger; 012 013 import org.apache.wicket.Application; 014 import org.apache.wicket.PageParameters; 015 import org.apache.wicket.model.IModel; 016 import org.apache.wicket.model.Model; 017 import org.hackystat.projectbrowser.ProjectBrowserApplication; 018 import org.hackystat.projectbrowser.ProjectBrowserSession; 019 import org.hackystat.projectbrowser.page.trajectory.datapanel.TrajectoryChartDataModel; 020 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 021 import org.hackystat.telemetry.service.client.TelemetryClient; 022 import org.hackystat.telemetry.service.client.TelemetryClientException; 023 import org.hackystat.telemetry.service.resource.chart.jaxb.ParameterDefinition; 024 import org.hackystat.telemetry.service.resource.chart.jaxb.TelemetryChartDefinition; 025 import org.hackystat.telemetry.service.resource.chart.jaxb.TelemetryChartRef; 026 import org.hackystat.telemetry.service.resource.chart.jaxb.Type; 027 import org.hackystat.utilities.logger.HackystatLogger; 028 import org.hackystat.utilities.tstamp.Tstamp; 029 030 /** 031 * Session to hold state for trajectory. 032 * 033 * @author Pavel Senin 034 * @author Shaoxuan Zhang 035 */ 036 public class TrajectorySession implements Serializable { 037 038 /** Support serialization. */ 039 private static final long serialVersionUID = 1L; 040 041 /** The parameter key of selectedProject1. */ 042 public static final String SELECTED_PROJECT1_KEY = "project1"; 043 /** The parameter key of start date of project 1. */ 044 public static final String START_DATE1_KEY = "startdate1"; 045 /** The parameter key of end dateof project 1. */ 046 public static final String END_DATE1_KEY = "enddate1"; 047 048 /** The parameter key of selectedProject1. */ 049 public static final String SELECTED_PROJECT2_KEY = "project2"; 050 /** The parameter key of start date of project 1. */ 051 public static final String START_DATE2_KEY = "startdate2"; 052 /** The parameter key of end dateof project 1. */ 053 public static final String END_DATE2_KEY = "enddate2"; 054 055 /** The parameter key of telemetry. */ 056 public static final String TELEMETRY_KEY = "telemetry"; 057 /** The parameter key of granularity. */ 058 public static final String GRANULARITY_KEY = "granularity"; 059 /** The parameter key of telemetry parameters. */ 060 public static final String TELEMETRY_PARAMERTERS_KEY = "param"; 061 062 /** The separator for parameter values. */ 063 public static final String PARAMETER_VALUE_SEPARATOR = ","; 064 /** The separator between project name and its onwer. */ 065 public static final String PROJECT_NAME_OWNER_SEPARATR = "-"; 066 067 /** The project #1 this user has selected. */ 068 private ProjectRecord selectedProject1 = new ProjectRecord(); 069 // /** The start date this user has selected. */ 070 // private long project1StartDate = ProjectBrowserBasePage.getDateBefore(7).getTime(); 071 // /** The end date this user has selected. */ 072 // private long project1EndDate = ProjectBrowserBasePage.getDateBefore(1).getTime(); 073 074 /** The project #2 this user has selected. */ 075 private ProjectRecord selectedProject2 = new ProjectRecord(); 076 // /** The start date this user has selected. */ 077 // private long project2StartDate = ProjectBrowserBasePage.getDateBefore(7).getTime(); 078 // /** The end date this user has selected. */ 079 // private long project2EndDate = ProjectBrowserBasePage.getDateBefore(1).getTime(); 080 081 /** The analysis this user has selected. */ 082 private String telemetryName = null; 083 /** The descriptions for all telemetries. */ 084 private final Map<String, TelemetryChartDefinition> telemetrys 085 = new HashMap<String, TelemetryChartDefinition>(); 086 /** The granularity of the chart. Either Day, Week, or Month. */ 087 private String granularity = "Day"; 088 /** The available granularities. */ 089 private final List<String> granularityList = new ArrayList<String>(); 090 /** the feedback string. */ 091 private String feedback = ""; 092 /** The parameters for telemetry chart. */ 093 private List<IModel> parameters = new ArrayList<IModel>(); 094 /** The data model to hold state for data panel. */ 095 private TrajectoryChartDataModel dataModel = new TrajectoryChartDataModel(); 096 /** Error message when parsing page paramters. */ 097 private String paramErrorMessage = ""; 098 099 /** Since I'm reusing the telemetry code, I'm keeping the way to communicate using list. */ 100 private List<ProjectRecord> projectList = null; 101 102 private String dtwWindowType; 103 104 private String dtwStep; 105 106 private String dtwOpenEndType; 107 108 private Integer dtwWindowSize; 109 110 // Some string constants used while logging 111 // 112 private static final String SP = " "; 113 private static final String CR = "\n"; 114 private static final String IDNT = " "; 115 private static final String IDNT2 = " "; 116 private static final String MARK = "[DEBUG] "; 117 private static final String ERROR_URL_PARAM = "Error URL parameter: project: "; 118 private static final String R_HAND = " > "; 119 120 // making life easy - preselecting the interval dates 121 // 122 private static final String project1StartString = "2008-01-01"; 123 private static final String project1EndString = "2008-01-15"; 124 125 private static final String project2StartString = "2008-03-01"; 126 private static final String project2EndString = "2008-03-15"; 127 128 /** 129 * Constructor - create the session instance. 130 */ 131 public TrajectorySession() { 132 // elevate the logging level here 133 Logger logger = HackystatLogger.getLogger("org.hackystat.projectbrowser", "projectbrowser"); 134 HackystatLogger.setLoggingLevel(logger, "FINER"); 135 136 granularityList.add("Day"); 137 granularityList.add("Week"); 138 granularityList.add("Month"); 139 try { 140 this.selectedProject1.setStartDate(Tstamp.makeTimestamp(project1StartString) 141 .toGregorianCalendar().getTimeInMillis()); 142 this.selectedProject1.setEndDate(Tstamp.makeTimestamp(project1EndString) 143 .toGregorianCalendar().getTimeInMillis()); 144 this.selectedProject2.setStartDate(Tstamp.makeTimestamp(project2StartString) 145 .toGregorianCalendar().getTimeInMillis()); 146 this.selectedProject2.setEndDate(Tstamp.makeTimestamp(project2EndString) 147 .toGregorianCalendar().getTimeInMillis()); 148 } 149 catch (Exception e) { 150 e.printStackTrace(); 151 } 152 } 153 154 /** 155 * Returns the list of Projects associated with this user. 156 * 157 * @return The list of Projects. 158 */ 159 public List<ProjectRecord> getProjectList() { 160 if (this.projectList == null || this.projectList.size() <= 0) { 161 projectList = new ArrayList<ProjectRecord>(); 162 List<Project> projects = ProjectBrowserSession.get().getProjectList(); 163 for (Project p : projects) { 164 ProjectRecord pr = new ProjectRecord(p, 0); 165 projectList.add(pr); 166 } 167 } 168 return projectList; 169 } 170 171 /** 172 * @return the parameters 173 */ 174 public List<IModel> getParameters() { 175 return this.parameters; 176 } 177 178 /** 179 * Returns the list of the parameters in a single String, separated by comma. 180 * 181 * @return a String. 182 */ 183 public String getParametersAsString() { 184 StringBuffer stringBuffer = new StringBuffer(); 185 for (IModel model : this.parameters) { 186 if (model != null) { 187 stringBuffer.append(model.getObject()); 188 stringBuffer.append(PARAMETER_VALUE_SEPARATOR); 189 } 190 } 191 String param = stringBuffer.toString(); 192 if (param.endsWith(PARAMETER_VALUE_SEPARATOR)) { 193 param = param.substring(0, param.length() - 1); 194 } 195 return param; 196 } 197 198 /** 199 * @param feedback the feedback to set 200 */ 201 public void setFeedback(String feedback) { 202 this.feedback = feedback; 203 } 204 205 /** 206 * @return the feedback 207 */ 208 public String getFeedback() { 209 String returnString = this.feedback; 210 this.feedback = ""; 211 return returnString; 212 } 213 214 /** 215 * @param telemetryName the telemetry to set 216 */ 217 public void setTelemetryName(String telemetryName) { 218 this.telemetryName = telemetryName; 219 } 220 221 /** 222 * @return the telemetry 223 */ 224 public String getTelemetryName() { 225 return this.telemetryName; 226 } 227 228 /** 229 * Get the logger. 230 * 231 * @return the logger that associated to this web application. 232 */ 233 private Logger getLogger() { 234 return ((ProjectBrowserApplication) Application.get()).getLogger(); 235 } 236 237 /** 238 * Return the TelemetryList. Returns empty list if no telemetry streams data collected. 239 * 240 * @return the telemetryList 241 */ 242 public List<String> getTelemetryList() { 243 Logger logger = getLogger(); 244 List<String> telemetryList = new ArrayList<String>(); 245 if (this.getTelemetrys().isEmpty()) { 246 TelemetryClient client = ProjectBrowserSession.get().getTelemetryClient(); 247 try { 248 logger.info("Retrieving data for Telemetry chart definitions."); 249 for (TelemetryChartRef chartRef : client.getChartIndex().getTelemetryChartRef()) { 250 getTelemetrys().put(chartRef.getName(), client.getChartDefinition(chartRef.getName())); 251 } 252 logger.info("Finished retrieving data for Telemetry chart definitions."); 253 } 254 catch (TelemetryClientException e) { 255 this.feedback = "Exception when retrieving Telemetry chart definition: " + e.getMessage(); 256 logger.warning("Error when retrieving Telemetry chart definition: " + e.getMessage()); 257 } 258 } 259 telemetryList.addAll(this.getTelemetrys().keySet()); 260 Collections.sort(telemetryList); 261 return telemetryList; 262 } 263 264 /** 265 * Return the list of ParameterDefinition under telemetry type in this session. 266 * 267 * @return list of ParameterDefinition. 268 */ 269 public List<ParameterDefinition> getParameterList() { 270 Logger logger = getLogger(); 271 if (this.telemetryName != null) { 272 TelemetryChartDefinition teleDef = this.getTelemetrys().get(telemetryName); 273 if (teleDef == null) { 274 TelemetryClient client = ProjectBrowserSession.get().getTelemetryClient(); 275 try { 276 logger.info("Retrieving chart definition of telemetry: " + this.telemetryName); 277 teleDef = client.getChartDefinition(this.telemetryName); 278 this.getTelemetrys().put(telemetryName, teleDef); 279 return teleDef.getParameterDefinition(); 280 } 281 catch (TelemetryClientException e) { 282 this.feedback = "Error when retrieving chart definition of telemetry: " 283 + this.telemetryName + ">>" + e.getMessage(); 284 logger.warning("Error when retrieving chart definition of telemetry: " 285 + this.telemetryName + ">>" + e.getMessage()); 286 } 287 } 288 else { 289 return teleDef.getParameterDefinition(); 290 } 291 } 292 return new ArrayList<ParameterDefinition>(); 293 } 294 295 /** 296 * @param startDate the startDate to set 297 */ 298 public void setProject1StartDate(Date startDate) { 299 this.selectedProject1.setStartDate(startDate.getTime()); 300 } 301 302 /** 303 * @return the startDate 304 */ 305 public Date getProject1StartDate() { 306 return new Date(this.selectedProject1.getStartDate().getTime()); 307 } 308 309 /** 310 * @param endDate the endDate to set 311 */ 312 public void setProject1EndDate(Date endDate) { 313 this.selectedProject1.setEndDate(endDate.getTime()); 314 } 315 316 /** 317 * @return the endDate 318 */ 319 public Date getProject1EndDate() { 320 return new Date(this.selectedProject1.getEndDate().getTime()); 321 } 322 323 /** 324 * @param startDate the startDate to set 325 */ 326 public void setProject2StartDate(Date startDate) { 327 this.selectedProject2.setStartDate(startDate.getTime()); 328 } 329 330 /** 331 * @return the startDate 332 */ 333 public Date getProject2StartDate() { 334 return new Date(this.selectedProject2.getStartDate().getTime()); 335 } 336 337 /** 338 * @param endDate the endDate to set 339 */ 340 public void setProject2EndDate(Date endDate) { 341 this.selectedProject2.setEndDate(endDate.getTime()); 342 } 343 344 /** 345 * @return the endDate 346 */ 347 public Date getProject2EndDate() { 348 return new Date(this.selectedProject2.getEndDate().getTime()); 349 } 350 351 /** 352 * Returns the string that represents startDate in standard formatted. e.g. 353 * 2008-08-08T08:08:08+08:00, the +08:00 in the end means the time zone of this time stamp is 354 * +08:00 355 * 356 * @return a String 357 */ 358 public String getFormattedProject1StartDateString() { 359 return Tstamp.makeTimestamp(this.selectedProject1.getStartDate().getTime()).toString(); 360 } 361 362 /** 363 * Returns the string that represents endDate in standard formatted. e.g. 364 * 2008-08-08T08:08:08+08:00, the +08:00 in the end means the time zone of this time stamp is 365 * +08:00 366 * 367 * @return a String 368 */ 369 public String getFormattedProject1EndDateString() { 370 return Tstamp.makeTimestamp(this.selectedProject1.getEndDate().getTime()).toString(); 371 } 372 373 /** 374 * Returns the string that represents startDate in standard formatted. e.g. 375 * 2008-08-08T08:08:08+08:00, the +08:00 in the end means the time zone of this time stamp is 376 * +08:00 377 * 378 * @return a String 379 */ 380 public String getFormattedProject2StartDateString() { 381 return Tstamp.makeTimestamp(this.selectedProject2.getStartDate().getTime()).toString(); 382 } 383 384 /** 385 * Returns the string that represents endDate in standard formatted. e.g. 386 * 2008-08-08T08:08:08+08:00, the +08:00 in the end means the time zone of this time stamp is 387 * +08:00 388 * 389 * @return a String 390 */ 391 public String getFormattedProject2EndDateString() { 392 return Tstamp.makeTimestamp(this.selectedProject2.getEndDate().getTime()).toString(); 393 } 394 395 /** 396 * Set the project1 indent. 397 * 398 * @param project1Indent The indent to set. 399 */ 400 public void setProject1Indent(Integer project1Indent) { 401 this.selectedProject1.setIndent(project1Indent); 402 } 403 404 /** 405 * Get the project1 indent. 406 * 407 * @return The project1 indent. 408 */ 409 public Integer getProject1Indent() { 410 return this.selectedProject1.getIndent(); 411 } 412 413 /** 414 * Set the project2 indent. 415 * 416 * @param project2Indent The indent to set. 417 */ 418 public void setProject2Indent(Integer project2Indent) { 419 this.selectedProject2.setIndent(project2Indent); 420 } 421 422 /** 423 * Get the project2 indent. 424 * 425 * @return The project2 indent. 426 */ 427 public Integer getProject2Indent() { 428 return this.selectedProject2.getIndent(); 429 } 430 431 /** 432 * @param granularity the granularity to set 433 */ 434 public void setGranularity(String granularity) { 435 this.granularity = granularity; 436 } 437 438 /** 439 * @return the granularity 440 */ 441 public String getGranularity() { 442 return granularity; 443 } 444 445 /** 446 * @return the granularityList 447 */ 448 public List<String> getGranularityList() { 449 return granularityList; 450 } 451 452 /** 453 * Update the data model. 454 */ 455 public void updateDataModel() { 456 getLogger().log( 457 Level.FINER, 458 MARK + "TrajectorySession: " + "setting TrajectoryChartDataModel with next parameters:" + 459 460 CR + IDNT + "selectedProject1: " + getSelectedProject1().getProject().getName() + CR + IDNT 461 + IDNT2 + "startDate: " + getProject1StartDate() + CR + IDNT + IDNT2 + "endDate: " 462 + getProject1EndDate() + CR + IDNT + IDNT2 + "indent: " + getProject1Indent() + 463 464 CR + IDNT + "selectedProject2: " + getSelectedProject2().getProject().getName() + CR 465 + IDNT + IDNT2 + "startDate: " + getProject2StartDate() + CR + IDNT + IDNT2 466 + "endDate: " + getProject2EndDate() + CR + IDNT + IDNT2 + "indent: " 467 + getProject2Indent() + 468 469 CR + IDNT + "telemetry: " + telemetryName + CR + IDNT + "granularity: " + granularity 470 + CR + IDNT + "parameters: " + CR + parametersToLog(parameters)); 471 472 this.dataModel.setModel(getSelectedProject1(), getSelectedProject2(), telemetryName, 473 granularity, parameters); 474 Thread thread = new Thread() { 475 @Override 476 public void run() { 477 dataModel.loadData(); 478 } 479 }; 480 thread.start(); 481 } 482 483 /** 484 * Cancel data model's update. 485 */ 486 public void cancelDataUpdate() { 487 getLogger().info( 488 MARK + "TrajectorySession " + this.hashCode() + " cancelling updateDataModel()"); 489 dataModel.cancelDataLoading(); 490 } 491 492 /** 493 * Set the data model. 494 * 495 * @param dataModel the dataModel to set 496 */ 497 public void setDataModel(TrajectoryChartDataModel dataModel) { 498 this.dataModel = dataModel; 499 } 500 501 /** 502 * Get the data model. 503 * 504 * @return the dataModel 505 */ 506 public TrajectoryChartDataModel getDataModel() { 507 return dataModel; 508 } 509 510 /** 511 * Set the project1. 512 * 513 * @param rec the selectedProjects to set 514 */ 515 public void setSelectedProject1(ProjectRecord rec) { 516 this.selectedProject1 = rec; 517 } 518 519 /** 520 * Set the project1. 521 * 522 * @return the project1. 523 */ 524 public ProjectRecord getSelectedProject1() { 525 return selectedProject1; 526 } 527 528 /** 529 * Set the project2. 530 * 531 * @param rec the selectedProjects to set 532 */ 533 public void setSelectedProject2(ProjectRecord rec) { 534 this.selectedProject2 = rec; 535 } 536 537 /** 538 * Set the project2. 539 * 540 * @return the project2. 541 */ 542 public ProjectRecord getSelectedProject2() { 543 return selectedProject2; 544 } 545 546 /** 547 * Returns the list of the selected projects in a single String, separated by comma. 548 * 549 * @return a String. 550 */ 551 public String getSelectedProject1AsString() { 552 if (null == selectedProject1) { 553 return "null"; 554 } 555 else { 556 StringBuffer projectStr = new StringBuffer(); 557 projectStr.append(selectedProject1.getProject().getName()); 558 projectStr.append(PROJECT_NAME_OWNER_SEPARATR); 559 projectStr.append(selectedProject1.getProject().getOwner()); 560 return projectStr.toString(); 561 } 562 } 563 564 /** 565 * Returns the list of the selected projects in a single String, separated by comma. 566 * 567 * @return a String. 568 */ 569 public String getSelectedProject2AsString() { 570 if (null == selectedProject2) { 571 return "null"; 572 } 573 else { 574 StringBuffer projectStr = new StringBuffer(); 575 projectStr.append(selectedProject2.getProject().getName()); 576 projectStr.append(PROJECT_NAME_OWNER_SEPARATR); 577 projectStr.append(selectedProject2.getProject().getOwner()); 578 return projectStr.toString(); 579 } 580 } 581 582 /** 583 * @return the telemetrys 584 */ 585 public Map<String, TelemetryChartDefinition> getTelemetrys() { 586 return telemetrys; 587 } 588 589 /** 590 * @return the list of TelemetryChartDefinition. 591 */ 592 public List<TelemetryChartDefinition> getChartDescriptions() { 593 List<TelemetryChartDefinition> chartDef = new ArrayList<TelemetryChartDefinition>(); 594 for (String telemetryName : this.getTelemetryList()) { 595 chartDef.add(this.telemetrys.get(telemetryName)); 596 } 597 return chartDef; 598 } 599 600 /** 601 * Returns a Project instance that is available to current user and is matched to the given 602 * project name and project owner. 603 * 604 * @param projectName the given project name. 605 * @param projectOwner the given project owner. 606 * @return the Project instance. null if no matching project is found, which may means either the 607 * project name or project owner is null or there is no Project for this user with the 608 * same project name and owner as the given ones. 609 */ 610 public Project getProject(String projectName, String projectOwner) { 611 if (projectName == null || projectOwner == null) { 612 return null; 613 } 614 for (Project project : ProjectBrowserSession.get().getProjectList()) { 615 if (projectName.equals(project.getName()) && projectOwner.equals(project.getOwner())) { 616 return project; 617 } 618 } 619 return null; 620 } 621 622 /** 623 * Reports a list of available DTW steps in this implementation. 624 * 625 * @return the list of steps to use in the display menu. 626 */ 627 public List<String> getAvailableDTWSteps() { 628 List<String> steps = new ArrayList<String>(); 629 steps.add("symmetric1"); 630 steps.add("symmetric2"); 631 steps.add("asymmetric"); 632 Collections.sort(steps); 633 return steps; 634 } 635 636 /** 637 * Set particular DTW step to use in the analysis. 638 * 639 * @param step the step to set. 640 */ 641 public void setDTWStep(String step) { 642 this.dtwStep = step; 643 } 644 645 /** 646 * Get the set step function. 647 * 648 * @return the step function set for analysis. 649 */ 650 public String getDTWStep() { 651 return this.dtwStep; 652 } 653 654 /** 655 * Get the list of available implementations of DTW constraints. 656 * 657 * @return the list of available DTW constraints functions to use in the form menu. 658 */ 659 public List<String> getAvailableWindowTypes() { 660 List<String> windows = new ArrayList<String>(); 661 windows.add("No Window"); 662 windows.add("SakoeChiba"); 663 windows.add("Slanted Band"); 664 windows.add("Itakura Window"); 665 // Collections.sort(windows); 666 return windows; 667 } 668 669 /** 670 * Set the specific constraint function. 671 * 672 * @param constraint the constraint function to set. 673 */ 674 public void setWindowType(String constraint) { 675 this.dtwWindowType = constraint; 676 } 677 678 /** 679 * Get the set constraint function for the DTW analysis. 680 * 681 * @return the set function. 682 */ 683 public String getWindowType() { 684 return this.dtwWindowType; 685 } 686 687 /** 688 * Set the window (band) size for the constraint function. 689 * 690 * @param size the window (band) size. 691 */ 692 public void setWindowSize(Integer size) { 693 this.dtwWindowSize = size; 694 } 695 696 /** 697 * Get the window (band) size for constraint function. 698 * 699 * @return the window size. 700 */ 701 public Integer getWindowSize() { 702 return this.dtwWindowSize; 703 } 704 705 /** 706 * Returns the list of available DTW open-end alignment implementations. 707 * 708 * @return the list of available alignment implementations to use in the form menu. 709 */ 710 public List<String> getAvailableOpenEndTypes() { 711 List<String> openEnds = new ArrayList<String>(); 712 openEnds.add("Open Begin"); 713 openEnds.add("Open End"); 714 // Collections.sort(openEnds); 715 return openEnds; 716 } 717 718 /** 719 * Set the specific opend-end alignment implementation. 720 * 721 * @param openEnd the open-end alignment implementation. 722 */ 723 public void setOpenEndType(String openEnd) { 724 this.dtwOpenEndType = openEnd; 725 } 726 727 /** 728 * Get the open-end alignment set for DTW analysis. 729 * 730 * @return the open-end alignment implementation. 731 */ 732 public String getOpenEndType() { 733 return this.dtwOpenEndType; 734 } 735 736 /** 737 * Load data from URL parameters into this session. 738 * 739 * @param parameters the URL parameters 740 * @return true if all parameters are loaded correctly 741 */ 742 public boolean loadPageParameters(PageParameters parameters) { 743 boolean isLoadSucceed = true; 744 boolean isTelemetryLoaded = false; 745 StringBuffer errorMessage = new StringBuffer(1000); 746 Logger logger = this.getLogger(); 747 748 // load selected projects 749 // 750 if (parameters.containsKey(SELECTED_PROJECT1_KEY)) { 751 String projectString = parameters.getString(SELECTED_PROJECT1_KEY); 752 String[] projectInfo = projectString.split(PROJECT_NAME_OWNER_SEPARATR, 2); 753 if (projectInfo.length < 1) { 754 isLoadSucceed = false; 755 String error = ERROR_URL_PARAM + projectString 756 + " >> project name and owner are missing or not formatted correctly."; 757 logger.warning(error); 758 errorMessage.append(error); 759 errorMessage.append('\n'); 760 } 761 String projectName = projectInfo[0]; 762 String projectOwner = projectInfo[1]; 763 Project project = this.getProject(projectName, projectOwner); 764 if (project == null) { 765 isLoadSucceed = false; 766 String error = ERROR_URL_PARAM + projectString 767 + " >> matching project not found under user: " 768 + ProjectBrowserSession.get().getEmail(); 769 logger.warning(error); 770 errorMessage.append(error); 771 errorMessage.append('\n'); 772 } 773 else { 774 selectedProject1 = new ProjectRecord(project, 0); 775 } 776 } 777 else { 778 isLoadSucceed = false; 779 errorMessage.append("projects key is missing in URL parameters.\n"); 780 } 781 // load start date 782 if (parameters.containsKey(START_DATE1_KEY)) { 783 String startDateString = parameters.getString(START_DATE1_KEY); 784 try { 785 this.selectedProject1.setStartDate(Tstamp.makeTimestamp(startDateString) 786 .toGregorianCalendar().getTimeInMillis()); 787 } 788 catch (Exception e) { 789 isLoadSucceed = false; 790 String error = "Errors when parsing start date from URL parameter: " + startDateString; 791 logger.warning(error + R_HAND + e.getMessage()); 792 errorMessage.append(error); 793 errorMessage.append('\n'); 794 } 795 } 796 else { 797 isLoadSucceed = false; 798 errorMessage.append("startDate key is missing in URL parameters."); 799 } 800 // load end date 801 if (parameters.containsKey(END_DATE1_KEY)) { 802 String endDateString = parameters.getString(END_DATE1_KEY); 803 try { 804 this.selectedProject1.setEndDate(Tstamp.makeTimestamp(endDateString).toGregorianCalendar() 805 .getTimeInMillis()); 806 } 807 catch (Exception e) { 808 isLoadSucceed = false; 809 String error = "Errors when parsing end date from URL parameter: " + endDateString; 810 logger.warning(error + R_HAND + e.getMessage()); 811 errorMessage.append(error); 812 errorMessage.append('\n'); 813 } 814 } 815 else { 816 isLoadSucceed = false; 817 errorMessage.append("endDate key is missing in URL parameters.\n"); 818 } 819 820 // load selected projects 821 // 822 if (parameters.containsKey(SELECTED_PROJECT2_KEY)) { 823 String projectString = parameters.getString(SELECTED_PROJECT2_KEY); 824 String[] projectInfo = projectString.split(PROJECT_NAME_OWNER_SEPARATR, 2); 825 if (projectInfo.length < 1) { 826 isLoadSucceed = false; 827 String error = ERROR_URL_PARAM + projectString 828 + " >> project name and owner are missing or not formatted correctly."; 829 logger.warning(error); 830 errorMessage.append(error); 831 errorMessage.append('\n'); 832 } 833 String projectName = projectInfo[0]; 834 String projectOwner = projectInfo[1]; 835 Project project = this.getProject(projectName, projectOwner); 836 if (project == null) { 837 isLoadSucceed = false; 838 String error = ERROR_URL_PARAM + projectString 839 + " >> matching project not found under user: " 840 + ProjectBrowserSession.get().getEmail(); 841 logger.warning(error); 842 errorMessage.append(error); 843 errorMessage.append('\n'); 844 } 845 else { 846 selectedProject2 = new ProjectRecord(project, 0); 847 } 848 } 849 else { 850 isLoadSucceed = false; 851 errorMessage.append("projects key is missing in URL parameters.\n"); 852 } 853 // load start date 854 if (parameters.containsKey(START_DATE2_KEY)) { 855 String startDateString = parameters.getString(START_DATE2_KEY); 856 try { 857 this.selectedProject2.setStartDate(Tstamp.makeTimestamp(startDateString) 858 .toGregorianCalendar().getTimeInMillis()); 859 } 860 catch (Exception e) { 861 isLoadSucceed = false; 862 String error = "Errors when parsing start date from URL parameter: " + startDateString; 863 logger.warning(error + R_HAND + e.getMessage()); 864 errorMessage.append(error); 865 errorMessage.append('\n'); 866 } 867 } 868 else { 869 isLoadSucceed = false; 870 errorMessage.append("startDate key is missing in URL parameters."); 871 } 872 // load end date 873 if (parameters.containsKey(END_DATE2_KEY)) { 874 String endDateString = parameters.getString(END_DATE2_KEY); 875 try { 876 this.selectedProject2.setEndDate(Tstamp.makeTimestamp(endDateString).toGregorianCalendar() 877 .getTimeInMillis()); 878 } 879 catch (Exception e) { 880 isLoadSucceed = false; 881 String error = "Errors when parsing end date from URL parameter: " + endDateString; 882 logger.warning(error + R_HAND + e.getMessage()); 883 errorMessage.append(error); 884 errorMessage.append('\n'); 885 } 886 } 887 else { 888 isLoadSucceed = false; 889 errorMessage.append("endDate key is missing in URL parameters.\n"); 890 } 891 892 // load telemetry name 893 if (parameters.containsKey(TELEMETRY_KEY)) { 894 String telemetryString = parameters.getString(TELEMETRY_KEY); 895 if (this.getTelemetryList().contains(telemetryString) 896 && telemetryString.equalsIgnoreCase("Build")) { 897 this.setTelemetryName(telemetryString); 898 isTelemetryLoaded = true; 899 } 900 else { 901 isLoadSucceed = false; 902 String error = "Telemetry from URL parameter is unknown: " + telemetryString; 903 logger.warning(error); 904 errorMessage.append(error); 905 errorMessage.append('\n'); 906 } 907 } 908 else { 909 isLoadSucceed = false; 910 errorMessage.append("Telemetry key is missing in URL parameters.\n"); 911 } 912 // load granularity 913 if (parameters.containsKey(GRANULARITY_KEY)) { 914 String granularityString = parameters.getString(GRANULARITY_KEY); 915 if (this.granularityList.contains(granularityString)) { 916 this.setGranularity(granularity); 917 } 918 else { 919 isLoadSucceed = false; 920 String error = "Granularity is not supported: " + granularityString; 921 logger.warning(error); 922 errorMessage.append(error); 923 errorMessage.append('\n'); 924 } 925 } 926 else { 927 isLoadSucceed = false; 928 errorMessage.append("granularity key is missing in URL parameters.\n"); 929 } 930 // load telemetry parameters 931 if (parameters.containsKey(TELEMETRY_PARAMERTERS_KEY)) { 932 String paramString = parameters.getString(TELEMETRY_PARAMERTERS_KEY); 933 String[] paramStringArray = paramString.split(PARAMETER_VALUE_SEPARATOR); 934 this.parameters.clear(); 935 if (isTelemetryLoaded) { 936 List<ParameterDefinition> paramDefList = this.getTelemetrys().get(this.telemetryName) 937 .getParameterDefinition(); 938 if (paramStringArray.length == paramDefList.size()) { 939 for (int i = 0; i < paramStringArray.length; ++i) { 940 if (isValueMatchType(paramStringArray[i], paramDefList.get(i).getType())) { 941 this.parameters.add(new Model(paramStringArray[i])); 942 } 943 else { 944 isLoadSucceed = false; 945 String error = "Telemetry parameter: " + paramStringArray[i] + " is not matched to" 946 + " type: " + paramDefList.get(i).getType().getName(); 947 logger.warning(error); 948 errorMessage.append(error); 949 errorMessage.append('\n'); 950 } 951 } 952 } 953 else { 954 isLoadSucceed = false; 955 String error = "Error in URL parameters: telemetry parameters: " 956 + parameters.getString(TELEMETRY_PARAMERTERS_KEY) + "(" + paramStringArray.length 957 + ") >> number of parameters not matched to definition within telemetry: " 958 + this.telemetryName + "(" + paramDefList.size() + ")"; 959 logger.warning(error); 960 errorMessage.append(error); 961 errorMessage.append('\n'); 962 } 963 } 964 } 965 else { 966 isLoadSucceed = false; 967 errorMessage.append("param key is missing in URL parameters.\n"); 968 } 969 if (errorMessage.length() > 0) { 970 this.paramErrorMessage = errorMessage.toString(); 971 } 972 return isLoadSucceed; 973 } 974 975 /** 976 * Checks if the given value is of the given type. 977 * 978 * @param value the given value. 979 * @param type the given type. 980 * @return true if the value and type are matched. 981 */ 982 private boolean isValueMatchType(String value, Type type) { 983 if ("Enumerated".equals(type.getName())) { 984 return type.getValue().contains(value); 985 } 986 else if ("Boolean".equals(type.getName())) { 987 return "true".equals(value) || "false".equals(value); 988 } 989 else if ("Integer".equals(type.getName())) { 990 try { 991 Integer.valueOf(value); 992 return true; 993 } 994 catch (NumberFormatException e) { 995 return false; 996 } 997 } 998 else if ("Text".equals(type.getName())) { 999 return true; 1000 } 1001 return false; 1002 } 1003 1004 /** 1005 * Returns a PageParameters instance that represents the content of the input form. 1006 * 1007 * @return a PageParameters instance. 1008 */ 1009 public PageParameters getPageParameters() { 1010 PageParameters parameters = new PageParameters(); 1011 1012 parameters.put(SELECTED_PROJECT1_KEY, this.getSelectedProject1AsString()); 1013 parameters.put(SELECTED_PROJECT1_KEY, this.getSelectedProject2AsString()); 1014 parameters.put(START_DATE1_KEY, this.getFormattedProject1StartDateString()); 1015 parameters.put(END_DATE1_KEY, this.getFormattedProject1EndDateString()); 1016 parameters.put(START_DATE2_KEY, this.getFormattedProject2StartDateString()); 1017 parameters.put(END_DATE2_KEY, this.getFormattedProject2EndDateString()); 1018 parameters.put(TELEMETRY_KEY, this.getTelemetryName()); 1019 parameters.put(GRANULARITY_KEY, this.getGranularity()); 1020 parameters.put(TELEMETRY_PARAMERTERS_KEY, this.getParametersAsString()); 1021 return parameters; 1022 } 1023 1024 /** 1025 * @return the paramErrorMessage 1026 */ 1027 public String getParamErrorMessage() { 1028 String temp = this.paramErrorMessage; 1029 this.clearParamErrorMessage(); 1030 return temp; 1031 } 1032 1033 /** 1034 * Clears the paramErrorMessage. 1035 */ 1036 public void clearParamErrorMessage() { 1037 this.paramErrorMessage = ""; 1038 } 1039 1040 /** 1041 * Helps to format parameters list. 1042 * 1043 * @param parameters The parameters list. 1044 * @return formatted parameters log message. 1045 */ 1046 private String parametersToLog(List<IModel> parameters) { 1047 StringBuffer sb = new StringBuffer(500); 1048 for (IModel im : parameters) { 1049 sb.append(IDNT + IDNT2 + im.getClass() + ": " + im.getObject() + CR); 1050 } 1051 return sb.toString(); 1052 } 1053 1054 /** 1055 * {@inheritDoc} 1056 */ 1057 public String toString() { 1058 StringBuffer sb = new StringBuffer(1024); 1059 sb.append("TrajectorySession: " + CR); 1060 sb.append(IDNT + "project1: " + getSelectedProject1AsString() + CR + IDNT 1061 + getFormattedProject1StartDateString() + SP + getFormattedProject1EndDateString() + CR); 1062 sb.append(IDNT + "project2 " + getSelectedProject2AsString() + CR + IDNT 1063 + getFormattedProject2StartDateString() + SP + getFormattedProject2EndDateString() + CR); 1064 sb.append(IDNT + "hash code: " + this.hashCode()); 1065 return sb.toString(); 1066 } 1067 1068 }