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