001/* 002 * Copyright 2018 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.odfpilotage.report.impl; 017 018import java.io.File; 019import java.io.FileOutputStream; 020import java.io.IOException; 021import java.util.Iterator; 022import java.util.List; 023 024import javax.xml.transform.Result; 025import javax.xml.transform.TransformerFactory; 026import javax.xml.transform.sax.SAXTransformerFactory; 027import javax.xml.transform.sax.TransformerHandler; 028import javax.xml.transform.stream.StreamResult; 029 030import org.apache.cocoon.xml.AttributesImpl; 031import org.apache.cocoon.xml.XMLUtils; 032import org.apache.commons.io.FileUtils; 033import org.apache.commons.lang3.StringUtils; 034import org.xml.sax.SAXException; 035 036import org.ametys.cms.FilterNameHelper; 037import org.ametys.cms.data.ContentDataHelper; 038import org.ametys.odf.course.Course; 039import org.ametys.odf.courselist.CourseList; 040import org.ametys.odf.courselist.CourseList.ChoiceType; 041import org.ametys.odf.coursepart.CoursePart; 042import org.ametys.odf.orgunit.OrgUnit; 043import org.ametys.odf.program.Container; 044import org.ametys.odf.program.Program; 045import org.ametys.odf.program.SubProgram; 046import org.ametys.plugins.odfpilotage.helper.PilotageHelper; 047import org.ametys.plugins.odfpilotage.report.impl.mcc.MCCAmetysObjectTree; 048import org.ametys.plugins.repository.AmetysObject; 049import org.ametys.plugins.repository.AmetysObjectIterable; 050import org.ametys.plugins.repository.AmetysObjectIterator; 051import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeaterEntry; 052 053/** 054 * Class to generate a report based on MCC. 055 */ 056public abstract class AbstractMCCReport extends AbstractReport 057{ 058 /** Prefix of the sessions name */ 059 protected static final String SESSION_NAME_PREFIX = "mccSession"; 060 /** Name of the first session */ 061 protected static final String FIRST_SESSION_NAME = SESSION_NAME_PREFIX + "1"; 062 /** Name of the second session */ 063 protected static final String SECOND_SESSION_NAME = SESSION_NAME_PREFIX + "2"; 064 065 @Override 066 protected void _launchByOrgUnit(String uaiCode, String catalog, String lang) throws Exception 067 { 068 // Initialize data 069 MCCAmetysObjectTree tree = _processMCC(uaiCode, lang, catalog); 070 071 // Generate the XML file corresponding to the organization with the current org unit reference 072 _writeReportsMcc(tree); 073 } 074 075 /** 076 * Processing of the MCC 077 * @param uaiCode the UAI code of the orgunit 078 * @param lang The language code 079 * @param catalog The catalogue 080 * @return {@link MCCAmetysObjectTree} 081 */ 082 protected MCCAmetysObjectTree _processMCC(String uaiCode, String lang, String catalog) 083 { 084 MCCAmetysObjectTree tree = null; 085 086 // Filter the programs with this uai code 087 AmetysObjectIterable<OrgUnit> orgUnits = _reportHelper.getRootOrgUnitsByUaiCode(uaiCode); 088 AmetysObjectIterator<OrgUnit> orgUnitsIterator = orgUnits.iterator(); 089 if (orgUnitsIterator.hasNext()) 090 { 091 OrgUnit orgUnit = orgUnitsIterator.next(); 092 getLogger().info("Rapport de pilotage construit sur la composante '{}' ({})", orgUnit.getTitle(), orgUnit.getUAICode()); 093 List<Program> selectedPrograms = _reportHelper.filterProgramsFromOrgUnits(orgUnit, lang, catalog); 094 tree = extractMCCAmetysObjectTree(orgUnit, selectedPrograms); 095 } 096 else 097 { 098 getLogger().error("Il n'existe pas de composante ayant pour code UAI '{}'", uaiCode); 099 } 100 101 return tree; 102 } 103 104 /** 105 * Create the MCC report for one organization unit 106 * @param tree The MCC tree 107 */ 108 protected void _writeReportsMcc(MCCAmetysObjectTree tree) 109 { 110 SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance(); 111 112 for (MCCAmetysObjectTree child : tree.getChildren()) 113 { 114 AmetysObject ao = child.getCurrent(); 115 116 // children are supposed to be programs 117 if (ao instanceof Program) 118 { 119 Program program = (Program) ao; 120 String fileName = _getReportFileName(program); 121 122 // Delete old files 123 File xmlFile = new File(_tmpFolder, fileName + ".xml"); 124 FileUtils.deleteQuietly(xmlFile); 125 126 try (FileOutputStream fos = new FileOutputStream(xmlFile)) 127 { 128 TransformerHandler handler = factory.newTransformerHandler(); 129 130 // Prepare the transformation 131 Result result = new StreamResult(fos); 132 handler.setResult(result); 133 handler.startDocument(); 134 135 // Write XML file 136 AttributesImpl attrs = new AttributesImpl(); 137 attrs.addCDATAAttribute("type", getType()); 138 attrs.addCDATAAttribute("date", _reportHelper.getReadableCurrentDate()); 139 XMLUtils.startElement(handler, "report", attrs); 140 141 // SAX other global informations 142 saxGlobalInformations(handler, program); 143 144 // SAX natures enseignement 145 _reportHelper.saxNaturesEnseignement(handler, getLogger()); 146 _refTableHelper.saxItems(handler, PilotageHelper.MCC_MODALITE_SESSION1); 147 _refTableHelper.saxItems(handler, PilotageHelper.MCC_MODALITE_SESSION2); 148 _refTableHelper.saxItems(handler, PilotageHelper.MCC_SESSION_NATURE); 149 150 // SAX tree 151 saxTree(handler, child); 152 153 XMLUtils.endElement(handler, "report"); 154 handler.endDocument(); 155 156 // Convert the report to configured output format 157 convertReport(_tmpFolder, fileName, xmlFile); 158 } 159 catch (Exception e) 160 { 161 getLogger().error("An error occured while generating 'MCC' report for program '{}' ({})", program.getTitle(), program.getCode(), e); 162 } 163 finally 164 { 165 FileUtils.deleteQuietly(xmlFile); 166 } 167 } 168 } 169 } 170 171 /** 172 * SAX the MCC tree for the report 173 * @param handler The handler 174 * @param tree The MCC tree 175 * @throws SAXException if an error occurs 176 */ 177 protected void saxTree(TransformerHandler handler, MCCAmetysObjectTree tree) throws SAXException 178 { 179 AmetysObject ao = tree.getCurrent(); 180 181 if (ao instanceof OrgUnit) 182 { 183 saxOrgUnit(handler, (OrgUnit) ao, tree); 184 } 185 else if (ao instanceof Program) 186 { 187 saxProgram(handler, (Program) ao, tree); 188 } 189 else if (ao instanceof SubProgram) 190 { 191 saxSubProgram(handler, (SubProgram) ao, tree); 192 } 193 else if (ao instanceof Container) 194 { 195 saxContainer(handler, (Container) ao, tree); 196 } 197 else if (ao instanceof CourseList) 198 { 199 saxCourseList(handler, (CourseList) ao, tree); 200 } 201 else if (ao instanceof Course) 202 { 203 saxCourse(handler, (Course) ao, tree); 204 } 205 } 206 207 /** 208 * Sax an {@link OrgUnit}. 209 * @param handler The transformer handler 210 * @param orgunit The orgunit to sax 211 * @param tree The MCC tree 212 * @throws SAXException If an error occurs 213 */ 214 protected void saxOrgUnit(TransformerHandler handler, OrgUnit orgunit, MCCAmetysObjectTree tree) throws SAXException 215 { 216 // id + name 217 AttributesImpl attrs = new AttributesImpl(); 218 attrs.addCDATAAttribute("name", orgunit.getName()); 219 attrs.addCDATAAttribute("title", orgunit.getTitle()); 220 221 // Start tag + children + end tag 222 XMLUtils.startElement(handler, "orgunit", attrs); 223 saxTreeChildren(handler, tree); 224 XMLUtils.endElement(handler, "orgunit"); 225 } 226 227 /** 228 * Sax a {@link Program}. 229 * @param handler The transformer handler 230 * @param program The program to sax 231 * @param tree The MCC tree 232 * @throws SAXException If an error occurs 233 */ 234 protected void saxProgram(TransformerHandler handler, Program program, MCCAmetysObjectTree tree) throws SAXException 235 { 236 // id + name 237 AttributesImpl attrs = new AttributesImpl(); 238 attrs.addCDATAAttribute("id", program.getId()); 239 attrs.addCDATAAttribute("name", program.getName()); 240 241 // Start tag + title 242 XMLUtils.startElement(handler, "program", attrs); 243 XMLUtils.createElement(handler, "title", program.getTitle()); 244 XMLUtils.createElement(handler, "catalog", program.getCatalog()); 245 246 // VDI 247 XMLUtils.createElement(handler, "dip", _reportHelper.getCodeDIP(program)); 248 XMLUtils.createElement(handler, "vdi", _reportHelper.getCodeVRSVDI(program)); 249 XMLUtils.createElement(handler, "speciality", program.getSpeciality()); 250 251 // Degree 252 String degreeId = program.getDegree(); 253 if (StringUtils.isNotEmpty(degreeId)) 254 { 255 AttributesImpl degreeAttrs = new AttributesImpl(); 256 degreeAttrs.addCDATAAttribute("degree", _refTableHelper.getItemCode(degreeId)); 257 XMLUtils.startElement(handler, "degree", degreeAttrs); 258 XMLUtils.createElement(handler, "label", _refTableHelper.getItemLabel(degreeId, program.getLanguage())); 259 XMLUtils.endElement(handler, "degree"); 260 } 261 262 // Domaine 263 _reportHelper.saxContentAttribute(handler, program, "domain", "domain"); 264 265 // Mention 266 String mentionId = program.getMention(); 267 if (StringUtils.isNotEmpty(mentionId)) 268 { 269 XMLUtils.createElement(handler, "mention", _refTableHelper.getItemLabel(mentionId, program.getLanguage())); 270 } 271 272 // Code anu 273 Long codeAnu = _getCodeAnu(tree); 274 if (codeAnu != null) 275 { 276 XMLUtils.createElement(handler, "codeAnu", String.valueOf(codeAnu)); 277 } 278 279 // Contrôles de connaissances (rich text) 280 try 281 { 282 program.dataToSAX(handler, "knowledgeCheck"); 283 } 284 catch (IOException e) 285 { 286 getLogger().error("Unable to SAX rich-text metadata 'knowledgeCheck'.", e); 287 } 288 289 // Children 290 saxTreeChildren(handler, tree); 291 292 // End tag 293 XMLUtils.endElement(handler, "program"); 294 } 295 296 /** 297 * Sax a {@link SubProgram}. 298 * @param handler The transformer handler 299 * @param subProgram The subprogram to sax 300 * @param tree The MCC tree 301 * @throws SAXException If an error occurs 302 */ 303 protected void saxSubProgram(TransformerHandler handler, SubProgram subProgram, MCCAmetysObjectTree tree) throws SAXException 304 { 305 // id + name 306 AttributesImpl attrs = new AttributesImpl(); 307 attrs.addCDATAAttribute("id", subProgram.getId()); 308 attrs.addCDATAAttribute("name", subProgram.getName()); 309 310 // Start tag + title 311 XMLUtils.startElement(handler, "subprogram", attrs); 312 XMLUtils.createElement(handler, "title", subProgram.getTitle()); 313 314 // COD_PAR 315 XMLUtils.createElement(handler, "codePar", subProgram.getValue("codePar", false, StringUtils.EMPTY)); 316 317 // Contrôles de connaissances (rich text) 318 try 319 { 320 subProgram.dataToSAX(handler, "knowledgeCheck"); 321 } 322 catch (IOException e) 323 { 324 getLogger().error("Unable to SAX rich-text metadata 'knowledgeCheck'.", e); 325 } 326 327 // Children 328 saxTreeChildren(handler, tree); 329 330 // End tag 331 XMLUtils.endElement(handler, "subprogram"); 332 } 333 334 /** 335 * Sax a {@link Container}. 336 * @param handler The transformer handler 337 * @param container The container to sax 338 * @param tree The MCC tree 339 * @throws SAXException If an error occurs 340 */ 341 protected void saxContainer(TransformerHandler handler, Container container, MCCAmetysObjectTree tree) throws SAXException 342 { 343 // id + name 344 AttributesImpl attrs = new AttributesImpl(); 345 attrs.addCDATAAttribute("id", container.getId()); 346 attrs.addCDATAAttribute("name", container.getName()); 347 348 // Nature 349 String natureId = container.getNature(); 350 if (StringUtils.isNotEmpty(natureId)) 351 { 352 attrs.addCDATAAttribute("nature", _refTableHelper.getItemCode(natureId)); 353 } 354 355 // Période 356 String periodId = container.getPeriod(); 357 if (StringUtils.isNotEmpty(periodId)) 358 { 359 attrs.addCDATAAttribute("periodCode", _refTableHelper.getItemCode(periodId)); 360 attrs.addCDATAAttribute("periodValue", _refTableHelper.getItemLabel(periodId, container.getLanguage())); 361 } 362 363 // ECTS 364 attrs.addCDATAAttribute("ects", String.valueOf(container.getEcts())); 365 366 // Start tag + title 367 XMLUtils.startElement(handler, "container", attrs); 368 XMLUtils.createElement(handler, "title", container.getTitle()); 369 370 // ETP + VRS_ETP 371 XMLUtils.createElement(handler, "etp", container.getValue("etpCode", false, StringUtils.EMPTY)); 372 XMLUtils.createElement(handler, "vrsEtp", container.getValue("vrsEtpCode", false, StringUtils.EMPTY)); 373 374 // DIP + VDI 375 XMLUtils.createElement(handler, "dip", _reportHelper.getCodeDIP(container)); 376 XMLUtils.createElement(handler, "vdi", _reportHelper.getCodeVRSVDI(container)); 377 378 // Code (cdm) 379 XMLUtils.createElement(handler, "code", container.getCode()); 380 381 // Info particulières (rich text) 382 try 383 { 384 container.dataToSAX(handler, "controles"); 385 } 386 catch (IOException e) 387 { 388 getLogger().error("Unable to SAX rich-text metadata 'controles'.", e); 389 } 390 391 // Children 392 saxTreeChildren(handler, tree); 393 394 // End tag 395 XMLUtils.endElement(handler, "container"); 396 } 397 398 /** 399 * Sax a {@link CourseList}. 400 * @param handler The transformer handler 401 * @param courseList The course list to sax 402 * @param tree The MCC tree 403 * @throws SAXException If an error occurs 404 */ 405 protected void saxCourseList(TransformerHandler handler, CourseList courseList, MCCAmetysObjectTree tree) throws SAXException 406 { 407 // id + name 408 AttributesImpl attrs = new AttributesImpl(); 409 attrs.addCDATAAttribute("id", courseList.getId()); 410 attrs.addCDATAAttribute("name", courseList.getName()); 411 412 // type 413 ChoiceType type = courseList.getType(); 414 attrs.addCDATAAttribute(type.name().toLowerCase(), "true"); 415 attrs.addCDATAAttribute("minCourses", String.valueOf(courseList.getMinNumberOfCourses())); 416 417 // Start tag + title 418 XMLUtils.startElement(handler, "courselist", attrs); 419 XMLUtils.createElement(handler, "title", courseList.getTitle()); 420 421 // Children 422 saxTreeChildren(handler, tree); 423 424 // End tag 425 XMLUtils.endElement(handler, "courselist"); 426 } 427 428 /** 429 * Sax a {@link Course}. 430 * @param handler The transformer handler 431 * @param course The course to sax 432 * @param tree The MCC tree 433 * @throws SAXException If an error occurs 434 */ 435 protected void saxCourse(TransformerHandler handler, Course course, MCCAmetysObjectTree tree) throws SAXException 436 { 437 // id + name 438 AttributesImpl attrs = new AttributesImpl(); 439 attrs.addCDATAAttribute("id", course.getId()); 440 attrs.addCDATAAttribute("name", course.getName()); 441 442 // type 443 attrs.addCDATAAttribute("type", _refTableHelper.getItemCode(course.getCourseType())); 444 445 // ECTS 446 attrs.addCDATAAttribute("ects", String.valueOf(course.getEcts())); 447 448 // MODU weight 449 attrs.addCDATAAttribute("poidsModu", String.valueOf(course.getValue("poidsModu", false, 0D))); 450 451 // Start tag + title 452 XMLUtils.startElement(handler, "course", attrs); 453 XMLUtils.createElement(handler, "title", course.getTitle()); 454 455 // short label 456 XMLUtils.createElement(handler, "shortLabel", course.getValue("shortLabel", false, StringUtils.EMPTY)); 457 458 // Code (cdm) 459 XMLUtils.createElement(handler, "code", course.getCode()); 460 461 // Is evaluated 462 XMLUtils.createElement(handler, "evaluated", course.getValue("isEvaluated", false, Boolean.FALSE) ? "X" : StringUtils.EMPTY); 463 464 // Code Apogée 465 XMLUtils.createElement(handler, "codeApogee", course.getValue("elpCode", false, StringUtils.EMPTY)); 466 467 // TODO besoin de etapePorteuse? 468 /** 469 if (course.hasValue("etapePorteuse")) 470 { 471 Content etapePorteuse = Optional.ofNullable((ContentValue) course.getValue("etapePorteuse")) 472 .map(ContentValue::getContent) 473 .orElse(null); 474 475 if (etapePorteuse != null && etapePorteuse.hasNonEmptyValue("etpCode")) 476 { 477 attr.addCDATAAttribute("etapePorteuse", etapePorteuse.getTitle()); 478 attr.addCDATAAttribute("codeEtapePorteuse", etapePorteuse.getValue("etpCode")); 479 } 480 } 481 */ 482 483 saxCourseParts(handler, course); 484 485 saxMCCs(handler, course, tree); 486 487 saxTreeChildren(handler, tree); 488 489 // End tag 490 XMLUtils.endElement(handler, "course"); 491 } 492 493 /** 494 * Iterate on tree's children. 495 * @param handler The transformer handler 496 * @param tree The MCC tree 497 * @throws SAXException If an error occurs 498 */ 499 protected void saxTreeChildren(TransformerHandler handler, MCCAmetysObjectTree tree) throws SAXException 500 { 501 for (MCCAmetysObjectTree child : tree.getChildren()) 502 { 503 saxTree(handler, child); 504 } 505 } 506 507 /** 508 * Sax the {@link CoursePart}s containing in a {@link Course}. 509 * @param handler The transformer handler 510 * @param course The course with course parts to sax 511 * @throws SAXException If an error occurs 512 */ 513 protected void saxCourseParts(TransformerHandler handler, Course course) throws SAXException 514 { 515 // Volume horaire 516 XMLUtils.startElement(handler, "volumeHoraire"); 517 518 // Heures d'enseignement 519 for (CoursePart coursePart : course.getCourseParts()) 520 { 521 AttributesImpl attr = new AttributesImpl(); 522 attr.addCDATAAttribute("nature", coursePart.getNature()); 523 XMLUtils.createElement(handler, "volume", attr, String.valueOf(coursePart.getNumberOfHours())); 524 } 525 526 XMLUtils.endElement(handler, "volumeHoraire"); 527 } 528 529 /** 530 * Sax the MCC sessions. 531 * @param handler The transformer handler 532 * @param course The concerned {@link Course} to sax the MCCs on 533 * @param tree The MCC tree 534 * @throws SAXException If an error occurs 535 */ 536 protected abstract void saxMCCs(TransformerHandler handler, Course course, MCCAmetysObjectTree tree) throws SAXException; 537 538 /** 539 * Generates SAX events for the details of a MCC session entry. 540 * @param handler The transformer handler 541 * @param sessionEntry The session repeater entry to SAX 542 * @throws SAXException If an error occurs 543 */ 544 protected void saxSessionEntryDetails(TransformerHandler handler, ModelAwareRepeaterEntry sessionEntry) throws SAXException 545 { 546 // modalite 547 String modalite = _refTableHelper.getItemCode(ContentDataHelper.getContentIdFromContentData(sessionEntry, "modalite")); 548 if (StringUtils.isNotEmpty(modalite)) 549 { 550 XMLUtils.createElement(handler, "modalite", modalite); 551 } 552 553 // nature 554 String nature = _refTableHelper.getItemCode(ContentDataHelper.getContentIdFromContentData(sessionEntry, "nature")); 555 if (StringUtils.isNotEmpty(nature)) 556 { 557 XMLUtils.createElement(handler, "nature", nature); 558 } 559 560 // duree 561 long duree = sessionEntry.getValue("duree", false, 0L); 562 if (duree > 0) 563 { 564 AttributesImpl dureeAttrs = new AttributesImpl(); 565 dureeAttrs.addCDATAAttribute("minutes", String.valueOf(duree)); 566 XMLUtils.createElement(handler, "duree", _reportHelper.minute2hour((int) duree)); 567 } 568 569 // nombre 570 String nombre = sessionEntry.getValue("nombre", false, StringUtils.EMPTY); 571 if (StringUtils.isNotEmpty(nombre)) 572 { 573 XMLUtils.createElement(handler, "nombre", nombre); 574 } 575 // coefficient 576 String coeff = sessionEntry.getValue("coefficient", false, StringUtils.EMPTY); 577 if (StringUtils.isNotEmpty(coeff)) 578 { 579 AttributesImpl coeffAttrs = new AttributesImpl(); 580 581 if (coeff.indexOf('%') != -1) 582 { 583 coeffAttrs.addCDATAAttribute("pourcent", StringUtils.substringBefore(coeff, "%")); 584 XMLUtils.createElement(handler, "coefficient", coeffAttrs, coeff); 585 } 586 else if (coeff.indexOf('/') != -1) 587 { 588 coeffAttrs.addCDATAAttribute("num", StringUtils.substringBefore(coeff, "/")); 589 coeffAttrs.addCDATAAttribute("denom", StringUtils.substringAfter(coeff, "/")); 590 XMLUtils.createElement(handler, "coefficient", coeffAttrs, coeff); 591 } 592 else 593 { 594 XMLUtils.createElement(handler, "coefficient", coeffAttrs, coeff); 595 } 596 } 597 598 // remarque 599 String remarques = sessionEntry.getValue("remarques", false, StringUtils.EMPTY); 600 if (StringUtils.isNotEmpty(remarques)) 601 { 602 XMLUtils.createElement(handler, "remarques", remarques); 603 } 604 } 605 606 /** 607 * Extract the tree of Ametys object of interested. 608 * @param ou the orgunit to extract the MCC from 609 * @param programs the list of associated programs 610 * @return {@link MCCAmetysObjectTree} 611 */ 612 protected MCCAmetysObjectTree extractMCCAmetysObjectTree(OrgUnit ou, List<Program> programs) 613 { 614 MCCAmetysObjectTree tree = new MCCAmetysObjectTree(ou); 615 for (Program program : programs) 616 { 617 addProgram2MCCAmetysObjectTree(tree, program); 618 } 619 return tree; 620 } 621 622 /** 623 * Add and populate the program to the {@link MCCAmetysObjectTree} 624 * @param tree The object tree 625 * @param program The program to add 626 */ 627 protected void addProgram2MCCAmetysObjectTree(MCCAmetysObjectTree tree, Program program) 628 { 629 MCCAmetysObjectTree programTree = tree.addChild(program); 630 populateMCCAmetysObjectTree(programTree); 631 } 632 633 /** 634 * Populate the MCC tree. 635 * @param tree The MCC tree 636 */ 637 protected abstract void populateMCCAmetysObjectTree(MCCAmetysObjectTree tree); 638 639 /** 640 * Recurse through containers and courses to find a code anu. 641 * @param tree The MCC tree 642 * @return Return the Code ANU 643 */ 644 private Long _getCodeAnu(MCCAmetysObjectTree tree) 645 { 646 Long codeAnu = null; 647 648 Iterator<MCCAmetysObjectTree> iterator = tree.getChildren().iterator(); 649 while (iterator.hasNext() && codeAnu == null) 650 { 651 AmetysObject child = iterator.next().getCurrent(); 652 long code = -1; 653 654 if (child instanceof Container) 655 { 656 Container container = (Container) child; 657 code = container.getValue("CodeAnu", false, 0L); 658 } 659 else if (child instanceof Course) 660 { 661 Course course = (Course) child; 662 code = course.getValue("CodeAnu", false, 0L); 663 } 664 665 if (code > 0) 666 { 667 codeAnu = code; 668 } 669 } 670 671 if (codeAnu == null) 672 { 673 iterator = tree.getChildren().iterator(); 674 while (iterator.hasNext() && codeAnu == null) 675 { 676 codeAnu = _getCodeAnu(iterator.next()); 677 } 678 } 679 680 return codeAnu; 681 } 682 683 /** 684 * Get the report filename for a given program 685 * @param program The program 686 * @return the file name 687 */ 688 protected String _getReportFileName(Program program) 689 { 690 StringBuilder sb = new StringBuilder(); 691 692 sb.append(getType()); 693 sb.append("-"); 694 695 // Catalog 696 sb.append(program.getCatalog()); 697 sb.append("-"); 698 699 // Lang 700 sb.append(program.getLanguage()); 701 sb.append("-"); 702 703 // Domain 704 String[] domains = program.getDomain(); 705 for (String domainId : domains) 706 { 707 String domain = _refTableHelper.getItemCode(domainId); 708 if (StringUtils.isNotEmpty(domain)) 709 { 710 sb.append(domain); 711 sb.append('-'); 712 } 713 } 714 715 // Mention or title 716 String mentionId = program.getMention(); 717 if (StringUtils.isBlank(mentionId)) 718 { 719 sb.append(program.getTitle()); 720 } 721 else 722 { 723 // Degree + mention 724 sb.append(_refTableHelper.getItemCode(program.getDegree())); 725 sb.append("-"); 726 sb.append(_refTableHelper.getItemLabel(mentionId, program.getLanguage())); 727 } 728 729 // CDM code 730 sb.append("-"); 731 sb.append(program.getCode()); 732 733 // Date 734 sb.append("-"); 735 sb.append(_currentFormattedDate); 736 737 return FilterNameHelper.filterName(sb.toString()); 738 } 739 740 /** 741 * Sax the additional global informations of the report. 742 * @param handler The transformer handler 743 * @param program The program on which the report is launched 744 * @throws SAXException If an error occurs 745 */ 746 protected abstract void saxGlobalInformations(TransformerHandler handler, Program program) throws SAXException; 747}