001/* 002 * Copyright 2022 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 */ 016 017package org.ametys.plugins.odfsync.pegase.ws.structure; 018 019import java.io.IOException; 020import java.math.BigDecimal; 021import java.util.HashMap; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Map; 025import java.util.Optional; 026import java.util.Set; 027import java.util.regex.Pattern; 028import java.util.stream.Collectors; 029import java.util.stream.Stream; 030 031import org.apache.avalon.framework.activity.Initializable; 032import org.apache.avalon.framework.component.Component; 033import org.apache.avalon.framework.service.ServiceException; 034import org.apache.avalon.framework.service.ServiceManager; 035import org.apache.commons.lang3.StringUtils; 036 037import org.ametys.cms.data.ContentValue; 038import org.ametys.cms.data.RichText; 039import org.ametys.cms.data.RichTextHelper; 040import org.ametys.cms.repository.Content; 041import org.ametys.odf.ODFHelper; 042import org.ametys.odf.ProgramItem; 043import org.ametys.odf.course.Course; 044import org.ametys.odf.course.CourseFactory; 045import org.ametys.odf.courselist.CourseList; 046import org.ametys.odf.enumeration.OdfReferenceTableEntry; 047import org.ametys.odf.enumeration.OdfReferenceTableHelper; 048import org.ametys.odf.program.AbstractProgram; 049import org.ametys.odf.program.Container; 050import org.ametys.odf.program.Program; 051import org.ametys.odf.program.ProgramFactory; 052import org.ametys.odf.program.ProgramPart; 053import org.ametys.odf.program.SubProgram; 054import org.ametys.plugins.odfsync.export.AbstractExportStructure; 055import org.ametys.plugins.odfsync.export.ExportReport; 056import org.ametys.plugins.odfsync.export.ExportReport.ExportStatus; 057import org.ametys.plugins.odfsync.export.ExportReport.ProblemTypes; 058import org.ametys.plugins.odfsync.pegase.ws.PegaseApiManager; 059import org.ametys.plugins.odfsync.pegase.ws.PegaseExportException; 060import org.ametys.runtime.config.Config; 061import org.ametys.runtime.i18n.I18nizableText; 062import org.ametys.runtime.model.ElementDefinition; 063 064import fr.pcscol.pegase.odf.ApiException; 065import fr.pcscol.pegase.odf.externe.model.Formation; 066import fr.pcscol.pegase.odf.externe.model.Groupement; 067import fr.pcscol.pegase.odf.externe.model.Pageable; 068 069/** 070 * The structure to export the program in Pegase 071 * 072 * TODO rewrite completely for Pegase 24 073 */ 074public class PegaseProgramStructure extends AbstractExportStructure implements Component, Initializable 075{ 076 /** Role */ 077 public static final String ROLE = PegaseProgramStructure.class.getName(); 078// 079// /** The attribute name for the code Pégase */ 080// public static final String CODE_PEGASE_ATTRIBUTE_NAME = "codePegase"; 081// 082// /* Constants */ 083// private static final String __PEGASE_SYNC_CODE = "pegaseSyncCode"; 084// private static final Pattern __PROGRAM_CODE_PATTERN = Pattern.compile("^[A-Z0-9\\-]{3,25}(/[1-9][0-9]*)?$"); 085// private static final Pattern __DEFAULT_CODE_PATTERN = Pattern.compile("^[A-Z0-9\\-]{3,25}$"); 086// private static final String __CODE_FORMATION_DIPLOMANTE = "0"; 087// private static final Map<String, Set<String>> __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE = new HashMap<>(); 088// static 089// { 090// __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put( 091// ProgramFactory.PROGRAM_CONTENT_TYPE, 092// Set.of( 093// AbstractProgram.DOMAIN, 094// AbstractProgram.EDUCATION_KIND, 095// AbstractProgram.DEGREE, 096// AbstractProgram.LEVEL, 097// AbstractProgram.RNCP_LEVEL 098// ) 099// ); 100// __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put( 101// CourseFactory.COURSE_CONTENT_TYPE, 102// Set.of(Course.COURSE_TYPE) 103// ); 104// __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.put( 105// OdfReferenceTableHelper.DEGREE, 106// Set.of( 107// "degreeNature", 108// "cursus" 109// ) 110// ); 111// } 112// 113// /* Components */ 114// private PegaseApiManager _pegaseApiManager; 115// private ODFHelper _odfHelper; 116// private RichTextHelper _richTextHelper; 117// 118// /* Pégase configuration */ 119// private boolean _isActive; 120// private String _structureCode; 121// private boolean _trustAmetys; 122 123 @Override 124 public void service(ServiceManager manager) throws ServiceException 125 { 126 super.service(manager); 127 128// _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 129// _richTextHelper = (RichTextHelper) manager.lookup(RichTextHelper.ROLE); 130// _pegaseApiManager = (PegaseApiManager) manager.lookup(PegaseApiManager.ROLE); 131 } 132 133 public void initialize() throws Exception 134 { 135// _isActive = Config.getInstance().getValue("pegase.activate", true, false); 136// if (_isActive) 137// { 138// _structureCode = Config.getInstance().getValue("pegase.structure.code"); 139// _trustAmetys = Config.getInstance().getValue("pegase.trust", true, false); 140// } 141 } 142 143// private String _getPegaseCodeOrCode(Content content) 144// { 145// String code = content.getValue(CODE_PEGASE_ATTRIBUTE_NAME); 146// if (StringUtils.isEmpty(code)) 147// { 148// code = content.getValue(OdfReferenceTableEntry.CODE); 149// } 150// return code; 151// } 152// 153// private String _getPegaseCodeOrCodeOfAttribute(Content content, String attributeName) 154// { 155// return _getContentValue(content, attributeName) 156// .map(this::_getPegaseCodeOrCode) 157// .orElse(null); 158// } 159// 160// private void _addMandatoryDataPathAndReport(Content content, String dataPath, ExportReport report) 161// { 162// I18nizableText invalidMessage = new I18nizableText( 163// "plugin.odf-sync", 164// "PLUGINS_ODF_SYNC_EXPORT_PEGASE_MANDATORY_FIELD", 165// Map.of("fieldName", content.getDefinition(dataPath).getLabel()) 166// ); 167// report.addInvalidDataPath(content, invalidMessage); 168// } 169// 170// private Optional<Content> _getContentValue(Content content, String attributeName) 171// { 172// return Optional.of(attributeName) 173// .map(content::<ContentValue>getValue) 174// .flatMap(ContentValue::getContentIfExists); 175// } 176// 177// private Stream<Content> _getContentValues(Content content, String attributeName) 178// { 179// return Optional.of(attributeName) 180// .map(content::<ContentValue[]>getValue) 181// .map(Stream::of) 182// .orElseGet(Stream::of) 183// .map(ContentValue::getContentIfExists) 184// .flatMap(Optional::stream); 185// } 186// 187 /** 188 * Checks if the program has all the required fields, their Pegase correspondence and that the program has a valid structure 189 * @param program the program 190 * @param report the Pegase export report 191 */ 192 @Override 193 public void checkProgram(Program program, ExportReport report) 194 { 195// if (!_isActive) 196// { 197// throw new UnsupportedOperationException("Pégase is not active in the configuration, you cannot check the program for the export."); 198// } 199// 200// try 201// { 202// _checkAttributes(program, report); 203// 204// if (program.hasValue(__PEGASE_SYNC_CODE)) 205// { 206// String codeAndVersion = program.getValue(__PEGASE_SYNC_CODE); 207// Map<String, Object> dataCodeAndVersion = _getCodeAndVersion(codeAndVersion); 208// String code = (String) dataCodeAndVersion.get("code"); 209// String versionString = (String) dataCodeAndVersion.get("version"); 210// 211// // If the code is not missing, check if it is valid 212// if (StringUtils.isNotBlank(versionString)) 213// { 214// BigDecimal version = new BigDecimal(versionString); 215// _checkProgramVersionCoherence(report, code, version); 216// } 217// } 218// 219// // If the education kind has a Pegase correspondence and is of code "0" (diplomante) 220// if (__CODE_FORMATION_DIPLOMANTE.equals(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.EDUCATION_KIND))) 221// { 222// _checkProgramDiplomanteField(program, report); 223// } 224// 225// _checkChildren(program, report); 226// 227// } 228// catch (IOException e) 229// { 230// report.updateStatus(ExportStatus.ERROR); 231// getLogger().error("Le jeton d'authentification à Pégase n'a pas pu être récupéré", e); 232// } 233 } 234// 235// private void _checkAttributes(Content content, ExportReport report) 236// { 237// if (content instanceof ProgramItem) 238// { 239// if (!content.hasValue(__PEGASE_SYNC_CODE)) 240// { 241// _addMandatoryDataPathAndReport(content, __PEGASE_SYNC_CODE, report); 242// } 243// else if (content instanceof Program) 244// { 245// if (!_matches(__PROGRAM_CODE_PATTERN, content, __PEGASE_SYNC_CODE)) 246// { 247// report.addInvalidDataPath(content, new I18nizableText("plugin.odf-sync", "PLUGINS_ODF_SYNC_EXPORT_PEGASE_INVALID_CODE_PROGRAM")); 248// } 249// } 250// else if (!_matches(__DEFAULT_CODE_PATTERN, content, __PEGASE_SYNC_CODE)) 251// { 252// report.addInvalidDataPath(content, new I18nizableText("plugin.odf-sync", "PLUGINS_ODF_SYNC_EXPORT_PEGASE_INVALID_CODE_DEFAULT")); 253// } 254// } 255// 256// String contentType = content.getTypes()[0]; 257// Set<String> mandatoryAttributes = __MANDATORY_ATTRIBUTES_BY_CONTENT_TYPE.getOrDefault(contentType, Set.of()); 258// for (String attribute : mandatoryAttributes) 259// { 260// if (!content.hasValue(attribute)) 261// { 262// _addMandatoryDataPathAndReport(content, attribute, report); 263// } 264// } 265// } 266// 267// private boolean _matches(Pattern regex, Content content, String attributeName) 268// { 269// return regex.matcher(content.getValue(attributeName)).matches(); 270// } 271// 272// private void _checkProgramVersionCoherence(ExportReport report, String code, BigDecimal version) throws IOException 273// { 274// // If the Program already exist in this version 275// ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code, version); 276// 277// Long versionLong = version.longValue(); 278// if (objetMaquette != null) 279// { 280// // If it is not of type "FORMATION" or if it is not editable 281// if (!objetMaquette.getType().getCode().equals("FORMATION") || !objetMaquette.getModifiable()) 282// { 283// report.setStatus(ExportStatus.NON_EDITABLE_PROGRAM_ALREADY_EXISTS); 284// } 285// } 286// 287// // If nothing was found for this code and version, and the version is not null 288// else 289// { 290// // Get the element for this code without requesting a specific version 291// objetMaquette = _getObjetMaquetteIfAlreadyExists(code); 292// 293// // If something was found and it's a Program 294// if (objetMaquette != null && objetMaquette.getType().getCode().equals("FORMATION")) 295// { 296// // Check if the version is compatible (versionFound == versionRequested or versionFound == versionRequested - 1) 297// Long versionFound = Long.valueOf(objetMaquette.getDetail().getFormation().getVersion()); 298// if (versionLong != versionFound && versionLong != (versionFound + 1)) 299// { 300// report.setStatus(ExportStatus.PROGRAM_IMPOSSIBLE_VERSION); 301// } 302// } 303// 304// // If something was found but it is not a Program 305// else if (objetMaquette != null && !objetMaquette.getType().getCode().equals("FORMATION")) 306// { 307// report.setStatus(ExportStatus.NON_EDITABLE_PROGRAM_ALREADY_EXISTS); 308// } 309// 310// // If nothing was found, check if the version requested is one 311// else if (versionLong != 1) 312// { 313// report.setStatus(ExportStatus.PROGRAM_IMPOSSIBLE_VERSION); 314// } 315// } 316// } 317// 318// private void _checkProgramDiplomanteField(Program program, ExportReport report) 319// { 320// // dataDegree which contains degree, cursus and degreeNature 321// _getContentValue(program, AbstractProgram.DEGREE) 322// .ifPresent(degree -> _checkAttributes(degree, report)); 323// } 324// 325// private void _checkChildren(ProgramItem programItem, ExportReport report) 326// { 327// for (ProgramItem child : _odfHelper.getChildProgramItems(programItem)) 328// { 329// _checkProgramItem(child, report); 330// } 331// } 332// 333// private void _checkChildrenOfYear(Container container, ExportReport report) 334// { 335// container.getProgramPartChildren() 336// .stream() 337// .filter(Container.class::isInstance) 338// .map(Container.class::cast) 339// .filter(c -> "annee".equals(getContainerNatureCode(c))) 340// .forEach( 341// child -> 342// { 343// report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID); 344// getLogger().error("L'élément {} (Année) ne peut avoir comme enfant une année : {}", container.getTitle(), child.getTitle()); 345// } 346// ); 347// } 348// 349// private void _checkChildrenOfSemester(Container container, ExportReport report) 350// { 351// container.getProgramPartChildren() 352// .stream() 353// .filter(Container.class::isInstance) 354// .map(Container.class::cast) 355// .filter(c -> 356// { 357// String nature = getContainerNatureCode(c); 358// return "annee".equals(nature) || "semestre".equals(nature); 359// }) 360// .forEach( 361// child -> 362// { 363// report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID); 364// getLogger().error("L'élément {} (Semestre) ne peut avoir comme enfant une année ou un semestre : {}", container.getTitle(), child.getTitle()); 365// } 366// ); 367// } 368// 369// private void _checkChildrenOfSubProgram(SubProgram subProgram, ExportReport report) 370// { 371// for (ProgramItem child : _odfHelper.getChildProgramItems(subProgram)) 372// { 373// // If the child is a SubProgram, then it is not compatible with the parent : SubProgram 374// if (child instanceof SubProgram childSubProgram) 375// { 376// report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID); 377// getLogger().error("L'élément {} (Parcours) ne peut avoir comme enfant un parcours : {}", subProgram.getTitle(), childSubProgram.getTitle()); 378// } 379// 380// _checkProgramItem(child, report); 381// } 382// } 383// 384// private void _checkProgramItem(ProgramItem programItem, ExportReport report) 385// { 386// _checkAttributes((Content) programItem, report); 387// 388// if (programItem instanceof CourseList couresList) 389// { 390// // Check if the courseList has children, because a Pegase group has to have at least one child 391// if (!couresList.hasCourses()) 392// { 393// getLogger().error("L'élément {} n'a pas d'enfant alors qu'il aurait dû être exporté en tant que groupement", couresList.getTitle()); 394// report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID); 395// } 396// } 397// else if (programItem instanceof Container container) 398// { 399// String childNatureCode = getContainerNatureCode(container); 400// 401// if ("annee".equals(childNatureCode)) 402// { 403// _checkChildrenOfYear(container, report); 404// } 405// else if ("semestre".equals(childNatureCode)) 406// { 407// _checkChildrenOfSemester(container, report); 408// } 409// else 410// { 411// // Check if the container (without a nature) has children, because a Pegase group has to have at least one child 412// if (!container.hasProgramPartChildren()) 413// { 414// getLogger().error("L'élément {} n'a pas d'enfant alors qu'il aurait dû être exporté en tant que groupement", container.getTitle()); 415// report.setStatus(ExportStatus.CONTENT_STRUCTURE_INVALID); 416// } 417// } 418// } 419// 420// else if (programItem instanceof SubProgram subProgram) 421// { 422// _checkChildrenOfSubProgram(subProgram, report); 423// } 424// 425// for (ProgramItem child : _odfHelper.getChildProgramItems(programItem)) 426// { 427// _checkProgramItem(child, report); 428// } 429// } 430// 431// private ObjetMaquette _getObjetMaquetteIfAlreadyExists(String code) throws IOException 432// { 433// return _getObjetMaquetteIfAlreadyExists(code, null); 434// } 435// 436// /** 437// * Get the latest version of an objetMaquette if it exists 438// * @param code The code wanted 439// * @param version The version wanted 440// * @return The ObjetMaquette wanted or null if it was not found 441// * @throws IOException If an error occurs while retrieving the token 442// */ 443// private ObjetMaquette _getObjetMaquetteIfAlreadyExists(String code, BigDecimal version) throws IOException 444// { 445// Pageable pageable = new Pageable(); 446// pageable.setPage(0); 447// pageable.setTaille(10); 448// pageable.setTri(List.of("version,desc")); 449// 450// PagedObjetMaquette pagedObjetMaquette; 451// try 452// { 453// // Get the objetMaquette for the code and the version 454// pagedObjetMaquette = _pegaseApiManager.getObjetsMaquetteApi().lireListeObjetsMaquette(_structureCode, null, null, null, code, null, null, null, null, null, null, version, null, null, null, null, null, null, pageable); 455// List<ObjetMaquette> objetsMaquette = pagedObjetMaquette.getItems(); 456// 457// // If it was found, return it 458// if (objetsMaquette.size() >= 1) 459// { 460// return objetsMaquette.get(0); 461// } 462// } 463// catch (ApiException e) 464// { 465// getLogger().warn("Une erreur est survenue lors la recherche de l'élément de code de synchronization Pégase {} pour vérifier son existance préalable dans Pégase", code, e); 466// } 467// 468// return null; 469// } 470// 471// private Map<String, Object> _getCodeAndVersion(String codeAndVersion) 472// { 473// Map<String, Object> result = new HashMap<>(); 474// 475// String code = codeAndVersion; 476// String version = null; 477// 478// if (codeAndVersion.contains("/")) 479// { 480// String[] codeAndVersionTab = codeAndVersion.split("/"); 481// if (codeAndVersionTab.length == 2) 482// { 483// code = codeAndVersionTab[0]; 484// version = codeAndVersionTab[1]; 485// } 486// } 487// 488// result.put("code", code); 489// result.put("version", version); 490// 491// return result; 492// } 493// 494// private boolean _isModifiable(ObjetMaquette objetMaquette, String code, ExportReport report) throws IOException 495// { 496// // If the object is not editable, return false 497// if (!objetMaquette.getModifiable()) 498// { 499// return false; 500// } 501// 502// // The object is editable, now we check if it is linked to this Program 503// List<FormationRef> parentPrograms = objetMaquette.getFormationsParentes(); 504// if (parentPrograms != null && parentPrograms.size() >= 1) 505// { 506// FormationRef parentProgram = parentPrograms.get(0); 507// 508// // If it is already linked to the Program, return true 509// if (report.getCodeParentProgram().equals(parentProgram.getCode()) && report.getVersionParentProgram() == parentProgram.getVersion()) 510// { 511// return true; 512// } 513// } 514// 515// // If the object is "mutualise" or orphan in Pégase then it can be linked to the Program 516// if (objetMaquette.getMutualise() || _isOrphan(code)) 517// { 518// return true; 519// } 520// 521// return false; 522// } 523// 524// private boolean _isOrphan(String code) throws IOException 525// { 526// PagedObjetMaquette pagedObjetMaquette; 527// try 528// { 529// // Try to get the objetMaquette for the code wanted and that are isolated 530// pagedObjetMaquette = _pegaseApiManager.getObjetsMaquetteApi().lireListeObjetsMaquette(_structureCode, null, null, null, code, null, null, null, true, null, null, null, null, null, null, null, null, null, null); 531// 532// List<ObjetMaquette> objetsMaquette = pagedObjetMaquette.getItems(); 533// 534// return objetsMaquette.size() >= 1; 535// } 536// catch (ApiException e) 537// { 538// getLogger().info("L'élément de code de synchronisation Pégase {} n'a pas pu être trouvé dans Pégase, nous ne pouvons donc pas vérifier si l'élément est isolé.", e); 539// } 540// 541// return false; 542// } 543// 544// private Enfant _createPegaseChild(Content child, String pegaseId) 545// { 546// Enfant pegaseChild = new Enfant(); 547// 548// pegaseChild.setDetails( 549// new EnfantDetails() 550// .libelle(child.getTitle()) 551// ); 552// 553// pegaseChild.setRef( 554// new Ref() 555// .id(pegaseId) 556// .code(child.getValue(__PEGASE_SYNC_CODE)) 557// ); 558// 559// return pegaseChild; 560// } 561// 562// private Enfant _createChild(Content content, ExportReport report) 563// { 564// boolean success = true; 565// try 566// { 567// String childPegaseId = _createPegaseInstance(content, report); 568// return _createPegaseChild(content, childPegaseId); 569// } 570// catch (Exception ex) 571// { 572// success = false; 573// getLogger().error("Erreur lors de l'export de l'élément {}", content.getTitle(), ex); 574// return null; 575// } 576// finally 577// { 578// if (success) 579// { 580// report.addElementExported(content); 581// } 582// } 583// } 584// 585// private String _createPegaseInstance(Content content, ExportReport report) throws PegaseExportException, IOException 586// { 587// // Conteneur : semestre, année -> OTT ou Groupement 588// if (content instanceof Container) 589// { 590// return _createOTTOrGroupFromContainer((Container) content, report); 591// } 592// 593// // Parcours -> OO 594// if (content instanceof SubProgram) 595// { 596// return _createOOFromSubProgram((SubProgram) content, report); 597// } 598// 599// // ELP -> OP 600// if (content instanceof Course) 601// { 602// return _createOPFromCourse((Course) content, report); 603// } 604// 605// // liste d'ELP -> Groupement 606// if (content instanceof CourseList) 607// { 608// return _createGroupFromCourseList((CourseList) content, report); 609// } 610// 611// return null; 612// } 613// 614// private Map<String, Enfant> _createAllChildren(Map<String, Enfant> children, List<ProgramItem> programItem, ExportReport report) 615// { 616// for (ProgramItem childContent : programItem) 617// { 618// Enfant containerChild = _createChild((Content) childContent, report); 619// 620// // If the child was created, add it to the list of children to attach 621// if (containerChild != null) 622// { 623// children.put(containerChild.getRef().getId(), containerChild); 624// } 625// } 626// 627// return children; 628// } 629// 630// private void _attachAllChildren(Content content, String pegaseId, Map<String, Enfant> children, ExportReport report) throws IOException 631// { 632// List<Enfant> childrenAlreadyAttached; 633// try 634// { 635// // Get the children already attached to the programItem 636// childrenAlreadyAttached = _pegaseApiManager.getObjetsMaquetteApi().lireEnfants(_structureCode, pegaseId); 637// 638// // If there are children already attached and the option trustAmetys is checked 639// if (childrenAlreadyAttached != null && _trustAmetys) 640// { 641// // For every child already attached 642// for (Enfant child : childrenAlreadyAttached) 643// { 644// // Try to detach it 645// try 646// { 647// _pegaseApiManager.getObjetsMaquetteApi().detacherEnfant(_structureCode, pegaseId, child.getRef().getId()); 648// } 649// catch (ApiException e) 650// { 651// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR, content); 652// getLogger().warn("L'enfant de code Pégase {} de l'élément {} n'a pas pu être détaché dans Pégase", child.getRef().getCode(), content.getTitle(), e); 653// } 654// } 655// } 656// 657// // If the option trustAmetys is not checked 658// else if (childrenAlreadyAttached != null) 659// { 660// // For every child already attached 661// for (Enfant childAlreadyAttached : childrenAlreadyAttached) 662// { 663// // Remove it from the list of children to attach 664// children.remove(childAlreadyAttached.getRef().getId()); 665// } 666// } 667// 668// List<Enfant> childrenToAttach = List.copyOf(children.values()); 669// 670// // If there are children that need to be attached 671// if (!childrenToAttach.isEmpty()) 672// { 673// // Try to attach them 674// try 675// { 676// _pegaseApiManager.getObjetsMaquetteApi().attacherEnfant(_structureCode, pegaseId, childrenToAttach); 677// } 678// catch (ApiException ex) 679// { 680// report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content); 681// 682// String childrenFailedToAttach = ""; 683// 684// for (Enfant child : childrenToAttach) 685// { 686// childrenFailedToAttach += child.getRef().getCode() + ","; 687// } 688// 689// getLogger().warn("Une erreur est survenue lors de l'attachement des enfants ({}) à l'élément ({}) dans Pégase", childrenFailedToAttach, content.getTitle(), ex); 690// } 691// } 692// } 693// catch (ApiException e) 694// { 695// report.updateExportReport(ExportStatus.WARN, ProblemTypes.API_ERROR, content); 696// 697// getLogger().warn("Les liens avec les enfants de l'élément {} n'ont pas pu être traités car les enfants depuis Pégase n'ont pas pu être récupérés.", content.getTitle(), e); 698// } 699// } 700// 701// private void _attachAllChildrenGroupementCase(Content content, String pegaseId, Map<String, Enfant> children, ExportReport report) throws IOException 702// { 703// // If the list of children that need to be attached is empty, throw an Exception 704// if (children.isEmpty()) 705// { 706// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.GROUPEMENT_WITHOUT_CHILDREN, content); 707// 708// getLogger().warn("Aucuns des enfants de la liste d'elp ou le conteneur {}, devant être exporté en groupement, n'ont pu être exportés, les enfants de ce groupement resterons donc inchangés ", content.getTitle()); 709// } 710// else 711// { 712// List<Enfant> childenAlreadyAttached; 713// try 714// { 715// // Get the children already attached 716// childenAlreadyAttached = _pegaseApiManager.getObjetsMaquetteApi().lireEnfants(_structureCode, pegaseId); 717// List<String> childrenAttachedInTheEnd = List.copyOf(children.keySet()); 718// 719// // If there are children already attached 720// if (childenAlreadyAttached != null) 721// { 722// // For every child already attached 723// for (Enfant childAlreadyAttached : childenAlreadyAttached) 724// { 725// // Remove it from the list of children to attach 726// children.remove(childAlreadyAttached.getRef().getId()); 727// } 728// } 729// 730// List<Enfant> childrenToAttach = List.copyOf(children.values()); 731// 732// // If there are children to attach, try to attach them 733// if (!childrenToAttach.isEmpty()) 734// { 735// try 736// { 737// _pegaseApiManager.getObjetsMaquetteApi().attacherEnfant(_structureCode, pegaseId, childrenToAttach); 738// } 739// catch (ApiException ex) 740// { 741// report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content); 742// 743// if (getLogger().isWarnEnabled()) 744// { 745// getLogger().warn("Une erreur est survenue lors de l'attachement des enfants ({}) à l'élément ({}) dans Pégase", 746// childrenToAttach.stream() 747// .map(Enfant::getRef) 748// .map(Ref::getCode) 749// .distinct() 750// .collect(Collectors.joining(", ")), 751// content.getTitle(), 752// ex 753// ); 754// } 755// } 756// } 757// 758// // If the option trustAmetys is checked, try to detach the other children (the children that were already attached to the content 759// if (_trustAmetys && childenAlreadyAttached != null) 760// { 761// // For every child that was already there 762// for (Enfant child : childenAlreadyAttached) 763// { 764// String childId = child.getRef().getId(); 765// 766// // If it was not part of the children that needed to be attached, try to detach it 767// if (!childrenAttachedInTheEnd.contains(childId)) 768// { 769// try 770// { 771// _pegaseApiManager.getObjetsMaquetteApi().detacherEnfant(_structureCode, pegaseId, child.getRef().getId()); 772// } 773// catch (ApiException e) 774// { 775// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR, content); 776// 777// getLogger().warn("L'enfant de code Pégase {} de l'élément {} n'a pas pu être détaché dans Pégase", child.getRef().getCode(), content.getTitle(), e); 778// } 779// } 780// } 781// } 782// } 783// catch (ApiException e) 784// { 785// report.updateExportReport(ExportStatus.WARN, ProblemTypes.LINKS_MISSING, content); 786// 787// getLogger().warn("Les liens avec les enfants de l'élément ({}) n'ont pas pu être traités car les enfants depuis Pégase n'ont pas pu être récupérés.", content.getTitle(), e); 788// } 789// } 790// } 791// 792// private ObjetFormation _createObjetFormation(Content content, String type, ExportReport report) throws PegaseExportException, IOException 793// { 794// // Create the ObjetFormation 795// ObjetFormation objetFormation = new ObjetFormation(); 796// 797// String code = content.getValue(__PEGASE_SYNC_CODE); 798// String label = content.getTitle(); 799// 800// objetFormation.setCode(code); 801// 802// objetFormation.setLibelle(StringUtils.truncate(label, 50)); // le libellé court doit faire moins de 50 caractères 803// objetFormation.setLibelleLong(StringUtils.truncate(label, 150)); // le libellé long doit faire moins de 150 caractères 804// 805// ObjetFormationType ob = new ObjetFormationType(); 806// ob.setCode(type); 807// objetFormation.setType(ob); 808// 809// objetFormation.setMutualise(true); 810// 811// if (content.hasValue("ects")) 812// { 813// Double ects = null; 814// if (content instanceof AbstractProgram) 815// { 816// ects = _getContentValue(content, AbstractProgram.ECTS) 817// .map(c -> c.<String>getValue(OdfReferenceTableEntry.CODE)) 818// .map(Double::parseDouble) 819// .orElse(null); 820// } 821// else 822// { 823// ects = content.getValue("ects"); 824// } 825// 826// if (ects != null) 827// { 828// objetFormation.putChampsAdditionnelsItem("ECTS", new ValeurNum().valeur(ects)); 829// } 830// } 831// 832// Object desc = null; 833// if (content.hasValue("description")) 834// { 835// desc = content.getValue("description"); 836// } 837// else if (content.hasValue("presentation")) 838// { 839// desc = content.getValue("presentation"); 840// } 841// 842// if (desc != null) 843// { 844// RichText descRichText = (RichText) desc; 845// String description = _richTextHelper.richTextToString(descRichText); 846// objetFormation.setDescription(StringUtils.truncate(description, 2000)); // la description doit faire moins de 2000 caractères 847// } 848// 849// // Check if the object already exists 850// ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code); 851// if (objetMaquette != null) 852// { 853// // If it already exist, check if it can be edited 854// if (_isModifiable(objetMaquette, code, report)) 855// { 856// String id = objetMaquette.getId(); 857// objetFormation.setId(id); 858// 859// // Edit the already existing object 860// try 861// { 862// objetFormation = _pegaseApiManager.getObjetsFormationApi().modifierObjetFormation(_structureCode, id, objetFormation); 863// return objetFormation; 864// } 865// catch (ApiException e) 866// { 867// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED); 868// 869// throw new PegaseExportException("L'élément " + content.getTitle() + " n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 870// } 871// } 872// 873// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_ALREADY_EXIST); 874// 875// throw new PegaseExportException("Erreur lors de l'export de " + label + "Un élément avec le code " + code + " existe déjà et n'est pas mutualisable ou modifiable"); 876// } 877// 878// // If it did not already exist, create the object 879// try 880// { 881// objetFormation = _pegaseApiManager.getObjetsFormationApi().creerObjetFormation(_structureCode, objetFormation); 882// 883// return objetFormation; 884// } 885// catch (ApiException e) 886// { 887// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED); 888// 889// throw new PegaseExportException("L'élément " + content.getTitle() + " n'a pas pu être exporté dû à un problème rencontré avec Pégase", e); 890// } 891// } 892// 893// private Formation _createProgram(Program program, ExportReport report) throws PegaseExportException, IOException 894// { 895// Formation pegaseProgram = new Formation(); 896// 897// String codeAndVersion = program.getValue(__PEGASE_SYNC_CODE); 898// 899// Map<String, Object> dataCodeAndVersion = _getCodeAndVersion(codeAndVersion); 900// String code = (String) dataCodeAndVersion.get("code"); 901// BigDecimal version = new BigDecimal((String) dataCodeAndVersion.get("version")); 902// 903// pegaseProgram.setCode(code); 904// 905// pegaseProgram.setLibelle(StringUtils.truncate(program.getTitle(), 50)); // le libellé court doit faire moins de 50 caractères 906// pegaseProgram.setLibelleLong(StringUtils.truncate(program.getTitle(), 150)); // le libellé court doit faire moins de 150 caractères 907// 908// _getContentValue(program, AbstractProgram.ECTS) 909// .map(c -> c.<String>getValue(OdfReferenceTableEntry.CODE)) 910// .map(Double::parseDouble) 911// .ifPresent(pegaseProgram::setEcts); 912// 913// pegaseProgram.setTypeFormation(new FormationTypeFormation().code(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.EDUCATION_KIND))); 914// 915// // If the Program is of education kind "diplomante", add the additional fields 916// if (__CODE_FORMATION_DIPLOMANTE.equals(pegaseProgram.getTypeFormation().getCode())) 917// { 918// _fieldsIfDiplomante(program, pegaseProgram); 919// } 920// 921// return _createOrEditProgram(code, version, pegaseProgram, report); 922// } 923// 924// private void _fieldsIfDiplomante(Program program, Formation pegaseProgram) 925// { 926// Content degree = _getContentValue(program, AbstractProgram.DEGREE).orElse(null); 927// 928// // Degree -> typeDiplome 929// pegaseProgram.setTypeDiplome(_getPegaseCodeOrCode(degree)); 930// 931// // degreeNature -> natureDiplome 932// Optional.ofNullable(degree) 933// .map(d -> d.<String>getValue("degreeNature")) 934// .ifPresent(pegaseProgram::setNatureDiplome); 935// 936// // Cursus 937// Optional.ofNullable(degree) 938// .map(d -> d.<String>getValue("cursus")) 939// .ifPresent(pegaseProgram::setCursus); 940// 941// // educationLevel -> niveauFormation 942// pegaseProgram.setNiveauFormation(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.LEVEL)); 943// 944// // RncpLevel -> niveauDiplome 945// String rncpLevelValue = _getContentValues(program, AbstractProgram.RNCP_LEVEL) 946// .map(this::_getPegaseCodeOrCode) 947// .collect(Collectors.joining(",")); 948// pegaseProgram.setNiveauDiplome(rncpLevelValue); 949// 950// // Domain 951// if (((ElementDefinition) program.getDefinition(AbstractProgram.DOMAIN)).isMultiple()) 952// { 953// _getContentValues(program, AbstractProgram.DOMAIN) 954// .findFirst() 955// .map(this::_getPegaseCodeOrCode) 956// .ifPresent(pegaseProgram::setDomaineFormation); 957// } 958// else 959// { 960// pegaseProgram.setDomaineFormation(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.DOMAIN)); 961// } 962// 963// // ProgramFields -> champFormation 964// String programFieldsValue = _getContentValues(program, AbstractProgram.PROGRAM_FIELD) 965// .map(this::_getPegaseCodeOrCode) 966// .collect(Collectors.joining(",")); 967// if (StringUtils.isNotBlank(programFieldsValue)) 968// { 969// pegaseProgram.setChampFormation(programFieldsValue); 970// } 971// 972// pegaseProgram.setMention(_getPegaseCodeOrCodeOfAttribute(program, AbstractProgram.MENTION)); 973// } 974// 975// private Formation _createOrEditProgram(String code, BigDecimal version, Formation pegaseProgram, ExportReport report) throws PegaseExportException, IOException 976// { 977// // Check if the Program already exist in this version 978// ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code, version); 979// 980// // If no version is requested 981// if (version == null) 982// { 983// // If no program with this code was found in Pegase, create a new Program 984// if (objetMaquette == null) 985// { 986// try 987// { 988// return _pegaseApiManager.getFormationsApi().creerFormation(_structureCode, pegaseProgram); 989// } 990// catch (ApiException e) 991// { 992// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 993// 994// throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 995// } 996// } 997// 998// // If a program was found, try to edit it 999// String id = objetMaquette.getId(); 1000// pegaseProgram.setId(id); 1001// 1002// try 1003// { 1004// return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram); 1005// } 1006// catch (ApiException e) 1007// { 1008// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 1009// 1010// throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 1011// } 1012// } 1013// 1014// // If a version was requested 1015// 1016// // If a program already exist in this version, try to edit it 1017// if (objetMaquette != null) 1018// { 1019// try 1020// { 1021// String id = objetMaquette.getId(); 1022// 1023// pegaseProgram.setId(id); 1024// 1025// return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram); 1026// } 1027// catch (ApiException e) 1028// { 1029// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 1030// 1031// throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 1032// } 1033// } 1034// 1035// // If no program was found in Pegase with this code and version 1036// // Check if the program exist in another version 1037// objetMaquette = _getObjetMaquetteIfAlreadyExists(code); 1038// 1039// // If the program exist in another version 1040// if (objetMaquette != null) 1041// { 1042// try 1043// { 1044// // Generate a new version of the Pegase Program 1045// Formation newVersionProgram = _pegaseApiManager.getFormationsApi().generer(_structureCode, objetMaquette.getId()); 1046// 1047// String id = newVersionProgram.getId(); 1048// pegaseProgram.setId(id); 1049// 1050// // Edit the new Program created 1051// return _pegaseApiManager.getFormationsApi().modifierFormation(_structureCode, id, pegaseProgram); 1052// } 1053// catch (ApiException e) 1054// { 1055// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 1056// 1057// throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 1058// } 1059// } 1060// 1061// // If no program was found for this code at all 1062// else 1063// { 1064// try 1065// { 1066// // Create the program in Pegase 1067// return _pegaseApiManager.getFormationsApi().creerFormation(_structureCode, pegaseProgram); 1068// } 1069// catch (ApiException e) 1070// { 1071// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 1072// 1073// throw new PegaseExportException("La formation n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 1074// } 1075// } 1076// } 1077// 1078// private String _createOTTOrGroupFromContainer(Container container, ExportReport report) throws PegaseExportException, IOException 1079// { 1080// String type = null; 1081// 1082// String childNatureCode = getContainerNatureCode(container); 1083// boolean isYear = "annee".equals(childNatureCode); 1084// boolean isSemester = "semestre".equals(childNatureCode); 1085// 1086// // If it is a container of nature : semester of year, export it as an OTT of type semester or year 1087// if (isYear || isSemester) 1088// { 1089// type = isYear ? "ANNEE" : "SEMESTRE"; 1090// 1091// ObjetFormation objetFormationCreated = _createObjetFormation(container, type, report); 1092// String pegaseId = objetFormationCreated.getId(); 1093// 1094// Map<String, Enfant> containerChildren = new HashMap<>(); 1095// 1096// // Create the children 1097// containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(container), report); 1098// 1099// // Attach the children that were created 1100// _attachAllChildren(container, pegaseId, containerChildren, report); 1101// 1102// return pegaseId; 1103// } 1104// 1105// // If it is a container without a nature, export it as a group 1106// return _createGroupFromContainer(container, report); 1107// } 1108// 1109// private String _createGroupFromContainer(Container container, ExportReport report) throws PegaseExportException, IOException 1110// { 1111// Map<String, Enfant> coursesChild = new HashMap<>(); 1112// Groupement pegaseGroup = _createGroupFromContent(container); 1113// 1114// // Create the children 1115// coursesChild = _createAllChildren(coursesChild, _odfHelper.getChildProgramItems(container), report); 1116// 1117// pegaseGroup.setEnfants(List.copyOf(coursesChild.keySet())); 1118// 1119// // Create the group 1120// Groupement groupementCreated = _createGroup(pegaseGroup, report); 1121// String pegaseId = groupementCreated.getId(); 1122// 1123// // Attach the children to the group 1124// _attachAllChildrenGroupementCase(container, pegaseId, coursesChild, report); 1125// 1126// return pegaseId; 1127// } 1128// 1129// private Groupement _createGroup(Groupement pegaseGroup, ExportReport report) throws PegaseExportException, IOException 1130// { 1131// String code = pegaseGroup.getCode(); 1132// ObjetMaquette objetMaquette = _getObjetMaquetteIfAlreadyExists(code); 1133// Groupement pegaseGroupCreated; 1134// 1135// // Check if the object already exists 1136// if (objetMaquette != null) 1137// { 1138// // If it already exist, check if it can be edited 1139// if (_isModifiable(objetMaquette, code, report)) 1140// { 1141// String id = objetMaquette.getId(); 1142// pegaseGroup.setId(id); 1143// 1144// // Edit the already existing object 1145// try 1146// { 1147// return _pegaseApiManager.getGroupementsApi().modifierGroupement(_structureCode, id, pegaseGroup); 1148// } 1149// catch (ApiException e) 1150// { 1151// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED); 1152// 1153// throw new PegaseExportException("Le groupement " + pegaseGroup.getLibelle() + " n'a pas pu être exportée car sa modification dans Pégase a posé un problème", e); 1154// } 1155// } 1156// 1157// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_ALREADY_EXIST); 1158// 1159// throw new PegaseExportException("Un élément avec ce code existe déjà et n'est pas mutualisable ou modifiable"); 1160// } 1161// 1162// // If it did not already exist, create the object 1163// try 1164// { 1165// pegaseGroupCreated = _pegaseApiManager.getGroupementsApi().creerGroupement(_structureCode, pegaseGroup); 1166// 1167// if (pegaseGroupCreated != null) 1168// { 1169// return pegaseGroupCreated; 1170// } 1171// } 1172// catch (ApiException e) 1173// { 1174// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.ELEMENT_NOT_EXPORTED); 1175// 1176// throw new PegaseExportException("Le groupement " + pegaseGroup.getLibelle() + " n'a pas pu être exporté dû à un problème rencontré avec Pégase", e); 1177// } 1178// 1179// return null; 1180// } 1181// 1182// private String _createOOFromSubProgram(SubProgram subProgram, ExportReport report) throws PegaseExportException, IOException 1183// { 1184// ObjetFormation objetFormationCreated = _createObjetFormation(subProgram, "PARCOURS-TYPE", report); 1185// String pegaseId = objetFormationCreated.getId(); 1186// 1187// Map<String, Enfant> containerChildren = new HashMap<>(); 1188// 1189// // Create the children 1190// containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(subProgram), report); 1191// 1192// // Attach the children 1193// _attachAllChildren(subProgram, pegaseId, containerChildren, report); 1194// 1195// return pegaseId; 1196// } 1197// 1198// private String _createOPFromCourse(Course course, ExportReport report) throws PegaseExportException, IOException 1199// { 1200// // Get the nature of the course 1201// String type = _getPegaseCodeOrCodeOfAttribute(course, Course.COURSE_TYPE); 1202// 1203// // Create the course in Pegase 1204// ObjetFormation objetFormationCreated = _createObjetFormation(course, type, report); 1205// String pegaseId = objetFormationCreated.getId(); 1206// Map<String, Enfant> containerChildren = new HashMap<>(); 1207// 1208// // Create the children 1209// containerChildren = _createAllChildren(containerChildren, _odfHelper.getChildProgramItems(course), report); 1210// 1211// // Attach the children 1212// _attachAllChildren(course, pegaseId, containerChildren, report); 1213// 1214// return pegaseId; 1215// } 1216// 1217// private Groupement _createGroupFromContent(Content content) 1218// { 1219// Groupement pegaseGroup = new Groupement(); 1220// String code = content.getValue(__PEGASE_SYNC_CODE); 1221// 1222// pegaseGroup.setStructure(_structureCode); 1223// pegaseGroup.setCode(code); 1224// pegaseGroup.setLibelle(StringUtils.truncate(content.getTitle(), 50)); // le libellé est limité à 50 caractères 1225// pegaseGroup.setPlageDeChoix(false); 1226// pegaseGroup.setMutualise(true); 1227// pegaseGroup.setEnfants(List.of()); 1228// 1229// return pegaseGroup; 1230// } 1231// 1232// private String _createGroupFromCourseList(CourseList courseList, ExportReport report) throws PegaseExportException, IOException 1233// { 1234// Map<String, Enfant> coursesChild = new HashMap<>(); 1235// Groupement pegaseGroup = _createGroupFromContent(courseList); 1236// 1237// coursesChild = _createAllChildren(coursesChild, _odfHelper.getChildProgramItems(courseList), report); 1238// 1239// pegaseGroup.setEnfants(List.copyOf(coursesChild.keySet())); 1240// 1241// Groupement pegaseGroupCreated = _createGroup(pegaseGroup, report); 1242// 1243// String pegaseId = pegaseGroupCreated.getId(); 1244// 1245// _attachAllChildrenGroupementCase(courseList, pegaseId, coursesChild, report); 1246// 1247// return pegaseId; 1248// } 1249 1250 /** 1251 * Create a program in Pegase 1252 * @param program the program to export 1253 * @param report the Pegase export report 1254 */ 1255 @Override 1256 public void createProgram(Program program, ExportReport report) 1257 { 1258// if (!_isActive) 1259// { 1260// throw new UnsupportedOperationException("Pégase is not active in the configuration, you cannot import or synchronize a program in Pégase."); 1261// } 1262// 1263// int nbTotal = _getEveryElements(program).size(); 1264// 1265// report.setNbTotal(nbTotal); 1266// 1267// Formation pegaseProgramCreated; 1268// try 1269// { 1270// // Create the Program in Pegase 1271// pegaseProgramCreated = _createProgram(program, report); 1272// report.addElementExported(program); 1273// 1274// // Get the Id of the created formation from Pegase that is going to be used to attach the children to the program 1275// String pegaseProgramId = pegaseProgramCreated.getId(); 1276// 1277// String codeParentProgram = pegaseProgramCreated.getCode(); 1278// int versionParentProgram = 1; 1279// 1280// if (codeParentProgram.contains("/")) 1281// { 1282// String[] codeAndVersionTab = codeParentProgram.split("/"); 1283// if (codeAndVersionTab.length == 2) 1284// { 1285// codeParentProgram = codeAndVersionTab[0]; 1286// versionParentProgram = Integer.parseInt(codeAndVersionTab[1]); 1287// } 1288// } 1289// 1290// report.setCodeAndVersion(codeParentProgram, versionParentProgram); 1291// 1292// // Get the children of the Ametys program 1293// List<ProgramPart> children = program.getProgramPartChildren(); 1294// Map<String, Enfant> childrenToLink = new HashMap<>(); 1295// 1296// for (ProgramPart child : children) 1297// { 1298// // Create the pegase instance of the child 1299// Enfant enfant = _createChild((Content) child, report); 1300// 1301// // Add the Enfant (created from the Pegase Id of the child) to the list of "Enfant" to link, if it is not already attached 1302// if (enfant != null) 1303// { 1304// childrenToLink.put(enfant.getRef().getId(), enfant); 1305// } 1306// } 1307// 1308// _attachAllChildren(program, pegaseProgramId, childrenToLink, report); 1309// 1310// } 1311// catch (IOException e) 1312// { 1313// report.updateExportReport(ExportStatus.ERROR, ProblemTypes.API_ERROR); 1314// getLogger().error("Le jeton d'authentification à Pégase n'a pas pu être récupéré", e); 1315// } 1316// catch (PegaseExportException e) 1317// { 1318// report.updateStatus(ExportStatus.ERROR); 1319// getLogger().error("Une erreur est survenue lors de l'export de la formation '{}' ({}) dans Pégase", program.getTitle(), program.getId(), e); 1320// } 1321 } 1322// 1323// private Set<ProgramItem> _getEveryElements(ProgramItem program) 1324// { 1325// Set<ProgramItem> elementNotExported = new HashSet<>(); 1326// elementNotExported.add(program); 1327// 1328// for (ProgramItem child : _odfHelper.getChildProgramItems(program)) 1329// { 1330// elementNotExported.addAll(_getEveryElements(child)); 1331// } 1332// 1333// return elementNotExported; 1334// } 1335}