1 24 package org.ofbiz.content.survey; 25 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.io.StringWriter ; 30 import java.io.Writer ; 31 import java.net.URL ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.LinkedList ; 35 import java.util.List ; 36 import java.util.Map ; 37 38 import javolution.util.FastList; 39 import javolution.util.FastMap; 40 import javolution.util.FastSet; 41 42 import org.ofbiz.base.util.Debug; 43 import org.ofbiz.base.util.GeneralException; 44 import org.ofbiz.base.util.UtilMisc; 45 import org.ofbiz.base.util.UtilURL; 46 import org.ofbiz.base.util.UtilValidate; 47 import org.ofbiz.base.util.template.FreeMarkerWorker; 48 import org.ofbiz.entity.GenericDelegator; 49 import org.ofbiz.entity.GenericEntityException; 50 import org.ofbiz.entity.GenericValue; 51 import org.ofbiz.entity.condition.EntityCondition; 52 import org.ofbiz.entity.condition.EntityConditionList; 53 import org.ofbiz.entity.condition.EntityExpr; 54 import org.ofbiz.entity.condition.EntityOperator; 55 import org.ofbiz.entity.transaction.TransactionUtil; 56 import org.ofbiz.entity.util.EntityFindOptions; 57 import org.ofbiz.entity.util.EntityListIterator; 58 import org.ofbiz.entity.util.EntityUtil; 59 60 import freemarker.template.Configuration; 61 import freemarker.template.Template; 62 import freemarker.template.TemplateException; 63 64 71 public class SurveyWrapper { 72 73 public static final String module = SurveyWrapper.class.getName(); 74 75 protected GenericDelegator delegator = null; 76 protected String responseId = null; 77 protected String partyId = null; 78 protected String surveyId = null; 79 protected Map passThru = null; 80 protected boolean edit = false; 81 82 protected SurveyWrapper() {} 83 84 public SurveyWrapper(GenericDelegator delegator, String responseId, String partyId, String surveyId, Map passThru) { 85 this.delegator = delegator; 86 this.responseId = responseId; 87 this.partyId = partyId; 88 this.surveyId = surveyId; 89 if (passThru != null) { 90 this.passThru = new HashMap (passThru); 91 } 92 this.checkParameters(); 93 } 94 95 public SurveyWrapper(GenericDelegator delegator, String surveyId) { 96 this(delegator, null, null, surveyId, null); 97 } 98 99 protected void checkParameters() { 100 if (delegator == null || surveyId == null) { 101 throw new IllegalArgumentException ("Missing one or more required parameters (delegator, surveyId)"); 102 } 103 } 104 105 110 public Writer render(String templatePath) throws SurveyWrapperException { 111 URL templateUrl = UtilURL.fromResource(templatePath); 112 if (templateUrl == null) { 113 String errMsg = "Problem getting the template for Survey from URL: " + templatePath; 114 Debug.logError(errMsg, module); 115 throw new IllegalArgumentException (errMsg); 116 } 117 118 Writer writer = new StringWriter (); 119 this.render(templateUrl, writer); 120 return writer; 121 } 122 123 128 public void render(URL templateUrl, Writer writer) throws SurveyWrapperException { 129 String responseId = this.getThisResponseId(); 130 GenericValue survey = this.getSurvey(); 131 List surveyQuestionAndAppls = this.getSurveyQuestionAndAppls(); 132 Map results = this.getResults(surveyQuestionAndAppls); 133 Map currentAnswers = null; 134 if (responseId != null && canUpdate()) { 135 currentAnswers = this.getResponseAnswers(responseId); 136 } 137 138 Map sqaaWithColIdListByMultiRespId = FastMap.newInstance(); 139 Iterator surveyQuestionAndApplIter = surveyQuestionAndAppls.iterator(); 140 while (surveyQuestionAndApplIter.hasNext()) { 141 GenericValue surveyQuestionAndAppl = (GenericValue) surveyQuestionAndApplIter.next(); 142 String surveyMultiRespColId = surveyQuestionAndAppl.getString("surveyMultiRespColId"); 143 if (UtilValidate.isNotEmpty(surveyMultiRespColId)) { 144 String surveyMultiRespId = surveyQuestionAndAppl.getString("surveyMultiRespId"); 145 List surveyQuestionAndApplList = (List ) sqaaWithColIdListByMultiRespId.get(surveyMultiRespId); 146 if (surveyQuestionAndApplList == null) { 147 surveyQuestionAndApplList = FastList.newInstance(); 148 sqaaWithColIdListByMultiRespId.put(surveyMultiRespId, surveyQuestionAndApplList); 149 } 150 surveyQuestionAndApplList.add(surveyQuestionAndAppl); 151 } 152 } 153 154 Map templateContext = FastMap.newInstance(); 155 FreeMarkerWorker.addAllOfbizTransforms(templateContext); 156 templateContext.put("partyId", partyId); 157 templateContext.put("survey", survey); 158 templateContext.put("surveyResults", results); 159 templateContext.put("surveyQuestionAndAppls", surveyQuestionAndAppls); 160 templateContext.put("sqaaWithColIdListByMultiRespId", sqaaWithColIdListByMultiRespId); 161 templateContext.put("alreadyShownSqaaPkWithColId", FastSet.newInstance()); 162 templateContext.put("surveyAnswers", currentAnswers); 163 templateContext.put("surveyResponseId", responseId); 164 templateContext.put("sequenceSort", UtilMisc.toList("sequenceNum")); 165 templateContext.put("additionalFields", passThru); 166 167 Template template = this.getTemplate(templateUrl); 168 try { 169 template.process(templateContext, writer); 170 } catch (TemplateException e) { 171 Debug.logError(e, "Error rendering Survey with template at [" + templateUrl.toExternalForm() + "]", module); 172 } catch (IOException e) { 173 Debug.logError(e, "Error rendering Survey with template at [" + templateUrl.toExternalForm() + "]", module); 174 } 175 } 176 177 protected Template getTemplate(URL templateUrl) { 179 Configuration config = null; 180 try { 181 config = FreeMarkerWorker.makeDefaultOfbizConfig(); 182 } catch (IOException e) { 183 Debug.logError(e, "Error creating default OFBiz FreeMarker Configuration", module); 184 } catch (TemplateException e) { 185 Debug.logError(e, "Error creating default OFBiz FreeMarker Configuration", module); 186 } 187 188 Template template = null; 189 try { 190 InputStream templateStream = templateUrl.openStream(); 191 InputStreamReader templateReader = new InputStreamReader (templateStream); 192 template = new Template(templateUrl.toExternalForm(), templateReader, config); 193 } catch (IOException e) { 194 Debug.logError(e, "Unable to get template from URL :" + templateUrl.toExternalForm(), module); 195 } 196 return template; 197 } 198 199 public void setEdit(boolean edit) { 200 this.edit = edit; 201 } 202 203 public GenericValue getSurvey() { 205 GenericValue survey = null; 206 try { 207 survey = delegator.findByPrimaryKey("Survey", UtilMisc.toMap("surveyId", surveyId)); 208 } catch (GenericEntityException e) { 209 Debug.logError(e, "Unable to get Survey : " + surveyId, module); 210 } 211 return survey; 212 } 213 214 public String getSurveyName() { 215 GenericValue survey = this.getSurvey(); 216 if (survey != null) { 217 return survey.getString("surveyName"); 218 } 219 return ""; 220 } 221 222 public boolean canUpdate() { 224 if (this.edit) { 225 return true; 226 } 227 228 GenericValue survey = this.getSurvey(); 229 if (!"Y".equals(survey.getString("allowMultiple")) || !"Y".equals(survey.getString("allowUpdate"))) { 230 return false; 231 } 232 return true; 233 } 234 235 public boolean canRespond() { 236 String responseId = this.getThisResponseId(); 237 if (responseId == null) { 238 return true; 239 } else { 240 GenericValue survey = this.getSurvey(); 241 if ("Y".equals(survey.getString("allowMultiple"))) { 242 return true; 243 } 244 } 245 return false; 246 } 247 248 public List getSurveyQuestionAndAppls() { 250 List questions = new LinkedList (); 251 252 try { 253 Map fields = UtilMisc.toMap("surveyId", surveyId); 254 List order = UtilMisc.toList("sequenceNum", "surveyMultiRespColId"); 255 questions = delegator.findByAnd("SurveyQuestionAndAppl", fields, order); 256 if (questions != null) { 257 questions = EntityUtil.filterByDate(questions); 258 } 259 } catch (GenericEntityException e) { 260 Debug.logError(e, "Unable to get questions for survey : " + surveyId, module); 261 } 262 263 return questions; 264 } 265 266 protected String getThisResponseId() { 268 if (responseId != null) { 269 return responseId; 270 } 271 272 if (partyId == null) { 273 return null; 274 } 275 276 String responseId = null; 277 List responses = null; 278 try { 279 responses = delegator.findByAnd("SurveyResponse", UtilMisc.toMap("surveyId", surveyId, "partyId", partyId), UtilMisc.toList("-lastModifiedDate")); 280 } catch (GenericEntityException e) { 281 Debug.logError(e, module); 282 } 283 284 if (responses != null && responses.size() > 0) { 285 GenericValue response = EntityUtil.getFirst(responses); 286 responseId = response.getString("surveyResponseId"); 287 if (responses.size() > 1) { 288 Debug.logWarning("More then one response found for survey : " + surveyId + " by party : " + partyId + " using most current", module); 289 } 290 } 291 292 return responseId; 293 } 294 295 protected void setThisResponseId(String responseId) { 296 this.responseId = responseId; 297 } 298 299 public long getNumberResponses() throws SurveyWrapperException { 300 long responses = 0; 301 try { 302 responses = delegator.findCountByAnd("SurveyResponse", UtilMisc.toMap("surveyId", surveyId)); 303 } catch (GenericEntityException e) { 304 throw new SurveyWrapperException(e); 305 } 306 return responses; 307 } 308 309 public List getSurveyResponses(GenericValue question) throws SurveyWrapperException { 310 List responses = null; 311 try { 312 responses = delegator.findByAnd("SurveyResponse", UtilMisc.toMap("surveyQuestionId", question.getString("surveyQuestionId"))); 313 } catch (GenericEntityException e) { 314 throw new SurveyWrapperException(e); 315 } 316 return responses; 317 } 318 319 public Map getResponseAnswers(String responseId) throws SurveyWrapperException { 321 if (responseId == null) { 322 throw new SurveyWrapperException("Null response ID is not supported at this time"); 323 } 324 325 Map answerMap = new HashMap (); 326 327 if (responseId != null) { 328 List answers = null; 329 try { 330 answers = delegator.findByAnd("SurveyResponseAnswer", UtilMisc.toMap("surveyResponseId", responseId)); 331 } catch (GenericEntityException e) { 332 Debug.logError(e, module); 333 } 334 335 if (answers != null && answers.size() > 0) { 336 Iterator i = answers.iterator(); 337 while (i.hasNext()) { 338 GenericValue answer = (GenericValue) i.next(); 339 answerMap.put(answer.get("surveyQuestionId"), answer); 340 } 341 } 342 } 343 344 if (passThru != null && passThru.size() > 0) { 346 Iterator i = passThru.keySet().iterator(); 347 while (i.hasNext()) { 348 String key = (String ) i.next(); 349 if (key.toUpperCase().startsWith("ANSWERS_")) { 350 int splitIndex = key.indexOf('_'); 351 String questionId = key.substring(splitIndex+1); 352 Map thisAnswer = new HashMap (); 353 String answer = (String ) passThru.remove(key); 354 thisAnswer.put("booleanResponse", answer); 355 thisAnswer.put("currencyResponse", answer); 356 thisAnswer.put("floatResponse", answer); 357 thisAnswer.put("numericResponse", answer); 358 thisAnswer.put("textResponse", answer); 359 thisAnswer.put("surveyOptionSeqId", answer); 360 answerMap.put(questionId, thisAnswer); 362 } 363 } 364 } 365 366 return answerMap; 367 } 368 369 public List getQuestionResponses(GenericValue question, int startIndex, int number) throws SurveyWrapperException { 370 List resp = null; 371 boolean beganTransaction = false; 372 try { 373 beganTransaction = TransactionUtil.begin(); 374 375 EntityListIterator eli = this.getEli(question); 376 if (startIndex > 0 && number > 0) { 377 resp = eli.getPartialList(startIndex, number); 378 } else { 379 resp = eli.getCompleteList(); 380 } 381 382 eli.close(); 383 } catch (GenericEntityException e) { 384 try { 385 TransactionUtil.rollback(beganTransaction, "Error getting survey question responses", e); 387 } catch (GenericEntityException e2) { 388 Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); 389 } 390 391 throw new SurveyWrapperException(e); 392 } finally { 393 try { 394 TransactionUtil.commit(beganTransaction); 396 } catch (GenericEntityException e) { 397 throw new SurveyWrapperException(e); 398 } 400 } 401 return resp; 402 } 403 404 public Map getResults(List questions) throws SurveyWrapperException { 405 Map questionResults = new HashMap (); 406 if (questions != null) { 407 Iterator i = questions.iterator(); 408 while (i.hasNext()) { 409 GenericValue question = (GenericValue) i.next(); 410 Map results = getResultInfo(question); 411 if (results != null) { 412 questionResults.put(question.getString("surveyQuestionId"), results); 413 } 414 } 415 } 416 return questionResults; 417 } 418 419 public Map getResultInfo(GenericValue question) throws SurveyWrapperException { 421 Map resultMap = new HashMap (); 422 423 435 String questionType = question.getString("surveyQuestionTypeId"); 436 resultMap.put("_q_type", questionType); 437 438 if ("OPTION".equals(questionType)) { 441 Map thisResult = getOptionResult(question); 442 if (thisResult != null) { 443 Long questionTotal = (Long ) thisResult.remove("_total"); 444 if (questionTotal == null) questionTotal = new Long (0); 445 resultMap.put("_total", questionTotal); 447 448 Iterator i = thisResult.keySet().iterator(); 450 while (i.hasNext()) { 451 Map optMap = new HashMap (); 452 String optId = (String ) i.next(); 453 Long optTotal = (Long ) thisResult.get(optId); 454 if (optTotal == null) optTotal = new Long (0); 455 Long percent = new Long ((long)(((double)optTotal.longValue() / (double)questionTotal.longValue()) * 100)); 456 optMap.put("_total", optTotal); 457 optMap.put("_percent", percent); 458 resultMap.put(optId, optMap); 459 } 460 resultMap.put("_a_type", "option"); 461 } 462 } else if ("BOOLEAN".equals(questionType)) { 463 long[] thisResult = getBooleanResult(question); 464 long yesPercent = thisResult[1] > 0 ? (long)(((double)thisResult[1] / (double)thisResult[0]) * 100) : 0; 465 long noPercent = thisResult[2] > 0 ? (long)(((double)thisResult[2] / (double)thisResult[0]) * 100) : 0; 466 467 resultMap.put("_total", new Long (thisResult[0])); 468 resultMap.put("_yes_total", new Long (thisResult[1])); 469 resultMap.put("_no_total", new Long (thisResult[2])); 470 resultMap.put("_yes_percent", new Long (yesPercent)); 471 resultMap.put("_no_percent", new Long (noPercent)); 472 resultMap.put("_a_type", "boolean"); 473 } else if ("NUMBER_LONG".equals(questionType)) { 474 double[] thisResult = getNumberResult(question, 1); 475 resultMap.put("_total", new Long ((long)thisResult[0])); 476 resultMap.put("_tally", new Long ((long)thisResult[1])); 477 resultMap.put("_average", new Long ((long)thisResult[2])); 478 resultMap.put("_a_type", "long"); 479 } else if ("NUMBER_CURRENCY".equals(questionType)) { 480 double[] thisResult = getNumberResult(question, 2); 481 resultMap.put("_total", new Long ((long)thisResult[0])); 482 resultMap.put("_tally", new Double (thisResult[1])); 483 resultMap.put("_average", new Double (thisResult[2])); 484 resultMap.put("_a_type", "double"); 485 } else if ("NUMBER_FLOAT".equals(questionType)) { 486 double[] thisResult = getNumberResult(question, 3); 487 resultMap.put("_total", new Long ((long)thisResult[0])); 488 resultMap.put("_tally", new Double (thisResult[1])); 489 resultMap.put("_average", new Double (thisResult[2])); 490 resultMap.put("_a_type", "double"); 491 } else if ("SEPERATOR_LINE".equals(questionType) || "SEPERATOR_TEXT".equals(questionType)) { 492 return null; 494 } else { 495 resultMap.put("_total", new Long (getTextResult(question))); 497 resultMap.put("_a_type", "text"); 498 } 499 500 return resultMap; 501 } 502 503 private long[] getBooleanResult(GenericValue question) throws SurveyWrapperException { 504 boolean beganTransaction = false; 505 try { 506 beganTransaction = TransactionUtil.begin(); 507 508 long[] result = { 0, 0, 0 }; 509 513 EntityListIterator eli = this.getEli(question); 514 515 if (eli != null) { 516 GenericValue value; 517 while (((value = (GenericValue) eli.next()) != null)) { 518 if ("Y".equalsIgnoreCase(value.getString("booleanResponse"))) { 519 result[1]++; 520 } else { 521 result[2]++; 522 } 523 result[0]++; } 525 526 eli.close(); 527 } 528 529 return result; 530 } catch (GenericEntityException e) { 531 try { 532 TransactionUtil.rollback(beganTransaction, "Error getting survey question responses Boolean result", e); 534 } catch (GenericEntityException e2) { 535 Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); 536 } 537 538 throw new SurveyWrapperException(e); 539 } finally { 540 try { 541 TransactionUtil.commit(beganTransaction); 543 } catch (GenericEntityException e) { 544 throw new SurveyWrapperException(e); 545 } 547 } 548 } 549 550 private double[] getNumberResult(GenericValue question, int type) throws SurveyWrapperException { 551 double[] result = { 0, 0, 0 }; 552 556 boolean beganTransaction = false; 557 try { 558 beganTransaction = TransactionUtil.begin(); 559 560 EntityListIterator eli = this.getEli(question); 561 562 if (eli != null) { 563 GenericValue value; 564 while (((value = (GenericValue) eli.next()) != null)) { 565 switch (type) { 566 case 1: 567 Long n = value.getLong("numericResponse"); 568 result[1] += n.longValue(); 569 break; 570 case 2: 571 Double c = value.getDouble("currencyResponse"); 572 result[1] += (((double) Math.round((c.doubleValue() - c.doubleValue()) * 100)) / 100); 573 break; 574 case 3: 575 Double f = value.getDouble("floatResponse"); 576 result[1] += f.doubleValue(); 577 break; 578 } 579 result[0]++; } 581 582 eli.close(); 583 } 584 } catch (GenericEntityException e) { 585 try { 586 TransactionUtil.rollback(beganTransaction, "Error getting survey question responses Number result", e); 588 } catch (GenericEntityException e2) { 589 Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); 590 } 591 592 throw new SurveyWrapperException(e); 593 } finally { 594 try { 595 TransactionUtil.commit(beganTransaction); 597 } catch (GenericEntityException e) { 598 throw new SurveyWrapperException(e); 599 } 601 } 602 603 switch (type) { 605 case 1: 606 if (result[0] > 0) 607 result[2] = ((long) result[1]) / ((long) result[0]); 608 break; 609 case 2: 610 if (result[0] > 0) 611 result[2] = (((double) Math.round((result[1] / result[0]) * 100)) / 100); 612 break; 613 case 3: 614 if (result[0] > 0) 615 result[2] = result[1] / result[0]; 616 break; 617 } 618 619 return result; 620 } 621 622 private long getTextResult(GenericValue question) throws SurveyWrapperException { 623 long result = 0; 624 625 try { 626 result = delegator.findCountByCondition("SurveyResponseAndAnswer", makeEliCondition(question), null); 627 } catch (GenericEntityException e) { 628 Debug.logError(e, module); 629 throw new SurveyWrapperException("Unable to get responses", e); 630 } 631 632 return result; 633 } 634 635 private Map getOptionResult(GenericValue question) throws SurveyWrapperException { 636 Map result = new HashMap (); 637 long total = 0; 638 639 boolean beganTransaction = false; 640 try { 641 beganTransaction = TransactionUtil.begin(); 642 643 EntityListIterator eli = this.getEli(question); 644 if (eli != null) { 645 GenericValue value; 646 while (((value = (GenericValue) eli.next()) != null)) { 647 String optionId = value.getString("surveyOptionSeqId"); 648 Long optCount = (Long ) result.remove(optionId); 649 if (optCount == null) { 650 optCount = new Long (1); 651 } else { 652 optCount = new Long (1 + optCount.longValue()); 653 } 654 result.put(optionId, optCount); 655 total++; } 657 658 eli.close(); 659 } 660 } catch (GenericEntityException e) { 661 try { 662 TransactionUtil.rollback(beganTransaction, "Error getting survey question responses Option result", e); 664 } catch (GenericEntityException e2) { 665 Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); 666 } 667 668 throw new SurveyWrapperException(e); 669 } finally { 670 try { 671 TransactionUtil.commit(beganTransaction); 673 } catch (GenericEntityException e) { 674 throw new SurveyWrapperException(e); 675 } 677 } 678 679 result.put("_total", new Long (total)); 680 return result; 681 } 682 683 private EntityCondition makeEliCondition(GenericValue question) { 684 return new EntityConditionList(UtilMisc.toList(new EntityExpr("surveyQuestionId", 685 EntityOperator.EQUALS, question.getString("surveyQuestionId")), 686 new EntityExpr("surveyId", EntityOperator.EQUALS, surveyId)), EntityOperator.AND); 687 } 688 689 private EntityListIterator getEli(GenericValue question) throws GenericEntityException { 690 EntityFindOptions efo = new EntityFindOptions(); 691 efo.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE); 692 efo.setResultSetConcurrency(EntityFindOptions.CONCUR_READ_ONLY); 693 efo.setSpecifyTypeAndConcur(true); 694 efo.setDistinct(false); 695 696 EntityListIterator eli = null; 697 eli = delegator.findListIteratorByCondition("SurveyResponseAndAnswer", makeEliCondition(question), null, null, null, efo); 698 699 return eli; 700 } 701 702 protected class SurveyWrapperException extends GeneralException { 703 704 public SurveyWrapperException() { 705 super(); 706 } 707 708 public SurveyWrapperException(String str) { 709 super(str); 710 } 711 712 public SurveyWrapperException(String str, Throwable nested) { 713 super(str, nested); 714 } 715 716 public SurveyWrapperException(Throwable nested) { 717 super(nested); 718 } 719 } 720 } 721 | Popular Tags |