001/* 002 * Copyright 2019 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.odf.lheo; 017 018import java.time.LocalDate; 019import java.time.format.DateTimeFormatter; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Objects; 024import java.util.Optional; 025import java.util.stream.Collectors; 026import java.util.stream.Stream; 027 028import org.apache.avalon.framework.component.Component; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.cocoon.xml.AttributesImpl; 033import org.apache.cocoon.xml.XMLUtils; 034import org.apache.commons.lang3.StringUtils; 035import org.xml.sax.ContentHandler; 036import org.xml.sax.SAXException; 037 038import org.ametys.cms.data.RichText; 039import org.ametys.cms.data.RichTextHelper; 040import org.ametys.cms.repository.Content; 041import org.ametys.odf.orgunit.OrgUnit; 042import org.ametys.odf.person.Person; 043import org.ametys.odf.program.Program; 044import org.ametys.plugins.repository.AmetysObjectResolver; 045import org.ametys.runtime.plugin.component.AbstractLogEnabled; 046 047/** 048 * Manager to generate programs to LHEO XML 049 */ 050public class ExportToLHEOManager extends AbstractLogEnabled implements Serviceable, Component 051{ 052 /** The Avalon role */ 053 public static final String ROLE = ExportToLHEOManager.class.getName(); 054 055 /** The ametys object resolver */ 056 protected AmetysObjectResolver _resolver; 057 058 /** The rich text helper */ 059 protected RichTextHelper _richTextHelper; 060 061 @Override 062 public void service(ServiceManager manager) throws ServiceException 063 { 064 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 065 _richTextHelper = (RichTextHelper) manager.lookup(RichTextHelper.ROLE); 066 } 067 068 /** 069 * Sax the LHEO xml for the list of programs 070 * @param contentHandler the content handler 071 * @param programs the list of program to sax 072 * @throws SAXException if a saxing exception occurred 073 */ 074 public void saxLHEO(ContentHandler contentHandler, List<Program> programs) throws SAXException 075 { 076 saxLHEO(contentHandler, programs, new HashMap<>()); 077 } 078 079 /** 080 * Sax the LHEO xml for the list of programs 081 * @param contentHandler the content handler 082 * @param programs the list of program to sax 083 * @param additionalParameters the additional parameters 084 * @throws SAXException if a saxing exception occurred 085 */ 086 public void saxLHEO(ContentHandler contentHandler, List<Program> programs, Map<String, Object> additionalParameters) throws SAXException 087 { 088 contentHandler.startDocument(); 089 contentHandler.startPrefixMapping("", "http://www.lheo.org/2.2"); 090 091 XMLUtils.startElement(contentHandler, "lheo"); 092 _saxOffers(contentHandler, programs, additionalParameters); 093 XMLUtils.endElement(contentHandler, "lheo"); 094 095 contentHandler.endDocument(); 096 } 097 098 /** 099 * Sax the XML tag <offres> 100 * <br>Can contain the following XML tags: 101 * <br>[1,N] <formation> 102 * <br>[0,N] <extras> 103 * @param contentHandler the content handler 104 * @param programs the list of program to sax 105 * @param additionalParameters the additional parameters 106 * @throws SAXException if a saxing exception occurred 107 */ 108 protected void _saxOffers(ContentHandler contentHandler, List<Program> programs, Map<String, Object> additionalParameters) throws SAXException 109 { 110 XMLUtils.startElement(contentHandler, "offres"); 111 _saxPrograms(contentHandler, programs, additionalParameters); 112 _saxOffersExtras(contentHandler, programs, additionalParameters); 113 XMLUtils.endElement(contentHandler, "offres"); 114 } 115 116 /** 117 * Sax for each program a XML tag <formation> 118 * @param contentHandler the content handler 119 * @param programs the list of program to sax 120 * @param additionalParameters the additional parameters 121 * @throws SAXException if a saxing exception occurred 122 */ 123 protected void _saxPrograms(ContentHandler contentHandler, List<Program> programs, Map<String, Object> additionalParameters) throws SAXException 124 { 125 for (Program program : programs) 126 { 127 _saxProgram(contentHandler, program, additionalParameters); 128 } 129 } 130 131 /** 132 * Sax a XML tag <formation> 133 * <br>Can contain the following XML tags: 134 * <br>[1,1] <domaine-formation> 135 * <br>[1,1] <intitule-formation> 136 * <br>[1,1] <objectif-formation> 137 * <br>[1,1] <resultats-attendus> 138 * <br>[1,1] <contenu-formation> 139 * <br>[1,1] <certifiante> 140 * <br>[1,1] <contact-formation> 141 * <br>[1,1] <parcours-de-formation> 142 * <br>[1,1] <code-niveau-entree> 143 * <br>[0,1] <objectif-general-formation> 144 * <br>[0,5] <certification> 145 * <br>[0,1] <code-niveau-sortie> 146 * <br>[0,1] <url-formation> 147 * <br>[1,N] <action> 148 * <br>[1,1] <organisme-formation-responsable> 149 * <br>[0,1] <identifiant-module> 150 * <br>[0,1] <positionnement> 151 * <br>[0,1] <sous-modules> 152 * <br>[0,1] <modules-prerequis> 153 * <br>[0,N] <extras> 154 * @param contentHandler the content handler 155 * @param program the program to sax 156 * @param additionalParameters the additional parameters 157 * @throws SAXException if a saxing exception occurred 158 */ 159 protected void _saxProgram(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 160 { 161 XMLUtils.startElement(contentHandler, "formation"); 162 163 // <domaine-formation> 164 _saxProgramDomain(contentHandler, program, additionalParameters); 165 166 // <intitule-formation> 167 _saxProgramTitle(contentHandler, program, additionalParameters); 168 169 // <objectif-formation> 170 _saxProgramObjectives(contentHandler, program, additionalParameters); 171 172 // <resultats-attendus> 173 _saxProgramExpectedResults(contentHandler, program, additionalParameters); 174 175 // <contenu-formation> 176 _saxProgramPresentation(contentHandler, program, additionalParameters); 177 178 // <certifiante> 179 _saxProgramCertifying(contentHandler, program, additionalParameters); 180 181 // <contact-formation> 182 _saxProgramContact(contentHandler, program, additionalParameters); 183 184 // <parcours-de-formation> 185 _saxProgramPath(contentHandler, program, additionalParameters); 186 187 // <code-niveau-entree> 188 _saxProgramEducationEntryLevel(contentHandler, program, additionalParameters); 189 190 // <certification> 191 _saxProgramCertification(contentHandler, program, additionalParameters); 192 193 // <action> 194 _saxProgramAction(contentHandler, program, additionalParameters); 195 196 // <organisme-formation-responsable> 197 _saxProgramResponsibleOrgUnit(contentHandler, program, additionalParameters); 198 199 // <extras> 200 _saxProgramsExtras(contentHandler, program, additionalParameters); 201 202 XMLUtils.endElement(contentHandler, "formation"); 203 } 204 205 /** 206 * Sax the XML tag <domaine-formation> 207 * <br>Can contain the following XML tags: 208 * <br>[0,5] <cpde-FORMACODE> 209 * <br>[0,3] <code-NSF> 210 * <br>[0,5] <code-ROME> 211 * <br>[0,N] <extras> 212 * @param contentHandler the content handler 213 * @param program the program to sax 214 * @param additionalParameters the additional parameters 215 * @throws SAXException if a saxing exception occurred 216 */ 217 protected void _saxProgramDomain(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 218 { 219 XMLUtils.startElement(contentHandler, "domaine-formation"); 220 221 // <code-FORMACODE> 222 _saxFORMACODE(contentHandler, program, additionalParameters); 223 224 // <code-NSF> 225 _saxNSF(contentHandler, program, additionalParameters); 226 227 // <code-ROME> 228 _saxROME(contentHandler, program, additionalParameters); 229 230 // <extras> 231 _saxProgramDomainExtras(contentHandler, program, additionalParameters); 232 233 XMLUtils.endElement(contentHandler, "domaine-formation"); 234 } 235 236 /** 237 * Sax the XML tag <code-FORMACODE> 238 * <br>The code contains exactly 5 characters 239 * <br>The tag must contains the attribute "ref" 240 * @param contentHandler the content handler 241 * @param program the program to sax 242 * @param additionalParameters the additional parameters 243 * @throws SAXException if a saxing exception occurred 244 */ 245 protected void _saxFORMACODE(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 246 { 247 AttributesImpl attrs = new AttributesImpl(); 248 attrs.addCDATAAttribute("ref", "V12"); // The value is fixed for the default implementation 249 String[] formacodes = program.getFORMACODE(); 250 if (formacodes.length > 5) 251 { 252 getLogger().warn("[" + program.getTitle() + " (" + program.getId() + ")] The LHEO format can have only 5 FORMACODE"); 253 } 254 255 for (String code : formacodes) 256 { 257 if (StringUtils.isNotBlank(code)) 258 { 259 LHEOUtils.createLHEOElement(contentHandler, program, "code-FORMACODE", attrs, code, 5, 5); 260 } 261 } 262 } 263 264 /** 265 * Sax the XML tag <code-NSF> 266 * <br>The code contains exactly 3 characters 267 * @param contentHandler the content handler 268 * @param program the program to sax 269 * @param additionalParameters the additional parameters 270 * @throws SAXException if a saxing exception occurred 271 */ 272 protected void _saxNSF(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 273 { 274 String nsfCodeId = program.getNSFCode(); 275 if (StringUtils.isNotBlank(nsfCodeId)) 276 { 277 Content nsfCodeContent = _resolver.resolveById(nsfCodeId); 278 String code = nsfCodeContent.getValue("code"); 279 if (StringUtils.isNotBlank(code)) 280 { 281 LHEOUtils.createLHEOElement(contentHandler, program, "code-NSF", code, 3, 3); 282 } 283 } 284 } 285 286 /** 287 * Sax the XML tag <code-ROME> 288 * <br>The code contains exactly 5 characters 289 * <br>The tag can have the attribute "ref". If not, the default value is "V3" 290 * @param contentHandler the content handler 291 * @param program the program to sax 292 * @param additionalParameters the additional parameters 293 * @throws SAXException if a saxing exception occurred 294 */ 295 protected void _saxROME(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 296 { 297 String[] romeCodes = program.getRomeCode(); 298 if (romeCodes.length > 5) 299 { 300 getLogger().warn("[" + program.getTitle() + " (" + program.getId() + ")] The LHEO format can have only 5 rome code"); 301 } 302 303 for (String romeCodeId : romeCodes) 304 { 305 Content romeCodeContent = _resolver.resolveById(romeCodeId); 306 String code = romeCodeContent.getValue("code"); 307 if (StringUtils.isNotBlank(code)) 308 { 309 LHEOUtils.createLHEOElement(contentHandler, program, "code-ROME", code, 5, 5); 310 } 311 } 312 } 313 314 /** 315 * Sax for program domain the XML tag <extras> 316 * <br>Can contains all not LHEO normalized elements 317 * @param contentHandler the content handler 318 * @param program the program to sax 319 * @param additionalParameters the additional parameters 320 * @throws SAXException if a saxing exception occurred 321 */ 322 protected void _saxProgramDomainExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 323 { 324 // No extras in default implementation 325 XMLUtils.createElement(contentHandler, "extras"); 326 } 327 328 /** 329 * Sax the XML tag <intitule-formation> 330 * <br>The value contains between 1 to 255 characters 331 * @param contentHandler the content handler 332 * @param program the program to sax 333 * @param additionalParameters the additional parameters 334 * @throws SAXException if a saxing exception occurred 335 */ 336 protected void _saxProgramTitle(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 337 { 338 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "intitule-formation", program.getTitle(), 1, 255); 339 } 340 341 /** 342 * Sax the XML tag <objectif-formation> 343 * <br>The value contains between 1 to 3000 characters 344 * @param contentHandler the content handler 345 * @param program the program to sax 346 * @param additionalParameters the additional parameters 347 * @throws SAXException if a saxing exception occurred 348 */ 349 protected void _saxProgramObjectives(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 350 { 351 String richText2String = _richText2String(program.getObjectives()); 352 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "objectif-formation", richText2String, 1, 3000); 353 } 354 355 /** 356 * Sax the XML tag <resultats-attendus> 357 * <br>The value contains between 1 to 3000 characters 358 * @param contentHandler the content handler 359 * @param program the program to sax 360 * @param additionalParameters the additional parameters 361 * @throws SAXException if a saxing exception occurred 362 */ 363 protected void _saxProgramExpectedResults(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 364 { 365 String richText2String = _richText2String(program.getExpectedResults()); 366 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "resultats-attendus", richText2String, 1, 3000); 367 } 368 369 /** 370 * Sax the XML tag <contenu-formation> 371 * <br>The value contains between 1 to 3000 characters 372 * @param contentHandler the content handler 373 * @param program the program to sax 374 * @param additionalParameters the additional parameters 375 * @throws SAXException if a saxing exception occurred 376 */ 377 protected void _saxProgramPresentation(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 378 { 379 String richText2String = _richText2String(program.getPresentation()); 380 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "contenu-formation", richText2String, 1, 3000); 381 } 382 383 /** 384 * Sax the XML tag <certifiante> 385 * <br>0 for false and 1 for true 386 * @param contentHandler the content handler 387 * @param program the program to sax 388 * @param additionalParameters the additional parameters 389 * @throws SAXException if a saxing exception occurred 390 */ 391 protected void _saxProgramCertifying(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 392 { 393 boolean certifying = program.isCertifying(); 394 String certifyingAsString = certifying ? "1" : "0"; 395 LHEOUtils.createLHEOElement(contentHandler, program, "certifiante", certifyingAsString); 396 } 397 398 /** 399 * Sax the XML tag <contact-formation> 400 * <br>Can contain the following XML tags: 401 * <br>[1,1] <coordonnees> 402 * <br>[0,N] <extras> 403 * @param contentHandler the content handler 404 * @param program the program to sax 405 * @param additionalParameters the additional parameters 406 * @throws SAXException if a saxing exception occurred 407 */ 408 protected void _saxProgramContact(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 409 { 410 XMLUtils.startElement(contentHandler, "contact-formation"); 411 412 // <coordonnees> 413 _saxProgramContactCoordonnees(contentHandler, program, additionalParameters); 414 415 // <extras> 416 _saxProgramContactExtras(contentHandler, program, additionalParameters); 417 418 XMLUtils.endElement(contentHandler, "contact-formation"); 419 } 420 421 /** 422 * Sax for program contact the XML tag <coordonnees> 423 * <br>Can contain the following XML tags: 424 * <br>[0,1] <civilite> 425 * <br>[0,1] <nom> 426 * <br>[0,1] <prenom> 427 * <br>[0,3] <ligne> 428 * <br>[0,1] <adresse> 429 * <br>[0,1] <telfixe> 430 * <br>[0,1] <portable> 431 * <br>[0,1] <fax> 432 * <br>[0,1] <courriel> 433 * <br>[0,1] <web> 434 * <br>[0,N] <extras> 435 * @param contentHandler the content handler 436 * @param program the program to sax 437 * @param additionalParameters the additional parameters 438 * @throws SAXException if a saxing exception occurred 439 */ 440 protected void _saxProgramContactCoordonnees(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 441 { 442 XMLUtils.startElement(contentHandler, "coordonnees"); 443 444 Optional<Person> personOpt = program.getContacts() 445 .stream() 446 .filter(StringUtils::isNotBlank) 447 .map(id -> _getPerson(id)) 448 .filter(Objects::nonNull) 449 .findFirst(); 450 451 if (personOpt.isPresent()) 452 { 453 Person person = personOpt.get(); 454 _saxPersonCoordinate(contentHandler, person, additionalParameters); 455 } 456 457 XMLUtils.endElement(contentHandler, "coordonnees"); 458 } 459 460 /** 461 * Sax for program contact the XML tag <extras> 462 * <br>Can contains all not LHEO normalized elements 463 * @param contentHandler the content handler 464 * @param program the program to sax 465 * @param additionalParameters the additional parameters 466 * @throws SAXException if a saxing exception occurred 467 */ 468 protected void _saxProgramContactExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 469 { 470 // No extras in default implementation 471 XMLUtils.createElement(contentHandler, "extras"); 472 } 473 474 /** 475 * Sax the XML tag <parcours-de-formation> 476 * @param contentHandler the content handler 477 * @param program the program to sax 478 * @param additionalParameters the additional parameters 479 * @throws SAXException if a saxing exception occurred 480 */ 481 protected void _saxProgramPath(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 482 { 483 // In default implementation, the path value is always 1 ('En groupe') 484 LHEOUtils.createLHEOElement(contentHandler, program, "parcours-de-formation", "1"); 485 } 486 487 /** 488 * Sax the XML tag <code-niveau-entree> 489 * @param contentHandler the content handler 490 * @param program the program to sax 491 * @param additionalParameters the additional parameters 492 * @throws SAXException if a saxing exception occurred 493 */ 494 protected void _saxProgramEducationEntryLevel(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 495 { 496 String[] educationLevelEntries = program.getEducationLevelEntry(); 497 498 String educationLevelEntryForLHEO = null; 499 if (educationLevelEntries.length > 0) 500 { 501 String educationLevelEntryId = educationLevelEntries[0]; // Take the first 502 Content educationLevelEntryContent = _resolver.resolveById(educationLevelEntryId); 503 504 String code = educationLevelEntryContent.getValue("code"); 505 educationLevelEntryForLHEO = _convertEducationEntryLevel2LHEO(code); 506 } 507 508 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "code-niveau-entree", educationLevelEntryForLHEO); 509 } 510 511 /** 512 * Convert the Ametys education entry level code to LHEO 513 * @param code the ametys code 514 * @return the LHEO key value 515 */ 516 protected String _convertEducationEntryLevel2LHEO(String code) 517 { 518 // No code or "Bac + 1" or "Inconnu" or "Inferieur ou égal au baccalauréat" 519 if (StringUtils.isBlank(code) || "1".equals(code) || "9".equals(code) || "0".equals(code)) 520 { 521 // "information non communiquée" 522 return "0"; 523 } 524 // "Bac + 2" 525 else if ("2".equals(code)) 526 { 527 // "niveau III (BTS, DUT)" 528 return "6"; 529 } 530 // "Bac + 3" 531 else if ("3".equals(code)) 532 { 533 // "niveau II (licence ou maîtrise universitaire)" 534 return "7"; 535 } 536 // "Bac + 4" or "Bac + 5" or "Bac + 6" or "Bac + 7" or "Bac + 8" 537 else 538 { 539 // "niveau I (supérieur à la maîtrise)" 540 return "8"; 541 } 542 } 543 544 /** 545 * Sax the XML tag <certification> 546 * <br>Can contain the following XML tags: 547 * <br>[0,1] <code-RNCP> 548 * <br>[0,1] <code-CERTIFINFO> 549 * <br>[0,N] <extras> 550 * @param contentHandler the content handler 551 * @param program the program to sax 552 * @param additionalParameters the additional parameters 553 * @throws SAXException if a saxing exception occurred 554 */ 555 protected void _saxProgramCertification(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 556 { 557 XMLUtils.startElement(contentHandler, "certification"); 558 559 // <code-RNCP> 560 _saxProgramRNCPCode(contentHandler, program, additionalParameters); 561 562 // <code-CERTIFINFO> 563 _saxProgramCERTIFINFOCode(contentHandler, program, additionalParameters); 564 565 // <extras> 566 _saxCertificationExtras(contentHandler, program, additionalParameters); 567 568 XMLUtils.endElement(contentHandler, "certification"); 569 } 570 571 /** 572 * Sax the XML tag <action> 573 * <br>Can contain the following XML tags: 574 * <br>[1,1] <rythme-formation> 575 * <br>[1,10] <code-public-vise> 576 * <br>[0,1] <info-public-vise> 577 * <br>[1,1] <niveau-entree-obligatoire> 578 * <br>[1,1] <modalites-alternance> 579 * <br>[1,1] <modalites-enseignement> 580 * <br>[1,1] <conditions-specifiques> 581 * <br>[1,1] <prise-en-charge-frais-possible> 582 * <br>[1,1] <lieu-de-formation> 583 * <br>[1,1] <modalites-entrees-sorties> 584 * <br>[0,1] <url-action> 585 * <br>[1,N] <session> 586 * <br>[0,1] <adresse-information> 587 * <br>[0,3] <date-information> 588 * <br>[0,1] <restauration> 589 * <br>[0,1] <hebergement> 590 * <br>[0,1] <transport> 591 * <br>[0,1] <acces-handicapes> 592 * <br>[0,1] <langue-formation> 593 * <br>[0,1] <modalites-recrutement> 594 * <br>[0,1] <modalites-pedagogiques> 595 * <br>[0,5] <code-modalite-pedagogique> 596 * <br>[0,1] <frais-restants> 597 * <br>[0,1] <code-perimetre-recrutement> 598 * <br>[0,1] <infos-perimetre-recrutement> 599 * <br>[0,1] <prix-horaire-TTC> 600 * <br>[0,1] <prix-total-TTC> 601 * <br>[0,1] <duree-indicative> 602 * <br>[0,1] <nombre-heures-centre> 603 * <br>[0,1] <nombre-heures-entreprise> 604 * <br>[0,1] <nombre-heures-total> 605 * <br>[0,1] <detail-conditions-prise-en-charge> 606 * <br>[0,1] <conventionnement> 607 * <br>[0,1] <duree-conventionnee> 608 * <br>[0,1] <organisme-formateur> 609 * <br>[0,8] <organisme-financeur> 610 * <br>[0,N] <extras> 611 * @param contentHandler the content handler 612 * @param program the program to sax 613 * @param additionalParameters the additional parameters 614 * @throws SAXException if a saxing exception occurred 615 */ 616 protected void _saxProgramAction(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 617 { 618 XMLUtils.startElement(contentHandler, "action"); 619 620 // <rythme-formation> 621 _saxProgramTiming(contentHandler, program, additionalParameters); 622 623 // <code-public-vise> 624 _saxProgramTargetAudience(contentHandler, program, additionalParameters); 625 626 // <niveau-entree-obligatoire> 627 _saxProgramMandatoryEntryLevel(contentHandler, program, additionalParameters); 628 629 // <modalites-alternance> 630 _saxProgramAlternationModality(contentHandler, program, additionalParameters); 631 632 // <modalites-enseignement> 633 _saxProrgamDistanceLearning(contentHandler, program, additionalParameters); 634 635 // <conditions-specifiques> 636 _saxProgramNeededPrerequisite(contentHandler, program, additionalParameters); 637 638 // <prise-en-charge-frais-possible> 639 _saxProgramCostBearing(contentHandler, program, additionalParameters); 640 641 // <lieu-de-formation> 642 _saxProgramPlaces(contentHandler, program, additionalParameters); 643 644 // <modalites-entrees-sorties> 645 _saxProgramEntryExitModalities(contentHandler, program, additionalParameters); 646 647 // <session> 648 _saxProgramSession(contentHandler, program, additionalParameters); 649 650 // <langue-formation> 651 _saxProgramEducationLanguage(contentHandler, program, additionalParameters); 652 653 // <modalites-recrutement> 654 _saxProgramAccessCondition(contentHandler, program, additionalParameters); 655 656 // <extras> 657 _saxActionExtras(contentHandler, program, additionalParameters); 658 659 XMLUtils.endElement(contentHandler, "action"); 660 } 661 662 /** 663 * Sax the XML tag <rythme-formation> 664 * <br>The value contains between 1 to 3000 characters 665 * @param contentHandler the content handler 666 * @param program the program to sax 667 * @param additionalParameters the additional parameters 668 * @throws SAXException if a saxing exception occurred 669 */ 670 protected void _saxProgramTiming(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 671 { 672 // In default implementation, the program timing value is always "Temps plein" 673 LHEOUtils.createLHEOElement(contentHandler, program, "rythme-formation", "Temps plein"); 674 } 675 676 /** 677 * Sax the XML tag <code-public-vise> 678 * <br>The code contains exactly 5 characters 679 * <br>The tag must contains the attribute "ref" 680 * @param contentHandler the content handler 681 * @param program the program to sax 682 * @param additionalParameters the additional parameters 683 * @throws SAXException if a saxing exception occurred 684 */ 685 protected void _saxProgramTargetAudience(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 686 { 687 AttributesImpl attrs = new AttributesImpl(); 688 attrs.addCDATAAttribute("ref", "V12"); // The value is fixed for the default implementation 689 String[] formacodes = program.getFORMACODE(); 690 if (formacodes.length > 10) 691 { 692 getLogger().warn("[" + program.getTitle() + " (" + program.getId() + ")] The LHEO format can have only 10 FORMACODE for XML tag 'code-public-vise'"); 693 } 694 if (formacodes.length == 0) 695 { 696 getLogger().warn("[" + program.getTitle() + " (" + program.getId() + ")] The LHEO format must have at least one FORMACODE for XML tag 'code-public-vise'"); 697 } 698 699 for (String code : formacodes) 700 { 701 if (StringUtils.isNotBlank(code)) 702 { 703 LHEOUtils.createLHEOElement(contentHandler, program, "code-public-vise", attrs, code, 5, 5); 704 } 705 } 706 } 707 708 /** 709 * Sax the XML tag <niveau-entree-obligatoire> 710 * <br>0 for false and 1 for true 711 * @param contentHandler the content handler 712 * @param program the program to sax 713 * @param additionalParameters the additional parameters 714 * @throws SAXException if a saxing exception occurred 715 */ 716 protected void _saxProgramMandatoryEntryLevel(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 717 { 718 boolean mandatoryEntryLevel = program.isMandatoryEntryLevel(); 719 String mandatoryEntryLevelAsString = mandatoryEntryLevel ? "1" : "0"; 720 LHEOUtils.createLHEOElement(contentHandler, program, "niveau-entree-obligatoire", mandatoryEntryLevelAsString); 721 } 722 723 /** 724 * Sax the XML tag <modalites-alternance> 725 * <br>The value contains between 1 to 3000 characters 726 * @param contentHandler the content handler 727 * @param program the program to sax 728 * @param additionalParameters the additional parameters 729 * @throws SAXException if a saxing exception occurred 730 */ 731 protected void _saxProgramAlternationModality(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 732 { 733 String richText2String = _richText2String(program.getAlternationModality()); 734 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "modalites-alternance", richText2String, 1, 3000); 735 } 736 737 /** 738 * Sax the XML tag <modalites-enseignement> 739 * @param contentHandler the content handler 740 * @param program the program to sax 741 * @param additionalParameters the additional parameters 742 * @throws SAXException if a saxing exception occurred 743 */ 744 protected void _saxProrgamDistanceLearning(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 745 { 746 String distanceLearningId = program.getDistanceLearning(); 747 String distanceLearningForLHEO = null; 748 if (StringUtils.isNotBlank(distanceLearningId)) 749 { 750 Content distanceLearningContent = _resolver.resolveById(distanceLearningId); 751 752 String code = distanceLearningContent.getValue("code"); 753 distanceLearningForLHEO = _convertDistanceLearning2LHEO(code); 754 } 755 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "modalites-enseignement", distanceLearningForLHEO); 756 } 757 758 /** 759 * Convert the ametys code in LHEO code 760 * @param code the ametys code 761 * @return the LHEO code 762 */ 763 protected String _convertDistanceLearning2LHEO(String code) 764 { 765 // "A distance" 766 if ("distanceLearningModalities_mandatory".equals(code)) 767 { 768 // "formation entièrement à distance" 769 return "2"; 770 } 771 // "Hybride" 772 else if ("distanceLearningModalities_possible".equals(code)) 773 { 774 // "formation mixte" 775 return "1"; 776 } 777 // "En présence" 778 else if ("distanceLearningModalities_no".equals(code)) 779 { 780 // "formation entièrement présentielle" 781 return "0"; 782 } 783 784 return null; 785 } 786 787 /** 788 * Sax the XML tag <conditions-specifiques> 789 * <br>The value contains between 1 to 3000 characters 790 * @param contentHandler the content handler 791 * @param program the program to sax 792 * @param additionalParameters the additional parameters 793 * @throws SAXException if a saxing exception occurred 794 */ 795 protected void _saxProgramNeededPrerequisite(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 796 { 797 String richText2String = _richText2String(program.getNeededPrerequisite()); 798 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "conditions-specifiques", richText2String, 1, 3000); 799 } 800 801 /** 802 * Sax the XML tag <prise-en-charge-frais-possible> 803 * <br>0 for false and 1 for true 804 * @param contentHandler the content handler 805 * @param program the program to sax 806 * @param additionalParameters the additional parameters 807 * @throws SAXException if a saxing exception occurred 808 */ 809 protected void _saxProgramCostBearing(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 810 { 811 // In default implementation, the program cost bearing value is always 0 (false) 812 LHEOUtils.createLHEOElement(contentHandler, program, "prise-en-charge-frais-possible", "0"); 813 } 814 815 /** 816 * Sax the XML tag <lieu-de-formation> 817 * <br>Can contain the following XML tags: 818 * <br>[1,1] <coordonnees> 819 * <br>[0,N] <extras> 820 * @param contentHandler the content handler 821 * @param program the program to sax 822 * @param additionalParameters the additional parameters 823 * @throws SAXException if a saxing exception occurred 824 */ 825 protected void _saxProgramPlaces(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 826 { 827 XMLUtils.startElement(contentHandler, "lieu-de-formation"); 828 829 // <coordonnees> 830 _saxPlacesCoordonnees(contentHandler, program, additionalParameters); 831 832 // <extras> 833 _saxPlacesExtras(contentHandler, program, additionalParameters); 834 835 XMLUtils.endElement(contentHandler, "lieu-de-formation"); 836 } 837 838 /** 839 * Sax for places the XML tag <coordonnees> 840 * <br>Can contain the following XML tags: 841 * <br>[0,1] <civilite> 842 * <br>[0,1] <nom> 843 * <br>[0,1] <prenom> 844 * <br>[0,3] <ligne> 845 * <br>[0,1] <adresse> 846 * <br>[0,1] <telfixe> 847 * <br>[0,1] <portable> 848 * <br>[0,1] <fax> 849 * <br>[0,1] <courriel> 850 * <br>[0,1] <web> 851 * <br>[0,N] <extras> 852 * @param contentHandler the content handler 853 * @param program the program to sax 854 * @param additionalParameters the additional parameters 855 * @throws SAXException if a saxing exception occurred 856 */ 857 protected void _saxPlacesCoordonnees(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 858 { 859 XMLUtils.startElement(contentHandler, "coordonnees"); 860 861 List<String> places = Stream.of(program.getPlace()) 862 .filter(StringUtils::isNotBlank) 863 .map(id -> _getRefContent(id)) 864 .filter(Objects::nonNull) 865 .map(c -> c.getTitle()) 866 .collect(Collectors.toList()); 867 868 LHEOUtils.createCoordinateLHEOElementsPart1( 869 contentHandler, 870 program, 871 null, // civilite 872 null, // nom 873 null, // prenom 874 places // ligne 875 ); 876 877 XMLUtils.endElement(contentHandler, "coordonnees"); 878 } 879 880 /** 881 * Sax for places the XML tag <extras> 882 * <br>Can contains all not LHEO normalized elements 883 * @param contentHandler the content handler 884 * @param program the program to sax 885 * @param additionalParameters the additional parameters 886 * @throws SAXException if a saxing exception occurred 887 */ 888 protected void _saxPlacesExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 889 { 890 // No extras in default implementation 891 XMLUtils.createElement(contentHandler, "extras"); 892 } 893 894 /** 895 * Sax the XML tag <modalites-entrees-sorties> 896 * @param contentHandler the content handler 897 * @param program the program to sax 898 * @param additionalParameters the additional parameters 899 * @throws SAXException if a saxing exception occurred 900 */ 901 protected void _saxProgramEntryExitModalities(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 902 { 903 // In default implementation, the program entry exit modalities value is always 0 ('entrées/sorties à dates fixes') 904 LHEOUtils.createLHEOElement(contentHandler, program, "modalites-entrees-sorties", "1"); 905 } 906 907 /** 908 * Sax the XML tag <session> 909 * <br>Can contain the following XML tags: 910 * <br>[1,1] <periode> 911 * <br>[1,1] <adresse-inscription> 912 * <br>[0,1] <modalites-inscription> 913 * <br>[0,1] <periode-inscription> 914 * <br>[0,1] <etat-recrutement> 915 * <br>[0,N] <extras> 916 * @param contentHandler the content handler 917 * @param program the program to sax 918 * @param additionalParameters the additional parameters 919 * @throws SAXException if a saxing exception occurred 920 */ 921 protected void _saxProgramSession(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 922 { 923 XMLUtils.startElement(contentHandler, "session"); 924 925 // <periode> 926 _saxProgramPeriod(contentHandler, program, additionalParameters); 927 928 // <adresse-inscription> 929 _saxProgramRegistrationAddress(contentHandler, program, additionalParameters); 930 931 // <extras> 932 _saxSessionExtras(contentHandler, program, additionalParameters); 933 934 XMLUtils.endElement(contentHandler, "session"); 935 } 936 937 /** 938 * Sax the XML tag <periode> 939 * <br>Can contain the following XML tags: 940 * <br>[1,1] <debut> 941 * <br>[1,1] <fin> 942 * <br>[0,N] <extras> 943 * @param contentHandler the content handler 944 * @param program the program to sax 945 * @param additionalParameters the additional parameters 946 * @throws SAXException if a saxing exception occurred 947 */ 948 protected void _saxProgramPeriod(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 949 { 950 XMLUtils.startElement(contentHandler, "periode"); 951 952 // <debut> 953 _saxProgramPeriodStartDate(contentHandler, program, additionalParameters); 954 955 // <fin> 956 _saxProgramPeriodEndDate(contentHandler, program, additionalParameters); 957 958 // <extras> 959 _saxPeriodExtras(contentHandler, program, additionalParameters); 960 961 XMLUtils.endElement(contentHandler, "periode"); 962 } 963 964 /** 965 * Sax the XML tag <debut> 966 * <br> 00000000 if the start date is not known. AAAA0000 for a year format, AAAAMM00 for a year/month format, AAAAMMDD for a year/month/day format 967 * @param contentHandler the content handler 968 * @param program the program to sax 969 * @param additionalParameters the additional parameters 970 * @throws SAXException if a saxing exception occurred 971 */ 972 protected void _saxProgramPeriodStartDate(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 973 { 974 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); 975 LocalDate teachingStart = program.getTeachingStart(); 976 LHEOUtils.createMandatoryLHEOElement(contentHandler, program, "debut", teachingStart != null ? formatter.format(teachingStart) : null, 8, 8); 977 } 978 979 /** 980 * Sax the XML tag <fin> 981 * <br> 99999999 if the end date is not known. AAAA0000 for a year format, AAAAMM00 for a year/month format, AAAAMMDD for a year/month/day format 982 * @param contentHandler the content handler 983 * @param program the program to sax 984 * @param additionalParameters the additional parameters 985 * @throws SAXException if a saxing exception occurred 986 */ 987 protected void _saxProgramPeriodEndDate(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 988 { 989 // No end date in default implementation 990 LHEOUtils.createLHEOElement(contentHandler, program, "fin", "99999999"); 991 } 992 993 /** 994 * Sax for period the XML tag <extras> 995 * <br>Can contains all not LHEO normalized elements 996 * @param contentHandler the content handler 997 * @param program the program to sax 998 * @param additionalParameters the additional parameters 999 * @throws SAXException if a saxing exception occurred 1000 */ 1001 protected void _saxPeriodExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1002 { 1003 // No extras in default implementation 1004 XMLUtils.createElement(contentHandler, "extras"); 1005 } 1006 1007 /** 1008 * Sax the XML tag <adresse-inscription> 1009 * <br>Can contain the following XML tags: 1010 * <br>[1,1] <adresse> 1011 * <br>[0,N] <extras> 1012 * @param contentHandler the content handler 1013 * @param program the program to sax 1014 * @param additionalParameters the additional parameters 1015 * @throws SAXException if a saxing exception occurred 1016 */ 1017 protected void _saxProgramRegistrationAddress(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1018 { 1019 XMLUtils.startElement(contentHandler, "adresse-inscription"); 1020 1021 // <adresse> 1022 _saxRegistrationAddress(contentHandler, program, additionalParameters); 1023 1024 // <extras> 1025 _saxRegistrationAddressExtras(contentHandler, program, additionalParameters); 1026 1027 XMLUtils.endElement(contentHandler, "adresse-inscription"); 1028 } 1029 1030 /** 1031 * Sax the XML tag <adresse> 1032 * <br>Can contain the following XML tags: 1033 * <br>[1,4] <ligne> 1034 * <br>[1,1] <codepostal> 1035 * <br>[1,1] <ville> 1036 * <br>[0,1] <departement> 1037 * <br>[0,1] <code-INSEE-commune> 1038 * <br>[0,1] <code-INSEE-canton> 1039 * <br>[0,1] <region> 1040 * <br>[0,1] <pays> 1041 * <br>[0,1] <geolocalisation> 1042 * <br>[0,N] <extras> 1043 * @param contentHandler the content handler 1044 * @param program the program to sax 1045 * @param additionalParameters the additional parameters 1046 * @throws SAXException if a saxing exception occurred 1047 */ 1048 protected void _saxRegistrationAddress(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1049 { 1050 Optional<Person> contactOpt = program.getContacts() 1051 .stream() 1052 .filter(StringUtils::isNotBlank) 1053 .map(id -> _getPerson(id)) 1054 .filter(Objects::nonNull) 1055 .findFirst(); 1056 1057 XMLUtils.startElement(contentHandler, "adresse"); 1058 1059 Content contentSaxed = contactOpt.isPresent() ? contactOpt.get() : program; 1060 String address = contactOpt.isPresent() ? contactOpt.get().getValue("address") : null; 1061 String zipCode = contactOpt.isPresent() ? contactOpt.get().getValue("zipCode") : null; 1062 String town = contactOpt.isPresent() ? contactOpt.get().getValue("town") : null; 1063 1064 LHEOUtils.createAddressLHEOElements( 1065 contentHandler, 1066 contentSaxed, 1067 address, // ligne 1068 zipCode, // codepostal 1069 town, // ville 1070 null, // departement 1071 null, // code-INSEE-commune 1072 null, // code-INSEE-canton 1073 null, // region 1074 null, // pays 1075 null, // geolocalisation/latitude 1076 null // geolocalisation/longitude 1077 ); 1078 XMLUtils.endElement(contentHandler, "adresse"); 1079 } 1080 1081 /** 1082 * Sax for registration address the XML tag <extras> 1083 * <br>Can contains all not LHEO normalized elements 1084 * @param contentHandler the content handler 1085 * @param program the program to sax 1086 * @param additionalParameters the additional parameters 1087 * @throws SAXException if a saxing exception occurred 1088 */ 1089 protected void _saxRegistrationAddressExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1090 { 1091 // No extras in default implementation 1092 XMLUtils.createElement(contentHandler, "extras"); 1093 } 1094 1095 /** 1096 * Sax for action the XML tag <extras> 1097 * <br>Can contains all not LHEO normalized elements 1098 * @param contentHandler the content handler 1099 * @param program the program to sax 1100 * @param additionalParameters the additional parameters 1101 * @throws SAXException if a saxing exception occurred 1102 */ 1103 protected void _saxSessionExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1104 { 1105 // No extras in default implementation 1106 XMLUtils.createElement(contentHandler, "extras"); 1107 } 1108 1109 /** 1110 * Sax the XML tag <langue-formation> 1111 * <br>The value contains exactly 2 characters 1112 * @param contentHandler the content handler 1113 * @param program the program to sax 1114 * @param additionalParameters the additional parameters 1115 * @throws SAXException if a saxing exception occurred 1116 */ 1117 protected void _saxProgramEducationLanguage(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1118 { 1119 Optional<String> languageOpt = Stream.of(program.getEducationLanguage()) 1120 .filter(StringUtils::isNotBlank) 1121 .map(id -> _getRefContent(id)) 1122 .filter(Objects::nonNull) 1123 .map(c -> (String) c.getValue("code")) 1124 .filter(StringUtils::isNotBlank) 1125 .findFirst(); 1126 1127 LHEOUtils.createLHEOElement(contentHandler, program, "langue-formation", languageOpt.isPresent() ? languageOpt.get() : null, 2, 2); 1128 } 1129 1130 /** 1131 * Sax the XML tag <modalites-recrutement> 1132 * <br>The value contains between 1 to 3000 characters 1133 * @param contentHandler the content handler 1134 * @param program the program to sax 1135 * @param additionalParameters the additional parameters 1136 * @throws SAXException if a saxing exception occurred 1137 */ 1138 protected void _saxProgramAccessCondition(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1139 { 1140 String richText2String = _richText2String(program.getAccessCondition()); 1141 LHEOUtils.createLHEOElement(contentHandler, program, "modalites-recrutement", richText2String, 0, 3000); 1142 } 1143 1144 /** 1145 * Sax for action the XML tag <extras> 1146 * <br>Can contains all not LHEO normalized elements 1147 * @param contentHandler the content handler 1148 * @param program the program to sax 1149 * @param additionalParameters the additional parameters 1150 * @throws SAXException if a saxing exception occurred 1151 */ 1152 protected void _saxActionExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1153 { 1154 // No extras in default implementation 1155 XMLUtils.createElement(contentHandler, "extras"); 1156 } 1157 1158 /** 1159 * Sax the XML tag <organisme-formation-responsable> 1160 * <br>Can contain the following XML tags: 1161 * <br>[1,1] <numero-activite> 1162 * <br>[1,1] <SIRET-organisme-formation> 1163 * <br>[1,1] <nom-organisme> 1164 * <br>[1,1] <raison-sociale> 1165 * <br>[1,1] <coordonnees-organisme> 1166 * <br>[1,1] <contact-organisme> 1167 * <br>[0,1] <renseignements-specifiques> 1168 * <br>[0,1] <potentiel> 1169 * <br>[0,N] <extras> 1170 * @param contentHandler the content handler 1171 * @param program the program to sax 1172 * @param additionalParameters the additional parameters 1173 * @throws SAXException if a saxing exception occurred 1174 */ 1175 protected void _saxProgramResponsibleOrgUnit(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1176 { 1177 XMLUtils.startElement(contentHandler, "organisme-formation-responsable"); 1178 1179 // <numero-activite> 1180 _saxProgramActivityNumber(contentHandler, program, additionalParameters); 1181 1182 // <SIRET-organisme-formation> 1183 _saxProgramSIRETInformation(contentHandler, program, additionalParameters); 1184 1185 // <nom-organisme> 1186 _saxProgramOrgUnitName(contentHandler, program, additionalParameters); 1187 1188 // <raison-sociale> 1189 _saxProgramCorporateName(contentHandler, program, additionalParameters); 1190 1191 // <coordonnees-organisme> 1192 _saxProgramOrgUnitDetails(contentHandler, program, additionalParameters); 1193 1194 // <contact-organisme> 1195 _saxProgramContactOrgUnit(contentHandler, program, additionalParameters); 1196 1197 // <extras> 1198 _saxResponsibleOrgUnitExtras(contentHandler, program, additionalParameters); 1199 1200 XMLUtils.endElement(contentHandler, "organisme-formation-responsable"); 1201 } 1202 1203 /** 1204 * Sax the XML tag <numero-activite> 1205 * <br>The value contains exactly 11 characters 1206 * @param contentHandler the content handler 1207 * @param program the program to sax 1208 * @param additionalParameters the additional parameters 1209 * @throws SAXException if a saxing exception occurred 1210 */ 1211 protected void _saxProgramActivityNumber(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1212 { 1213 // In default implementation, the program activity number value is always '00000000000' 1214 LHEOUtils.createLHEOElement(contentHandler, program, "numero-activite", "00000000000"); 1215 } 1216 1217 /** 1218 * Sax the XML tag <SIRET-organisme-formation> 1219 * <br>Can contain the following XML tags: 1220 * <br>[1,1] <SIRET> 1221 * <br>[0,N] <extras> 1222 * @param contentHandler the content handler 1223 * @param program the program to sax 1224 * @param additionalParameters the additional parameters 1225 * @throws SAXException if a saxing exception occurred 1226 */ 1227 protected void _saxProgramSIRETInformation(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1228 { 1229 XMLUtils.startElement(contentHandler, "SIRET-organisme-formation"); 1230 1231 // <SIRET> 1232 _saxProgramSIRET(contentHandler, program, additionalParameters); 1233 1234 // <extras> 1235 _saxSIRETInformationExtras(contentHandler, program, additionalParameters); 1236 1237 XMLUtils.endElement(contentHandler, "SIRET-organisme-formation"); 1238 } 1239 1240 /** 1241 * Sax the XML tag <SIRET> 1242 * <br>The value contains exactly 14 characters 1243 * @param contentHandler the content handler 1244 * @param program the program to sax 1245 * @param additionalParameters the additional parameters 1246 * @throws SAXException if a saxing exception occurred 1247 */ 1248 protected void _saxProgramSIRET(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1249 { 1250 Optional<OrgUnit> orgUnit = program.getOrgUnits() 1251 .stream() 1252 .filter(StringUtils::isNotBlank) 1253 .map(id -> _getOrgUnit(id)) 1254 .filter(Objects::nonNull) 1255 .findFirst(); 1256 1257 LHEOUtils.createMandatoryLHEOElement(contentHandler, orgUnit.isPresent() ? orgUnit.get() : program, "SIRET", orgUnit.isPresent() ? orgUnit.get().getSIRET() : null, 14, 14); 1258 } 1259 1260 /** 1261 * Sax for SIRET information the XML tag <extras> 1262 * <br>Can contains all not LHEO normalized elements 1263 * @param contentHandler the content handler 1264 * @param program the program to sax 1265 * @param additionalParameters the additional parameters 1266 * @throws SAXException if a saxing exception occurred 1267 */ 1268 protected void _saxSIRETInformationExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1269 { 1270 // No extras in default implementation 1271 XMLUtils.createElement(contentHandler, "extras"); 1272 } 1273 1274 /** 1275 * Sax the XML tag <nom-organisme> 1276 * <br>The value contains between 1 to 255 characters 1277 * @param contentHandler the content handler 1278 * @param program the program to sax 1279 * @param additionalParameters the additional parameters 1280 * @throws SAXException if a saxing exception occurred 1281 */ 1282 protected void _saxProgramOrgUnitName(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1283 { 1284 Optional<OrgUnit> orgUnit = program.getOrgUnits() 1285 .stream() 1286 .filter(StringUtils::isNotBlank) 1287 .map(id -> _getOrgUnit(id)) 1288 .filter(Objects::nonNull) 1289 .findFirst(); 1290 1291 LHEOUtils.createMandatoryLHEOElement(contentHandler, orgUnit.isPresent() ? orgUnit.get() : program, "nom-organisme", orgUnit.isPresent() ? orgUnit.get().getTitle() : null, 1, 255); 1292 } 1293 1294 /** 1295 * Sax the XML tag <raison-sociale> 1296 * <br>The value contains between 1 to 255 characters 1297 * @param contentHandler the content handler 1298 * @param program the program to sax 1299 * @param additionalParameters the additional parameters 1300 * @throws SAXException if a saxing exception occurred 1301 */ 1302 protected void _saxProgramCorporateName(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1303 { 1304 Optional<OrgUnit> orgUnit = program.getOrgUnits() 1305 .stream() 1306 .filter(StringUtils::isNotBlank) 1307 .map(id -> _getOrgUnit(id)) 1308 .filter(Objects::nonNull) 1309 .findFirst(); 1310 1311 LHEOUtils.createMandatoryLHEOElement(contentHandler, orgUnit.isPresent() ? orgUnit.get() : program, "raison-sociale", orgUnit.isPresent() ? orgUnit.get().getTitle() : null, 1, 255); 1312 } 1313 1314 /** 1315 * Sax the XML tag <coordonnees-organisme> 1316 * <br>Can contain the following XML tags: 1317 * <br>[1,1] <coordonnees> 1318 * <br>[0,N] <extras> 1319 * @param contentHandler the content handler 1320 * @param program the program to sax 1321 * @param additionalParameters the additional parameters 1322 * @throws SAXException if a saxing exception occurred 1323 */ 1324 protected void _saxProgramOrgUnitDetails(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1325 { 1326 XMLUtils.startElement(contentHandler, "coordonnees-organisme"); 1327 1328 // <coordonnees> 1329 _saxOrgUnitDetailsCoordinates(contentHandler, program, additionalParameters); 1330 1331 // <extras> 1332 _saxOrgUnitDetailsExtras(contentHandler, program, additionalParameters); 1333 1334 XMLUtils.endElement(contentHandler, "coordonnees-organisme"); 1335 } 1336 1337 /** 1338 * Sax for orgUnit details the XML tag <coordonnees> 1339 * <br>Can contain the following XML tags: 1340 * <br>[0,1] <civilite> 1341 * <br>[0,1] <nom> 1342 * <br>[0,1] <prenom> 1343 * <br>[0,3] <ligne> 1344 * <br>[0,1] <adresse> 1345 * <br>[0,1] <telfixe> 1346 * <br>[0,1] <portable> 1347 * <br>[0,1] <fax> 1348 * <br>[0,1] <courriel> 1349 * <br>[0,1] <web> 1350 * <br>[0,N] <extras> 1351 * @param contentHandler the content handler 1352 * @param program the program to sax 1353 * @param additionalParameters the additional parameters 1354 * @throws SAXException if a saxing exception occurred 1355 */ 1356 protected void _saxOrgUnitDetailsCoordinates(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1357 { 1358 XMLUtils.startElement(contentHandler, "coordonnees"); 1359 1360 Optional<Person> personOpt = program.getOrgUnits() 1361 .stream() 1362 .filter(StringUtils::isNotBlank) 1363 .map(id -> _getOrgUnit(id)) 1364 .filter(Objects::nonNull) 1365 .map(OrgUnit::getContacts) 1366 .flatMap(List::stream) 1367 .filter(StringUtils::isNotBlank) 1368 .map(id -> _getPerson(id)) 1369 .filter(Objects::nonNull) 1370 .findFirst(); 1371 1372 if (personOpt.isPresent()) 1373 { 1374 Person person = personOpt.get(); 1375 _saxPersonCoordinate(contentHandler, person, additionalParameters); 1376 } 1377 1378 XMLUtils.endElement(contentHandler, "coordonnees"); 1379 } 1380 1381 /** 1382 * Sax for orgUnit details the XML tag <extras> 1383 * <br>Can contains all not LHEO normalized elements 1384 * @param contentHandler the content handler 1385 * @param program the program to sax 1386 * @param additionalParameters the additional parameters 1387 * @throws SAXException if a saxing exception occurred 1388 */ 1389 protected void _saxOrgUnitDetailsExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1390 { 1391 // No extras in default implementation 1392 XMLUtils.createElement(contentHandler, "extras"); 1393 } 1394 1395 /** 1396 * Sax the XML tag <contact-organisme> 1397 * <br>Can contain the following XML tags: 1398 * <br>[1,1] <coordonnees> 1399 * <br>[0,N] <extras> 1400 * @param contentHandler the content handler 1401 * @param program the program to sax 1402 * @param additionalParameters the additional parameters 1403 * @throws SAXException if a saxing exception occurred 1404 */ 1405 protected void _saxProgramContactOrgUnit(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1406 { 1407 XMLUtils.startElement(contentHandler, "contact-organisme"); 1408 1409 // <coordonnees> 1410 _saxContactOrgUnitCoordinates(contentHandler, program, additionalParameters); 1411 1412 // <extras> 1413 _saxContactOrgUnitExtras(contentHandler, program, additionalParameters); 1414 1415 XMLUtils.endElement(contentHandler, "contact-organisme"); 1416 } 1417 1418 /** 1419 * Sax for contact orgUnit the XML tag <coordonnees> 1420 * <br>Can contain the following XML tags: 1421 * <br>[0,1] <civilite> 1422 * <br>[0,1] <nom> 1423 * <br>[0,1] <prenom> 1424 * <br>[0,3] <ligne> 1425 * <br>[0,1] <adresse> 1426 * <br>[0,1] <telfixe> 1427 * <br>[0,1] <portable> 1428 * <br>[0,1] <fax> 1429 * <br>[0,1] <courriel> 1430 * <br>[0,1] <web> 1431 * <br>[0,N] <extras> 1432 * @param contentHandler the content handler 1433 * @param program the program to sax 1434 * @param additionalParameters the additional parameters 1435 * @throws SAXException if a saxing exception occurred 1436 */ 1437 protected void _saxContactOrgUnitCoordinates(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1438 { 1439 XMLUtils.startElement(contentHandler, "coordonnees"); 1440 1441 Optional<Person> personOpt = program.getContacts() 1442 .stream() 1443 .filter(StringUtils::isNotBlank) 1444 .map(id -> _getPerson(id)) 1445 .filter(Objects::nonNull) 1446 .findFirst(); 1447 1448 if (personOpt.isPresent()) 1449 { 1450 Person person = personOpt.get(); 1451 _saxPersonCoordinate(contentHandler, person, additionalParameters); 1452 } 1453 1454 XMLUtils.endElement(contentHandler, "coordonnees"); 1455 } 1456 1457 /** 1458 * Sax for contact orgUnit the XML tag <extras> 1459 * <br>Can contains all not LHEO normalized elements 1460 * @param contentHandler the content handler 1461 * @param program the program to sax 1462 * @param additionalParameters the additional parameters 1463 * @throws SAXException if a saxing exception occurred 1464 */ 1465 protected void _saxContactOrgUnitExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1466 { 1467 // No extras in default implementation 1468 XMLUtils.createElement(contentHandler, "extras"); 1469 } 1470 1471 /** 1472 * Sax for responsible orgUnit the XML tag <extras> 1473 * <br>Can contains all not LHEO normalized elements 1474 * @param contentHandler the content handler 1475 * @param program the program to sax 1476 * @param additionalParameters the additional parameters 1477 * @throws SAXException if a saxing exception occurred 1478 */ 1479 protected void _saxResponsibleOrgUnitExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1480 { 1481 // No extras in default implementation 1482 XMLUtils.createElement(contentHandler, "extras"); 1483 } 1484 1485 /** 1486 * Sax the XML tag <code-RNCP> 1487 * <br>The value contains between 1 and 6 characters 1488 * @param contentHandler the content handler 1489 * @param program the program to sax 1490 * @param additionalParameters the additional parameters 1491 * @throws SAXException if a saxing exception occurred 1492 */ 1493 protected void _saxProgramRNCPCode(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1494 { 1495 Optional<String> rncpCode = Stream.of(program.getRncpCode()) 1496 .filter(StringUtils::isNotBlank) 1497 .findFirst(); 1498 1499 LHEOUtils.createLHEOElement(contentHandler, program, "code-RNCP", rncpCode.isPresent() ? rncpCode.get() : null, 1, 6); 1500 } 1501 1502 /** 1503 * Sax the XML tag <code-CERTIFINFO> 1504 * <br>The value contains between 1 and 6 characters 1505 * @param contentHandler the content handler 1506 * @param program the program to sax 1507 * @param additionalParameters the additional parameters 1508 * @throws SAXException if a saxing exception occurred 1509 */ 1510 protected void _saxProgramCERTIFINFOCode(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1511 { 1512 // No CERTIFINFO code in default implementation 1513 } 1514 1515 /** 1516 * Sax for certification the XML tag <extras> 1517 * <br>Can contains all not LHEO normalized elements 1518 * @param contentHandler the content handler 1519 * @param program the program to sax 1520 * @param additionalParameters the additional parameters 1521 * @throws SAXException if a saxing exception occurred 1522 */ 1523 protected void _saxCertificationExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1524 { 1525 // No extras in default implementation 1526 XMLUtils.createElement(contentHandler, "extras"); 1527 } 1528 1529 /** 1530 * Sax for programs the XML tag <extras> 1531 * <br>Can contains all not LHEO normalized elements 1532 * @param contentHandler the content handler 1533 * @param program the program to sax 1534 * @param additionalParameters the additional parameters 1535 * @throws SAXException if a saxing exception occurred 1536 */ 1537 protected void _saxProgramsExtras(ContentHandler contentHandler, Program program, Map<String, Object> additionalParameters) throws SAXException 1538 { 1539 // No extras in default implementation 1540 XMLUtils.createElement(contentHandler, "extras"); 1541 } 1542 1543 /** 1544 * Sax for offers the XML tag <extras> 1545 * <br>Can contains all not LHEO normalized elements 1546 * @param contentHandler the content handler 1547 * @param programs the list of program to sax 1548 * @param additionalParameters the additional parameters 1549 * @throws SAXException if a saxing exception occurred 1550 */ 1551 protected void _saxOffersExtras(ContentHandler contentHandler, List<Program> programs, Map<String, Object> additionalParameters) throws SAXException 1552 { 1553 // No extras in default implementation 1554 XMLUtils.createElement(contentHandler, "extras"); 1555 } 1556 1557 /** 1558 * Sax LHEO elements of a ametys person for the XML tag >coordonnees< 1559 * @param contentHandler the content handler 1560 * @param contact the person contact 1561 * @param additionalParameters the additional parameters 1562 * @throws SAXException if a saxing exception occurred 1563 */ 1564 protected void _saxPersonCoordinate(ContentHandler contentHandler, Person contact, Map<String, Object> additionalParameters) throws SAXException 1565 { 1566 LHEOUtils.createCoordinateLHEOElementsPart1( 1567 contentHandler, 1568 contact, 1569 contact.getValue("personTitle"), // civilite 1570 contact.getValue("lastName"), // nom 1571 contact.getValue("givenName"), // prenom 1572 (String) contact.getValue("address") // ligne 1573 ); 1574 1575 XMLUtils.startElement(contentHandler, "adresse"); 1576 LHEOUtils.createAddressLHEOElements( 1577 contentHandler, 1578 contact, 1579 (String) contact.getValue("address"), // ligne 1580 contact.getValue("zipCode"), // codepostal 1581 contact.getValue("town"), // ville 1582 null, // departement 1583 null, // code-INSEE-commune 1584 null, // code-INSEE-canton 1585 null, // region 1586 null, // pays 1587 null, // geolocalisation/latitude 1588 null // geolocalisation/longitude 1589 ); 1590 XMLUtils.endElement(contentHandler, "adresse"); 1591 1592 LHEOUtils.createCoordinateLHEOElementsPart2( 1593 contentHandler, 1594 contact, 1595 contact.getValue("phone"), // telfix 1596 null, // portable 1597 contact.getValue("fax"), //fax 1598 contact.getValue("mail"), // courriel 1599 contact.getValue("webLinkUrl") // web 1600 ); 1601 } 1602 1603 /** 1604 * Get ref content from id 1605 * @param id the ref content id 1606 * @return the ref content. Null if no exist 1607 */ 1608 protected Content _getRefContent(String id) 1609 { 1610 try 1611 { 1612 return _resolver.resolveById(id); 1613 } 1614 catch (Exception e) 1615 { 1616 getLogger().warn("Can't find person with id " + id, e); 1617 return null; 1618 } 1619 } 1620 1621 /** 1622 * Get person from id 1623 * @param id the person id 1624 * @return the person content. Null if no exist 1625 */ 1626 protected Person _getPerson(String id) 1627 { 1628 try 1629 { 1630 return _resolver.resolveById(id); 1631 } 1632 catch (Exception e) 1633 { 1634 getLogger().warn("Can't find person with id " + id, e); 1635 return null; 1636 } 1637 } 1638 1639 /** 1640 * Get orgUnit from id 1641 * @param id the orgUnit id 1642 * @return the orgUnit content. Null if no exist 1643 */ 1644 protected OrgUnit _getOrgUnit(String id) 1645 { 1646 try 1647 { 1648 return _resolver.resolveById(id); 1649 } 1650 catch (Exception e) 1651 { 1652 getLogger().warn("Can't find orgUnit with id " + id, e); 1653 return null; 1654 } 1655 } 1656 1657 /** 1658 * Convert rich-text to string for LHEO 1659 * @param richText the rich-text 1660 * @return the transformed rich-text 1661 */ 1662 protected String _richText2String(RichText richText) 1663 { 1664 return richText != null ? _richTextHelper.richTextToString(richText) : null; 1665 } 1666}