001/* 002 * Copyright 2014 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.cdmfr; 017 018import java.text.SimpleDateFormat; 019import java.time.LocalDate; 020import java.util.Date; 021import java.util.HashMap; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Map; 025import java.util.Map.Entry; 026import java.util.Optional; 027import java.util.Set; 028 029import org.apache.avalon.framework.component.Component; 030import org.apache.avalon.framework.context.Context; 031import org.apache.avalon.framework.context.ContextException; 032import org.apache.avalon.framework.context.Contextualizable; 033import org.apache.avalon.framework.service.ServiceException; 034import org.apache.avalon.framework.service.ServiceManager; 035import org.apache.avalon.framework.service.Serviceable; 036import org.apache.cocoon.components.ContextHelper; 037import org.apache.cocoon.environment.Request; 038import org.apache.cocoon.xml.AttributesImpl; 039import org.apache.cocoon.xml.XMLUtils; 040import org.apache.commons.collections4.MapUtils; 041import org.apache.commons.lang3.ArrayUtils; 042import org.apache.commons.lang3.StringUtils; 043import org.apache.excalibur.source.SourceResolver; 044import org.xml.sax.ContentHandler; 045import org.xml.sax.SAXException; 046 047import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 048import org.ametys.cms.contenttype.ContentTypesHelper; 049import org.ametys.cms.data.ContentDataHelper; 050import org.ametys.cms.data.ContentValue; 051import org.ametys.cms.data.RichText; 052import org.ametys.cms.data.type.ModelItemTypeConstants; 053import org.ametys.cms.repository.Content; 054import org.ametys.cms.repository.ModifiableContent; 055import org.ametys.core.util.DateUtils; 056import org.ametys.odf.NoLiveVersionException; 057import org.ametys.odf.ODFHelper; 058import org.ametys.odf.course.Course; 059import org.ametys.odf.course.LOMSheet; 060import org.ametys.odf.courselist.CourseList; 061import org.ametys.odf.courselist.CourseList.ChoiceType; 062import org.ametys.odf.coursepart.CoursePart; 063import org.ametys.odf.enumeration.OdfReferenceTableEntry; 064import org.ametys.odf.enumeration.OdfReferenceTableHelper; 065import org.ametys.odf.orgunit.OrgUnit; 066import org.ametys.odf.orgunit.RootOrgUnitProvider; 067import org.ametys.odf.person.ContactData; 068import org.ametys.odf.person.Person; 069import org.ametys.odf.program.AbstractProgram; 070import org.ametys.odf.program.Container; 071import org.ametys.odf.program.Program; 072import org.ametys.odf.program.ProgramFactory; 073import org.ametys.odf.program.ProgramPart; 074import org.ametys.odf.program.SubProgram; 075import org.ametys.odf.program.TraversableProgramPart; 076import org.ametys.odf.program.WebsiteLink; 077import org.ametys.plugins.repository.AmetysObjectResolver; 078import org.ametys.plugins.repository.UnknownAmetysObjectException; 079import org.ametys.plugins.repository.jcr.DefaultAmetysObject; 080import org.ametys.plugins.repository.model.RepositoryDataContext; 081import org.ametys.runtime.model.type.DataContext; 082import org.ametys.runtime.plugin.component.AbstractLogEnabled; 083 084/** 085 * Component able to generate CDM-fr for a {@link CDMEntity}. 086 */ 087public class ExportCDMfrManager extends AbstractLogEnabled implements Component, Serviceable, Contextualizable 088{ 089 /** The Avalon role */ 090 public static final String ROLE = ExportCDMfrManager.class.getName(); 091 092 /** Request attribute to get if the export is for Ametys application */ 093 public static final String REQUEST_ATTRIBUTE_EXPORT_FOR_AMETYS = ExportCDMfrManager.class.getName() + "$forAmetys"; 094 095 private static final String[] __FIXED_DOMAIN_NAMES = new String[]{"ALL", "DEG", "SHS", "STS", "STA"}; 096 097 /** The Ametys object resolver */ 098 protected AmetysObjectResolver _resolver; 099 /** The source resolver */ 100 protected SourceResolver _sourceResolver; 101 /** The ODF enumeration helper */ 102 protected OdfReferenceTableHelper _refTableHelper; 103 /** The root orgunit provider */ 104 protected RootOrgUnitProvider _rootOrgUnitProvider; 105 /** The avalon context */ 106 protected Context _context; 107 /** The CDMfr extension point */ 108 protected CDMfrExtensionPoint _cdmFrExtensionPoint; 109 /** The content type extension point */ 110 protected ContentTypeExtensionPoint _cTypeEP; 111 /** Helper for content types */ 112 protected ContentTypesHelper _cTypeHelper; 113 /** The ODF helper */ 114 protected ODFHelper _odfHelper; 115 116 @Override 117 public void service(ServiceManager smanager) throws ServiceException 118 { 119 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 120 _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE); 121 _refTableHelper = (OdfReferenceTableHelper) smanager.lookup(OdfReferenceTableHelper.ROLE); 122 _rootOrgUnitProvider = (RootOrgUnitProvider) smanager.lookup(RootOrgUnitProvider.ROLE); 123 _cdmFrExtensionPoint = (CDMfrExtensionPoint) smanager.lookup(CDMfrExtensionPoint.ROLE); 124 _cTypeEP = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE); 125 _cTypeHelper = (ContentTypesHelper) smanager.lookup(ContentTypesHelper.ROLE); 126 _odfHelper = (ODFHelper) smanager.lookup(ODFHelper.ROLE); 127 } 128 129 @Override 130 public void contextualize(Context context) throws ContextException 131 { 132 _context = context; 133 } 134 135 /** 136 * Entry point to generate the CDM for a program 137 * @param contentHandler The content handler to sax into 138 * @param program The program 139 * @throws SAXException if failed to generate CDM 140 */ 141 public void generateCDM(ContentHandler contentHandler, Program program) throws SAXException 142 { 143 contentHandler.startDocument(); 144 contentHandler.startPrefixMapping("", "http://cdm-fr.fr/2013/CDM"); 145 contentHandler.startPrefixMapping("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 146 contentHandler.startPrefixMapping("cdmfr", "http://cdm-fr.fr/2013/CDM-frSchema"); 147 contentHandler.startPrefixMapping("xhtml", "http://www.w3.org/1999/xhtml"); 148 contentHandler.startPrefixMapping("ametys-cdm", "http://www.ametys.org/cdm/1.0"); 149 150 AttributesImpl attrs = new AttributesImpl(); 151 attrs.addCDATAAttribute("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi:schemaLocation", "http://cdm-fr.fr/2013/CDM http://cdm-fr.fr/2013/schemas/CDMFR.xsd"); 152 attrs.addCDATAAttribute("profile", "CDM-fr"); 153 attrs.addCDATAAttribute("language", program.getLanguage()); 154 XMLUtils.startElement(contentHandler, "CDM", attrs); 155 156 saxHabilitation(contentHandler, program); 157 158 XMLUtils.startElement(contentHandler, "properties"); 159 XMLUtils.createElement(contentHandler, "datasource", "Ametys v4.2"); 160 attrs = new AttributesImpl(); 161 attrs.addCDATAAttribute("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date())); 162 XMLUtils.createElement(contentHandler, "datetime", attrs); 163 XMLUtils.endElement(contentHandler, "properties"); 164 165 program2CDM(contentHandler, program); 166 167 XMLUtils.endElement(contentHandler, "CDM"); 168 169 contentHandler.endDocument(); 170 } 171 172 /** 173 * Switch to Live version if it was required 174 * @param ao the Ametys object 175 * @return true if the ametys object is switched 176 */ 177 protected boolean switchToLiveVersionIfNeeded(DefaultAmetysObject ao) 178 { 179 try 180 { 181 _odfHelper.switchToLiveVersionIfNeeded(ao); 182 return true; 183 } 184 catch (NoLiveVersionException e) 185 { 186 getLogger().warn("Cannot export content to CDM : Live label is required but there is no Live version for content " + ao.getId()); 187 } 188 189 return false; 190 } 191 192 /** 193 * Determines if this CDM export if for a Ametys application 194 * @return true if this CDM export if for a Ametys application 195 */ 196 protected boolean isExportForAmetys() 197 { 198 Request request = ContextHelper.getRequest(_context); 199 return request.getAttribute(ExportCDMfrManager.REQUEST_ATTRIBUTE_EXPORT_FOR_AMETYS) != null; 200 } 201 202 /** 203 * SAX CDMfr events for program's habilitation 204 * @param contentHandler the content handler to sax into 205 * @param program the program 206 * @throws SAXException if an error occurred 207 */ 208 public void saxHabilitation(ContentHandler contentHandler, Program program) throws SAXException 209 { 210 /* 211 * <cdmfr:habilitation> 212 * <cdmfr:habiliId>ID</cdmfr:habiliId> 213 * <cdmfr:cohabilitation> 214 * <cdmfr:exists>true|false</cdmfr:exists> // Habilité ou non 215 * <cdmfr:listOfOrgUnit> 216 * <cdmfr:habOrgUnit> 217 * <cdmfr:refOrgUnit> // Etablisssement cohabilité 218 * <cdmfr:domainName> 219 * <cdmfr:fixedDomain> // Domaine concerné par cette habilitation 220 * </cdmfr:domainName> 221 * </cdmfr:habOrgUnit> 222 * </cdmfr:listOfOrgUnit> 223 * </cdmfr:cohabilitation> 224 * <cdmfr:field> 225 * <fieldname> 226 * <free>MENTION</free> 227 * </fieldname> 228 * <speciality> 229 * <specialityId/> 230 * <specialityName/> 231 * </speciality> 232 * </cdmfr:field> 233 * <cdmfr:partnership> 234 * <cdmfr:training> 235 * <cdmfr:trainingStrategy /> // Stages 236 * </cdmfr:training> 237 * </cdmfr:partnership> 238 * </cdmfr:habilitation> 239 * 240 */ 241 242 if (program.isPublishable() && switchToLiveVersionIfNeeded(program)) 243 { 244 Request request = ContextHelper.getRequest(_context); 245 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 246 247 try 248 { 249 request.setAttribute(Content.class.getName(), program); 250 251 AttributesImpl attrs = new AttributesImpl(); 252 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, ""); 253 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_DIPLOMA_TYPE, getDiplomaType(program)); 254 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_HABILITATION, attrs); 255 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_HABILITATION_ID, program.getCDMId()); 256 257 _saxCohabilitation(contentHandler, program); 258 _saxHabilitationJointOrgUnit(contentHandler, program); 259 _saxHabilitationDiploma(contentHandler, program); 260 _saxHabilitationPartnerShip(contentHandler, program); 261 262 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_HABILITATION); 263 } 264 finally 265 { 266 request.setAttribute(Content.class.getName(), currentContent); 267 } 268 } 269 } 270 271 /** 272 * Sax habilitation informations of the diploma. 273 * @param contentHandler The content handler 274 * @param program The program to sax 275 * @throws SAXException if an error occurs 276 */ 277 protected void _saxHabilitationDiploma(ContentHandler contentHandler, Program program) throws SAXException 278 { 279 String speciality = program.getSpeciality(); 280 String mention = program.getMention(); 281 282 if (StringUtils.isNotEmpty(mention) || StringUtils.isNotEmpty(speciality)) 283 { 284 // Formation LMD : Mention - Speciality 285 /* 286 * <cdmfr:field> 287 * <cdmfr:fieldName> 288 * <cdmfr:controlled fieldNameCode="code_mention"> 289 * <cdmfr:registeredName>Libelle mention</cdmfr:registeredName> 290 * </cdmfr:controlled> 291 * </cdmfr:fieldName> 292 * <cdmfr:speciality> 293 * <cdmfr:specialityName/> 294 * <cdmfr:specialityId/> 295 * <cdmfr:refProgram/> 296 * </cdmfr:speciality> 297 * </cdmfr:field> 298 */ 299 300 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "field"); 301 _saxHabilitationMention(contentHandler, program, mention); 302 _saxHabilitationSpeciality(contentHandler, program, speciality); 303 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "field"); 304 } 305 else if (OdfReferenceTableHelper.MENTION_LICENCEPRO.equals(_getMentionType(program))) 306 { 307 _saxHabilitationLicPro(contentHandler, program); 308 } 309 else 310 { 311 _saxHabilitationOtherDiploma(contentHandler, program); 312 } 313 } 314 315 /** 316 * Sax habilitation informations of professional license. 317 * @param contentHandler The content handler 318 * @param program The program to sax 319 * @throws SAXException if an error occurs 320 */ 321 protected void _saxHabilitationLicPro(ContentHandler contentHandler, Program program) throws SAXException 322 { 323 // Licence professionelle 324 /* 325 * <cdmfr:licPro> 326 * <cdmfr:specialite> 327 * <cdm:text/> 328 * </cdmfr:specialite> 329 * </cdmfr:licPro> 330 */ 331 332 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "licPro"); 333 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "specialite"); 334 XMLUtils.createElement(contentHandler, "text", program.getSpeciality()); 335 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "specialite"); 336 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "licPro"); 337 } 338 339 /** 340 * Sax habilitation informations for another diploma : no mention, not a license. 341 * @param contentHandler The content handler 342 * @param program The program to sax 343 * @throws SAXException if an error occurs 344 */ 345 protected void _saxHabilitationOtherDiploma(ContentHandler contentHandler, Program program) throws SAXException 346 { 347 // Autre diplôme habilité ne s'inscrivant pas dans une structure mention-spécialité 348 /* 349 * <cdmfr:otherDiploma> 350 * <cdmfr:refProgram/> 351 * </cdmfr:otherDiploma> 352 */ 353 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "otherDiploma"); 354 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "refProgram", program.getCDMId()); 355 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "otherDiploma"); 356 } 357 358 /** 359 * Sax habilitation informations of mention. 360 * @param contentHandler The content handler 361 * @param program The program to sax 362 * @param mention The mention to sax 363 * @throws SAXException if an error occurs 364 */ 365 protected void _saxHabilitationMention(ContentHandler contentHandler, Program program, String mention) throws SAXException 366 { 367 if (StringUtils.isNotEmpty(mention)) 368 { 369 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "fieldName"); 370 371 if (ModelItemTypeConstants.CONTENT_ELEMENT_TYPE_ID.equals(program.getType("mention").getId())) 372 { 373 OdfReferenceTableEntry entry = _refTableHelper.getItem(mention); 374 375 String mentionLabel = entry.getCdmValue(); 376 if (StringUtils.isEmpty(mentionLabel)) 377 { 378 mentionLabel = entry.getLabel(program.getLanguage()); 379 } 380 381 AttributesImpl attrs = new AttributesImpl(); 382 attrs.addCDATAAttribute("fieldNameCode", entry.getCode()); 383 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "controlled", attrs); 384 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "registeredName", mentionLabel); 385 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "controlled"); 386 } 387 else 388 { 389 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "free", mention); 390 } 391 392 393 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "fieldName"); 394 } 395 } 396 397 /** 398 * Sax habilitation informations of speciality. 399 * @param contentHandler The content handler 400 * @param program The program to sax 401 * @param speciality The speciality to sax 402 * @throws SAXException if an error occurs 403 */ 404 protected void _saxHabilitationSpeciality(ContentHandler contentHandler, Program program, String speciality) throws SAXException 405 { 406 if (StringUtils.isNotEmpty(speciality)) 407 { 408 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "speciality"); 409 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "specialityName", speciality); 410 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "specialityId", program.getCDMId() + "SP01"); // FIXME "SP + n° ordre de la spécialité" 411 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "refProgram", program.getCDMId()); 412 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "speciality"); 413 } 414 } 415 416 /** 417 * Sax cohabilitation informations. 418 * @param contentHandler The content handler 419 * @param program The program to sax 420 * @throws SAXException if an error occurs 421 */ 422 protected void _saxCohabilitation(ContentHandler contentHandler, Program program) throws SAXException 423 { 424 String[] domains = program.getDomain(); 425 boolean isHabilited = false; 426 for (String domain : domains) 427 { 428 isHabilited |= !"HD".equals(_refTableHelper.getItemCode(domain)); 429 } 430 431 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "cohabilitation"); 432 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "exists", String.valueOf(isHabilited)); 433 434 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "listOfOrgUnit"); 435 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "habOrgUnit"); 436 437 String rneCode = _getRootOrgUnitId(program); 438 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "refOrgUnit", rneCode); 439 440 _saxHabilitationDomains(contentHandler, domains); 441 442 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "habOrgUnit"); 443 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "listOfOrgUnit"); 444 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "cohabilitation"); 445 } 446 447 /** 448 * Sax habilitation informations of domains. 449 * @param contentHandler The content handler 450 * @param domains The domains to SAX 451 * @throws SAXException if an error occurs 452 */ 453 protected void _saxHabilitationDomains(ContentHandler contentHandler, String[] domains) throws SAXException 454 { 455 for (String domain : domains) 456 { 457 Content content = _resolver.resolveById(domain); 458 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 459 String domainName = entry.getCdmValue(); 460 String domainCode = entry.getCode(); 461 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "domainName"); 462 if (ArrayUtils.contains(__FIXED_DOMAIN_NAMES, domainCode)) 463 { 464 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "fixedDomain", domainName); 465 } 466 else 467 { 468 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "openDomain", domainName); 469 } 470 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "domainName"); 471 } 472 } 473 474 /** 475 * Sax habilitation informations of joint orgunits. 476 * @param contentHandler The content handler 477 * @param program The program to sax 478 * @throws SAXException if an error occurs 479 */ 480 protected void _saxHabilitationJointOrgUnit(ContentHandler contentHandler, Program program) throws SAXException 481 { 482 // Etablissement cohabilité 483 String[] jointOrgUnit = program.getJointOrgUnit(); 484 if (jointOrgUnit.length > 0) 485 { 486 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "cohabilitation"); 487 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "exists", String.valueOf(true)); 488 489 AttributesImpl attrs = new AttributesImpl(); 490 attrs.addCDATAAttribute("cohabilitationRole", "cohabilité"); 491 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "listOfOrgUnit", attrs); 492 for (String id : jointOrgUnit) 493 { 494 if (StringUtils.isNotEmpty(id)) 495 { 496 String uaiCode = _refTableHelper.getItemCode(id); 497 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "habOrgUnit"); 498 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "refOrgUnit", uaiCode); 499 String ouLabel = _refTableHelper.getItemLabel(id, program.getLanguage()); 500 if (ouLabel != null) 501 { 502 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, ouLabel); 503 } 504 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "habOrgUnit"); 505 } 506 } 507 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "listOfOrgUnit"); 508 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "cohabilitation"); 509 } 510 } 511 512 /** 513 * Sax habilitation informations of partner ship. 514 * @param contentHandler The content handler 515 * @param program The program to sax 516 * @throws SAXException if an error occurs 517 */ 518 protected void _saxHabilitationPartnerShip(ContentHandler contentHandler, Program program) throws SAXException 519 { 520 /* 521 * <cdmfr:partnership> 522 * <cdmfr:training> 523 * <cdmfr:trainingStrategy /> 524 * </cdmfr:training> 525 * </cdmfr:partnership> 526 */ 527 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "partnership"); 528 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "training"); 529 DataContext richTextContext = RepositoryDataContext.newInstance() 530 .withObject(program) 531 .withDataPath(AbstractProgram.TRAINING_STRATEGY); 532 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "trainingStrategy", program.getTrainingStrategy(), richTextContext, _sourceResolver, false, isExportForAmetys()); 533 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "training"); 534 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + "partnership"); 535 } 536 537 /** 538 * Get the root organization unit uai code 539 * @param program the exported program 540 * @return the uai code of the root organization unit corresponding to the exported program 541 */ 542 protected String _getRootOrgUnitId(Program program) 543 { 544 return _rootOrgUnitProvider.getRoot().getUAICode(); 545 } 546 547 /** 548 * Get the type of diploma 549 * @param program the program 550 * @return diploma type 551 */ 552 protected String getDiplomaType (Program program) 553 { 554 String degreeMentionType = _getMentionType(program); 555 if (OdfReferenceTableHelper.MENTION_LICENCE.equals(degreeMentionType)) 556 { 557 return "L"; 558 } 559 else if (OdfReferenceTableHelper.MENTION_MASTER.equals(degreeMentionType)) 560 { 561 return "M"; 562 } 563 else if (OdfReferenceTableHelper.MENTION_LICENCEPRO.equals(degreeMentionType)) 564 { 565 return "Lpro"; 566 } 567 return "autre"; 568 } 569 570 //***********************************************************************// 571 // PROGRAM // 572 //***********************************************************************// 573 574 /** 575 * Export this entity in CDM-fr format. 576 * @param contentHandler the target handler 577 * @param program the program 578 * @throws SAXException if an error occurs during export. 579 */ 580 public void program2CDM(ContentHandler contentHandler, Program program) throws SAXException 581 { 582 boolean rootOrgUnitSaxed = false; 583 584 Set<String> persons = new HashSet<>(); 585 Set<String> orgUnits = new HashSet<>(); 586 Set<String> coursesToSax = new HashSet<>(); 587 588 abstractProgram2CDM(contentHandler, program, persons, orgUnits, coursesToSax); 589 590 Set<String> coursesAlreadySax = new HashSet<>(); 591 592 while (!coursesToSax.isEmpty()) 593 { 594 Set<String> courses = new HashSet<>(); 595 for (String courseId : coursesToSax) 596 { 597 coursesAlreadySax.add(courseId); 598 Course course = _resolver.resolveById(courseId); 599 courses.addAll(course2CDM(contentHandler, course, orgUnits, persons)); 600 } 601 602 coursesToSax.clear(); 603 coursesToSax.addAll(courses); 604 coursesToSax.removeAll(coursesAlreadySax); 605 } 606 607 for (String orgUnitId : orgUnits) 608 { 609 OrgUnit orgUnit = _resolver.resolveById(orgUnitId); 610 if (orgUnitId.equals(_rootOrgUnitProvider.getRootId())) 611 { 612 rootOrgUnitSaxed = true; 613 } 614 615 _orgunit2CDM(contentHandler, orgUnit, persons); 616 } 617 618 if (!rootOrgUnitSaxed) 619 { 620 _orgunit2CDM(contentHandler, _rootOrgUnitProvider.getRoot(), persons); 621 } 622 623 for (String personId : persons) 624 { 625 Person person = _resolver.resolveById(personId); 626 person2CDM(contentHandler, person); 627 } 628 } 629 630 /** 631 * Send the CDM-fr representation of their ProgramPart to the given Contenthandler.<br> 632 * Also collects referenced orgUnits, persons and courses, so that they could be sent afterwards. 633 * @param contentHandler the receiving contentHandler. 634 * @param program the program 635 * @param persons collected {@link Person} ids. 636 * @param orgUnits collected {@link OrgUnit} ids. 637 * @param courses collected {@link Course} ids. 638 * @throws SAXException if an error occurs during CDM processing. 639 */ 640 public void abstractProgram2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, Set<String> persons, Set<String> orgUnits, Set<String> courses) throws SAXException 641 { 642 DataContext programRichTextsContext = RepositoryDataContext.newInstance() 643 .withObject(program); 644 if (program.isPublishable() && switchToLiveVersionIfNeeded(program)) 645 { 646 Request request = ContextHelper.getRequest(_context); 647 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 648 649 try 650 { 651 request.setAttribute(Content.class.getName(), program); 652 653 String tagName = program.getCDMTagName(); 654 655 AttributesImpl attrs = new AttributesImpl(); 656 657 // <program id="FRUAI{rootOrgUnitId}PR{code}" language="..."> 658 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, program.getCDMId()); 659 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LANGUAGE, program.getLanguage()); 660 XMLUtils.startElement(contentHandler, tagName, attrs); 661 662 // <programID>code</programID> 663 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PROGRAM_ID, program.getCDMId()); 664 665 // <programName><text>name</text></programName> 666 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 667 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_TEXT, program.getTitle()); 668 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 669 670 _abstractProgram2CDMCode(contentHandler, program); 671 672 // <webLink> 673 // <href>href</href> 674 // <linkName>linkName</linkName> 675 // </webLink> 676 for (WebsiteLink website : program.getWebsiteLinks()) 677 { 678 website.toCDM(contentHandler); 679 } 680 681 // <programDescription>...</programDescription> 682 attrs = new AttributesImpl(); 683 String programType = program.getEducationKind(); 684 if (StringUtils.isNotEmpty(programType)) 685 { 686 programType = _refTableHelper.getItemCDMfrValue(programType, false); 687 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_NATURE, programType); 688 } 689 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION, attrs); 690 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getPresentation(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.PRESENTATION), _sourceResolver, false, isExportForAmetys()); 691 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION); 692 693 // <qualification>...</qualification> 694 _qualification2CDM(contentHandler, program, programRichTextsContext); 695 696 // <levelCode @codeSet="bac|bac+1|bac+2|bac+3|..."/> 697 // <level @level="L|M|Doc"/> 698 _level2CDM(contentHandler, program); 699 700 // <learningObjectives>...</learningObjectives> 701 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES, program.getObjectives(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.OBJECTIVES), _sourceResolver, false, isExportForAmetys()); 702 703 // <admissionInfo> 704 // <cdmfr:admissionDescription>...</cdmfr:admissionDescription> 705 // </admissionInfo> 706 _admissionInfo2CDM(contentHandler, program, programRichTextsContext); 707 708 // <recommendedPrerequisites>...</recommendedPrerequisites> 709 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_RECOMMANDED_PREREQUISITES, program.getRecommendedPrerequisite(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.RECOMMENDED_PREREQUISITE), _sourceResolver, false, isExportForAmetys()); 710 711 // <formalPrerequisites>...</formalPrerequisites> 712 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORMAL_PREREQUISITES, program.getNeededPrerequisite(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.NEEDED_PREREQUISITE), _sourceResolver, true, isExportForAmetys()); 713 714 // <teachingPlace>...</teachingPlace> 715 _place2CDM(contentHandler, program); 716 717 // <targetGroup>...</targetGroup> 718 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_TARGET_GROUP, program.getTargetGroup(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.TARGET_GROUP), _sourceResolver, false, isExportForAmetys()); 719 720 // <formOfTeaching org="" method=""/> 721 String formOfTeachingMethod = _refTableHelper.getItemCDMfrValue(program.getDistanceLearning(), false); 722 for (String formOfTeachingOrg: program.getFormOfTeachingOrgs()) 723 { 724 attrs = new AttributesImpl(); 725 String formOfTeachingOrgValue = _refTableHelper.getItemCDMfrValue(formOfTeachingOrg, false); 726 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, formOfTeachingMethod); 727 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ORG, formOfTeachingOrgValue); 728 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_TEACHING, attrs); 729 } 730 731 // <instructionLanguage teachingLang="fr"/> 732 String[] langs = program.getEducationLanguage(); 733 for (String lang : langs) 734 { 735 String teachingLanguageValue = _refTableHelper.getItemCDMfrValue(lang, true); 736 attrs = new AttributesImpl(); 737 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_LANG, teachingLanguageValue); 738 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INSTRUCTION_LANGUAGE, attrs); 739 } 740 741 // <studyAbroad>...</studoAbroad> 742 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDY_ABROAD, program.getStudyAbroad(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.STUDY_ABROAD), _sourceResolver, false, isExportForAmetys()); 743 744 // <programDuration>...</programDuration> 745 String duration = program.getDuration(); 746 if (StringUtils.isNotBlank(duration)) 747 { 748 String durationValue = _refTableHelper.getItemCDMfrValue(duration, true); 749 if (durationValue != null) 750 { 751 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PROGRAM_DURATION, durationValue); 752 } 753 } 754 755 // <cdmfr:programStructure>...</cdmfr:programStructure> 756 RichText teachingOrganization = program.getTeachingOrganization(); 757 if (teachingOrganization != null && teachingOrganization.getLength() > 0) 758 { 759 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 760 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getTeachingOrganization(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.TEACHING_ORGANIZATION), _sourceResolver, false, isExportForAmetys()); 761 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 762 } 763 764 // Sax courses list 765 ContentValue[] children = program.getValue(TraversableProgramPart.CHILD_PROGRAM_PARTS, false, new ContentValue[0]); 766 for (ContentValue child : children) 767 { 768 Optional<ModifiableContent> content = child.getContentIfExists(); 769 if (content.isPresent() && content.get() instanceof CourseList courseList) 770 { 771 courselist2CDM(contentHandler, courseList, courses); 772 } 773 } 774 775 // <regulations/> 776 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REGULATIONS); 777 778 // <expenses>...</expenses> 779 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_EXPENSES, program.getExpenses(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.EXPENSES), _sourceResolver, false, isExportForAmetys()); 780 781 // <universalAjustment>...</universalAjustment> 782 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_UNIVERSAL_ADJUSTMENT, program.getUniversalAdjustment(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.UNIVERSAL_ADJUSTMENT), _sourceResolver, false, isExportForAmetys()); 783 784 // <contacts> 785 // <refPerson idRef="ID"/> 786 // <refOrgUnit idRef="ID"/> 787 // </contacts> 788 _abstractProgram2CDMContacts(contentHandler, program, persons, orgUnits); 789 790 // <infoBlock>...</infoBlock> 791 attrs = new AttributesImpl(); 792 if (tagName.equals(CDMFRTagsConstants.TAG_SUB_PROGRAM)) 793 { 794 attrs.addCDATAAttribute("userDefined", "subProgram"); 795 } 796 797 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getAdditionalInformations(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.ADDITIONNAL_INFORMATIONS), _sourceResolver, false, isExportForAmetys(), attrs); 798 799 // <infoBlock userDefined="ametys-extension>...</infoBlock> 800 saxExtensions(contentHandler, program, persons, orgUnits); 801 802 // <programStructure>...</programStructure> 803 _programPart2CDMSubPrograms(contentHandler, program, persons, orgUnits, courses); 804 805 // <searchword>keyword</searchword> 806 for (String keyword : program.getKeywords()) 807 { 808 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_SEARCH_WORD, keyword); 809 } 810 811 // </program> 812 XMLUtils.endElement(contentHandler, tagName); 813 } 814 finally 815 { 816 request.setAttribute(Content.class.getName(), currentContent); 817 } 818 } 819 } 820 821 /** 822 * Export CDM extensions handling all elements that do not belong to the CDM-fr schema 823 * @param contentHandler the receiving contentHandler. 824 * @param content the current ODF Content 825 * @param persons collected {@link Person} ids. 826 * @param orgUnits collected {@link OrgUnit} ids. 827 * @throws SAXException if an error occurs during CDM processing. 828 */ 829 protected void saxExtensions(ContentHandler contentHandler, Content content, Set<String> persons, Set<String> orgUnits) throws SAXException 830 { 831 AttributesImpl attrs = new AttributesImpl(); 832 attrs.addCDATAAttribute("userDefined", "ametys-extension"); 833 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs); 834 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_EXTENSION_BLOCK); 835 836 for (String id : _cdmFrExtensionPoint.getExtensionsIds()) 837 { 838 CDMfrExtension cdmFrExtension = _cdmFrExtensionPoint.getExtension(id); 839 840 if (content instanceof AbstractProgram<?> abstractProgram) 841 { 842 if (abstractProgram instanceof Program program) 843 { 844 cdmFrExtension.program2CDM(contentHandler, program, persons, orgUnits); 845 } 846 else if (abstractProgram instanceof SubProgram subProgram) 847 { 848 cdmFrExtension.subProgram2CDM(contentHandler, subProgram, persons, orgUnits); 849 } 850 851 cdmFrExtension.abstractProgram2CDM(contentHandler, abstractProgram, persons, orgUnits); 852 } 853 else if (content instanceof Container container) 854 { 855 cdmFrExtension.container2CDM(contentHandler, container, persons, orgUnits); 856 } 857 else if (content instanceof Course course) 858 { 859 cdmFrExtension.course2CDM(contentHandler, course, persons, orgUnits); 860 } 861 else if (content instanceof Person person) 862 { 863 cdmFrExtension.person2CDM(contentHandler, person); 864 } 865 else if (content instanceof OrgUnit orgunit) 866 { 867 cdmFrExtension.orgunit2CDM(contentHandler, orgunit); 868 } 869 } 870 871 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_EXTENSION_BLOCK); 872 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK); 873 } 874 875 /** 876 * SAX CDM-fr teaching places 877 * @param contentHandler the content handler to sax into 878 * @param program the program or subprogram 879 * @throws SAXException if an error occurred 880 */ 881 protected void _place2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 882 { 883 // <teachingPlace> 884 // <cdmfr:refOrgUnit /> 885 // <adr> 886 // <pcode></pcode> 887 // </adr> 888 // </teachingPlace> 889 String[] places = program.getPlace(); 890 for (String id : places) 891 { 892 if (StringUtils.isNotEmpty(id)) 893 { 894 String postalCode = _refTableHelper.getItemCode(id); 895 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 896 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 897 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 898 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, postalCode); 899 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 900 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 901 } 902 } 903 } 904 905 /** 906 * SAX CDM-fr qualification 907 * @param contentHandler the content handler to sax into 908 * @param program the program or subprogram 909 * @param programRichTextsContext the context for program's rich texts 910 * @throws SAXException if an error occurred 911 */ 912 protected void _qualification2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, DataContext programRichTextsContext) throws SAXException 913 { 914 // <qualification> 915 // <qualificatioName><text></text></qualificationName> 916 // <qualificationDescription> 917 // <infoBlock>...</infoBlock> 918 // <statistics>success rate</statistics> 919 // </qualificationDescription> 920 // <degree degree=""/> 921 // <profession>...</profession> 922 // <studyQualification>...</studyQualification> 923 // </qualification> 924 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 925 926 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION_NAME); 927 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT); 928 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION_NAME); 929 930 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_QUALIFICATION_DESCRIPTION); 931 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getQualification(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.QUALIFICATION), _sourceResolver, true, isExportForAmetys()); 932 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STATISTICS, program.getSuccessRate()); 933 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_QUALIFICATION_DESCRIPTION); 934 935 AttributesImpl attrs = new AttributesImpl(); 936 String ects = _refTableHelper.getItemCDMfrValue(program.getEcts(), true); 937 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, ects); 938 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 939 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getKnowledgeCheck(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.KNOWLEDGE_CHECK), _sourceResolver, true, isExportForAmetys()); 940 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 941 942 _degree2CDM(contentHandler, program); 943 944 // <profession> 945 // <infoBlock>...</infoBlock> 946 // <romeData romeCode="code" romeLibel=""/> 947 // </profession> 948 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESSION); 949 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getJobOpportunities(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.JOB_OPPORTUNITIES), _sourceResolver, true, isExportForAmetys()); 950 _romeCodes2CDM(contentHandler, program); 951 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESSION); 952 953 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDY_QUALIFICATION); 954 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getFurtherStudy(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.FURTHER_STUDY), _sourceResolver, true, isExportForAmetys()); 955 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COMPETENCE_DESC); 956 attrs = new AttributesImpl(); 957 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIMITED, "false"); 958 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COMPETENCE_VALIDITY, attrs); 959 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDY_QUALIFICATION); 960 961 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 962 } 963 964 /** 965 * SAX CDMfr degree 966 * @param contentHandler the content handler to sax into 967 * @param abstractProgram the program or subprogram 968 * @throws SAXException if an error occurred 969 */ 970 protected void _degree2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> abstractProgram) throws SAXException 971 { 972 if (abstractProgram instanceof Program program) 973 { 974 AttributesImpl attrs = new AttributesImpl(); 975 String degreeId = program.getDegree(); 976 if (StringUtils.isNotEmpty(degreeId)) 977 { 978 String cdmCode = _refTableHelper.getItemCDMfrValue(degreeId, false); 979 if (StringUtils.isNotEmpty(cdmCode)) 980 { 981 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_DEGREE, cdmCode); 982 } 983 else 984 { 985 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_DEGREE_NOT_LMD, _refTableHelper.getItemCode(degreeId)); 986 } 987 988 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DEGREE, attrs); 989 } 990 } 991 } 992 993 /** 994 * SAX CDMfr rome codes 995 * @param contentHandler the content handler to sax into 996 * @param program the program or subprogram 997 * @throws SAXException if an error occurred 998 */ 999 protected void _romeCodes2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1000 { 1001 String[] romeCode = program.getRomeCode(); 1002 for (String id : romeCode) 1003 { 1004 AttributesImpl attrs = new AttributesImpl(); 1005 String code = _refTableHelper.getItemCode(id); 1006 attrs.addCDATAAttribute("romeCode", code); 1007 String label = _refTableHelper.getItemCDMfrValue(id, false); 1008 if (StringUtils.isNotBlank(label)) 1009 { 1010 attrs.addCDATAAttribute("romeLibel", label); 1011 } 1012 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ROME_DATA, attrs); 1013 } 1014 } 1015 1016 /** 1017 * SAX CDMfr level 1018 * @param contentHandler the content handler to sax into 1019 * @param program the program or subprogram 1020 * @throws SAXException if an error occurred 1021 */ 1022 protected void _level2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1023 { 1024 AttributesImpl attrs = new AttributesImpl(); 1025 String educationLevel = program.getEducationLevel(); 1026 _addNotNullAttribute(attrs, "codeSet", _refTableHelper.getItemCDMfrValue(educationLevel, true)); 1027 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL_CODE, attrs); 1028 1029 attrs = new AttributesImpl(); 1030 String educationLevelCode = _refTableHelper.getItemCode(educationLevel); 1031 if (educationLevelCode.startsWith("licence")) 1032 { 1033 _addNotNullAttribute(attrs, "level", "L"); 1034 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1035 } 1036 else if (educationLevelCode.startsWith("master")) 1037 { 1038 _addNotNullAttribute(attrs, "level", "M"); 1039 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1040 } 1041 else if (educationLevelCode.startsWith("doctorat")) 1042 { 1043 _addNotNullAttribute(attrs, "level", "Doc"); 1044 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1045 } 1046 } 1047 1048 /** 1049 * SAX CDMfr admission info 1050 * @param contentHandler the content handler to sax into 1051 * @param program the program or subprogram 1052 * @param programRichTextsContext the context for program's rich texts 1053 * @throws SAXException if an error occurred 1054 */ 1055 protected void _admissionInfo2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, DataContext programRichTextsContext) throws SAXException 1056 { 1057 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1058 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ADMISSION_DESCRIPTION, program.getAccessCondition(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.ACCESS_CONDITION), _sourceResolver, false, isExportForAmetys()); 1059 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDENT_STATUS, ""); 1060 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ECTS_REQUIRED, ""); 1061 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDENT_PLACES, program.getEffectives(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.NUMBER_OF_STUDENTS), _sourceResolver, false, isExportForAmetys()); 1062 1063 LocalDate teachingStart = program.getTeachingStart(); 1064 if (teachingStart != null) 1065 { 1066 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_TEACHING_START, teachingStart); 1067 } 1068 1069 LocalDate registrationDeadline = program.getRegistrationDeadline(); 1070 if (registrationDeadline != null) 1071 { 1072 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_REGISTRATION_DEADLINE, registrationDeadline); 1073 } 1074 1075 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_DETAIL); 1076 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_PROCESS); 1077 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_MODALITIES, program.getInscription(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.INSCRIPTION), _sourceResolver, false, isExportForAmetys()); 1078 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_PROCESS); 1079 LocalDate registrationStart = program.getRegistrationStart(); 1080 if (registrationStart != null) 1081 { 1082 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_REGISTRATION_START, registrationStart); 1083 } 1084 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_DETAIL); 1085 1086 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1087 } 1088 1089 /** 1090 * SAX CDMfr events for a {@link AbstractProgram} codes 1091 * @param contentHandler the content handler to sax into 1092 * @param program the program or subprogram 1093 * @throws SAXException if an error occurred 1094 */ 1095 protected void _abstractProgram2CDMCode(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1096 { 1097 AttributesImpl attrs = new AttributesImpl(); 1098 1099 // <programCode codeSet="userDefined">code</programCode> 1100 String code = program.getCode(); 1101 if (StringUtils.isNotBlank(code)) 1102 { 1103 attrs = new AttributesImpl(); 1104 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "userDefined"); 1105 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, code); 1106 } 1107 1108 // <programCode codeSet="codeCNIS-NSF">code</programCode> 1109 // <programCode libSet="codeCNIS-NSF">label</programCode> 1110 String nsfId = ContentDataHelper.getContentIdFromContentData(program, "nsfCode"); 1111 if (StringUtils.isNotBlank(nsfId)) 1112 { 1113 attrs = new AttributesImpl(); 1114 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "codeCNIS-NSF"); 1115 1116 String nsfCode = _refTableHelper.getItemCode(nsfId); 1117 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, nsfCode); 1118 1119 String codeLib = _refTableHelper.getItemCDMfrValue(nsfId, false); 1120 if (StringUtils.isNotEmpty(codeLib)) 1121 { 1122 attrs = new AttributesImpl(); 1123 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "codeCNIS-NSF"); 1124 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1125 } 1126 } 1127 1128 // <programCode codeSet="sectDGESIP">code</programCode> 1129 // <programCode libSet="sectDGESIP">label</programCode> 1130 for (String id : program.getDGESIPCode()) 1131 { 1132 attrs = new AttributesImpl(); 1133 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "sectDGESIP"); 1134 1135 String dgesipCode = _refTableHelper.getItemCode(id); 1136 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, dgesipCode); 1137 1138 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1139 if (StringUtils.isNotEmpty(codeLib)) 1140 { 1141 attrs = new AttributesImpl(); 1142 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "sectDGESIP"); 1143 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1144 } 1145 } 1146 1147 // <programCode codeSet="ERASMUS">code</programCode> 1148 // <programCode libSet="ERASMUS">label</programCode> 1149 for (String id : program.getErasmusCode()) 1150 { 1151 attrs = new AttributesImpl(); 1152 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "ERASMUS"); 1153 1154 String erasmusCode = _refTableHelper.getItemCode(id); 1155 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, erasmusCode); 1156 1157 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1158 if (StringUtils.isNotEmpty(codeLib)) 1159 { 1160 attrs = new AttributesImpl(); 1161 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "ERASMUS"); 1162 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1163 } 1164 } 1165 1166 // <programCode codeSet="cite97">code</programCode> 1167 // <programCode libSet="cite97">label</programCode> 1168 for (String id : program.getCite97Code()) 1169 { 1170 attrs = new AttributesImpl(); 1171 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "cite97"); 1172 String cite97Code = _refTableHelper.getItemCode(id); 1173 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, cite97Code); 1174 1175 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1176 if (StringUtils.isNotEmpty(codeLib)) 1177 { 1178 attrs = new AttributesImpl(); 1179 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "cite97"); 1180 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1181 } 1182 } 1183 1184 // <programCode codeSet="FAP">code</programCode> 1185 // <programCode libSet="FAP">label</programCode> 1186 for (String id : program.getFapCode()) 1187 { 1188 attrs = new AttributesImpl(); 1189 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "FAP"); 1190 String fapCode = _refTableHelper.getItemCode(id); 1191 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, fapCode); 1192 1193 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1194 if (StringUtils.isNotEmpty(codeLib)) 1195 { 1196 attrs = new AttributesImpl(); 1197 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "FAP"); 1198 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1199 } 1200 } 1201 1202 // <programCode codeSet="codeSectDiscipSISE">code</programCode> 1203 // <programCode libSet="codeSectDiscipSISE">label</programCode> 1204 for (String id : program.getSiseCode()) 1205 { 1206 attrs = new AttributesImpl(); 1207 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "sectDiscipSISE"); 1208 1209 String siseCode = _refTableHelper.getItemCode(id); 1210 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, siseCode); 1211 1212 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1213 if (StringUtils.isNotEmpty(codeLib)) 1214 { 1215 attrs = new AttributesImpl(); 1216 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "sectDiscipSISE"); 1217 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1218 } 1219 } 1220 } 1221 1222 /** 1223 * SAX CDMfr events for a {@link AbstractProgram} contacts 1224 * @param contentHandler the content handler to sax into 1225 * @param program the program or subprogram 1226 * @param persons the contacts 1227 * @param orgUnits the orgunits 1228 * @throws SAXException if an error occurred 1229 */ 1230 protected void _abstractProgram2CDMContacts(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, Set<String> persons, Set<String> orgUnits) throws SAXException 1231 { 1232 AttributesImpl attrs = new AttributesImpl(); 1233 1234 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1235 1236 Map<String, List<String>> contactsByRole = program.getContactsByRole(); 1237 1238 for (Entry<String, List<String>> entry : contactsByRole.entrySet()) 1239 { 1240 String role = entry.getKey(); 1241 List<String> contactIds = entry.getValue(); 1242 1243 String roleCode = null; 1244 if (StringUtils.isNotEmpty(role)) 1245 { 1246 roleCode = _refTableHelper.getItemCode(role); 1247 } 1248 1249 for (String personID : contactIds) 1250 { 1251 try 1252 { 1253 Person person = _resolver.resolveById(personID); 1254 persons.add(person.getId()); 1255 attrs = new AttributesImpl(); 1256 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 1257 if (roleCode != null) 1258 { 1259 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, roleCode); 1260 } 1261 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 1262 } 1263 catch (UnknownAmetysObjectException e) 1264 { 1265 // Contact does exist anymore, ignore it 1266 } 1267 } 1268 } 1269 1270 for (String orgUnitId : program.getOrgUnits()) 1271 { 1272 if (!"".equals(orgUnitId)) 1273 { 1274 try 1275 { 1276 OrgUnit orgUnit = _resolver.resolveById(orgUnitId); 1277 orgUnits.add(orgUnit.getId()); 1278 attrs = new AttributesImpl(); 1279 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 1280 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 1281 } 1282 catch (UnknownAmetysObjectException e) 1283 { 1284 // OrgUnit does exist anymore, ignore it 1285 } 1286 } 1287 } 1288 1289 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1290 } 1291 1292 /** 1293 * SAX CDMfr events for a {@link ProgramPart} strcuture 1294 * @param contentHandler the content handler to sax into 1295 * @param programPart the program part 1296 * @param persons the contacts 1297 * @param orgUnits the orgunits 1298 * @param courses the courses 1299 * @throws SAXException if an error occurred 1300 */ 1301 protected void _programPart2CDMSubPrograms(ContentHandler contentHandler, TraversableProgramPart programPart, Set<String> persons, Set<String> orgUnits, Set<String> courses) throws SAXException 1302 { 1303 ContentValue[] children = programPart.getValue(TraversableProgramPart.CHILD_PROGRAM_PARTS, false, new ContentValue[0]); 1304 for (ContentValue child : children) 1305 { 1306 Optional<ModifiableContent> content = child.getContentIfExists(); 1307 if (content.isPresent()) 1308 { 1309 if (content.get() instanceof AbstractProgram<?> program) 1310 { 1311 abstractProgram2CDM(contentHandler, program, persons, orgUnits, courses); 1312 } 1313 else if (content.get() instanceof Container container) 1314 { 1315 container2CDM(contentHandler, container, persons, orgUnits, courses); 1316 } 1317 } 1318 } 1319 } 1320 1321 1322 //***********************************************************************// 1323 // CONTAINER // 1324 //***********************************************************************// 1325 1326 /** 1327 * Send the CDM-fr representation of their ProgramPart to the given Contenthandler.<br> 1328 * Also collects referenced orgUnits, persons and courses, so that they could be sent afterwards. 1329 * @param contentHandler the receiving contentHandler. 1330 * @param container The container 1331 * @param persons collected {@link Person} ids. 1332 * @param orgUnits collected {@link OrgUnit} ids. 1333 * @param courses collected {@link Course} ids. 1334 * @throws SAXException if an error occurs during CDM processing. 1335 */ 1336 public void container2CDM(ContentHandler contentHandler, Container container, Set<String> persons, Set<String> orgUnits, Set<String> courses) throws SAXException 1337 { 1338 if (container.isPublishable() && switchToLiveVersionIfNeeded(container)) 1339 { 1340 Request request = ContextHelper.getRequest(_context); 1341 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 1342 1343 try 1344 { 1345 request.setAttribute(Content.class.getName(), container); 1346 1347 AttributesImpl attrs = new AttributesImpl(); 1348 1349 // <program id="FR_RNE_{rootOrgUnitId}_PR_{code}"> 1350 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, container.getCDMId()); 1351 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_SUB_PROGRAM, attrs); 1352 1353 // <programID>code</programID> 1354 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PROGRAM_ID, container.getCDMId()); 1355 1356 // <programName><text>name</text></programName> 1357 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 1358 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_TEXT, container.getTitle()); 1359 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 1360 1361 // <programCode codeSet="userDefined">code</programCode> 1362 String code = container.getCode(); 1363 if (StringUtils.isNotBlank(code)) 1364 { 1365 attrs = new AttributesImpl(); 1366 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "userDefined"); 1367 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, code); 1368 } 1369 1370 // <programDescription>...</programDescription> 1371 attrs = new AttributesImpl(); 1372 String nature = container.getNature(); 1373 if (StringUtils.isNotEmpty(nature)) 1374 { 1375 nature = _refTableHelper.getItemCDMfrValue(nature, true); 1376 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_NATURE, nature); 1377 } 1378 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION, attrs); 1379 1380 // <qualification>...</qualification> 1381 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 1382 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, container.getEcts()); 1383 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 1384 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, null, null, null, true, isExportForAmetys()); 1385 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 1386 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 1387 1388 // <programStructure>...</programStructure> 1389 ContentValue[] children = container.getValue(TraversableProgramPart.CHILD_PROGRAM_PARTS, false, new ContentValue[0]); 1390 for (ContentValue child : children) 1391 { 1392 Optional<ModifiableContent> content = child.getContentIfExists(); 1393 if (content.isPresent() && content.get() instanceof CourseList courseList) 1394 { 1395 courselist2CDM(contentHandler, courseList, courses); 1396 } 1397 } 1398 1399 // <infoBlock>...</infoBlock> 1400 attrs = new AttributesImpl(); 1401 attrs.addCDATAAttribute("userDefined", "container"); 1402 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs); 1403 1404 // <infoBlock userDefined="ametys-extension>...</infoBlock> 1405 saxExtensions(contentHandler, container, persons, orgUnits); 1406 1407 // <subProgram>...</subProgram> 1408 _programPart2CDMSubPrograms(contentHandler, container, persons, orgUnits, courses); 1409 1410 // </program> 1411 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_SUB_PROGRAM); 1412 } 1413 finally 1414 { 1415 request.setAttribute(Content.class.getName(), currentContent); 1416 } 1417 } 1418 } 1419 1420 /** 1421 * SAX the course list structure 1422 * @param contentHandler The content handler to SAX into 1423 * @param cl The course list 1424 * @param courses References of saxed courses 1425 * @throws SAXException if an error occurs 1426 */ 1427 public void courselist2CDM (ContentHandler contentHandler, CourseList cl, Set<String> courses) throws SAXException 1428 { 1429 if (cl.isPublishable() && switchToLiveVersionIfNeeded(cl)) 1430 { 1431 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 1432 1433 _courselist2CDM (contentHandler, cl); 1434 1435 for (Course course : cl.getCourses()) 1436 { 1437 if (course.isPublishable()) 1438 { 1439 courses.add(course.getId()); 1440 AttributesImpl attrs = new AttributesImpl(); 1441 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, course.getCDMId()); 1442 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_COURSE, attrs); 1443 } 1444 } 1445 1446 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 1447 } 1448 } 1449 1450 /** 1451 * Convert course list info to CDM (without child courses) 1452 * @param contentHandler The content handler to sax into 1453 * @param cl The course list 1454 * @throws SAXException if an error occurs 1455 */ 1456 protected void _courselist2CDM (ContentHandler contentHandler, CourseList cl) throws SAXException 1457 { 1458 if (switchToLiveVersionIfNeeded(cl)) 1459 { 1460 AttributesImpl attrs = new AttributesImpl(); 1461 attrs.addCDATAAttribute("userDefined", "listCode"); 1462 String code = cl.getCode(); 1463 if (StringUtils.isEmpty(code)) 1464 { 1465 code = org.ametys.core.util.StringUtils.generateKey().toUpperCase(); 1466 } 1467 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, code); 1468 1469 attrs = new AttributesImpl(); 1470 attrs.addCDATAAttribute("userDefined", "listName"); 1471 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, cl.getTitle()); 1472 1473 ChoiceType type = cl.getType(); 1474 if (type != null) 1475 { 1476 attrs = new AttributesImpl(); 1477 attrs.addCDATAAttribute("userDefined", "listChoiceType"); 1478 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, cl.getType().toString().toLowerCase()); 1479 } 1480 1481 if (type != null && type.equals(ChoiceType.CHOICE)) 1482 { 1483 attrs = new AttributesImpl(); 1484 attrs.addCDATAAttribute("userDefined", "listMinNumberOfCourses"); 1485 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, String.valueOf(cl.getMinNumberOfCourses())); 1486 1487 attrs = new AttributesImpl(); 1488 attrs.addCDATAAttribute("userDefined", "listMaxNumberOfCourses"); 1489 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, String.valueOf(cl.getMaxNumberOfCourses())); 1490 } 1491 } 1492 } 1493 1494 //***********************************************************************// 1495 // COURSE // 1496 //***********************************************************************// 1497 1498 /** 1499 * Export this entity in CDM-fr format. 1500 * @param contentHandler the target handler 1501 * @param course The course 1502 * @throws SAXException if an error occurs during export. 1503 */ 1504 public void course2CDM(ContentHandler contentHandler, Course course) throws SAXException 1505 { 1506 boolean rootOrgUnitSaxed = false; 1507 1508 Set<String> orgUnits = new HashSet<>(); 1509 Set<String> persons = new HashSet<>(); 1510 1511 Set<String> coursesAlreadySax = new HashSet<>(); 1512 Set<String> coursesToSax = new HashSet<>(); 1513 coursesToSax.add(course.getId()); 1514 1515 while (!coursesToSax.isEmpty()) 1516 { 1517 Set<String> courses = new HashSet<>(); 1518 for (String courseId : coursesToSax) 1519 { 1520 coursesAlreadySax.add(courseId); 1521 Course courseToSax = _resolver.resolveById(courseId); 1522 courses.addAll(course2CDM(contentHandler, courseToSax, orgUnits, persons)); 1523 } 1524 coursesToSax.clear(); 1525 coursesToSax.addAll(courses); 1526 coursesToSax.removeAll(coursesAlreadySax); 1527 } 1528 1529 for (String orgUnitId : orgUnits) 1530 { 1531 OrgUnit orgUnit = _resolver.resolveById(orgUnitId); 1532 if (orgUnitId.equals(_rootOrgUnitProvider.getRootId())) 1533 { 1534 rootOrgUnitSaxed = true; 1535 } 1536 _orgunit2CDM(contentHandler, orgUnit, persons); 1537 } 1538 1539 if (!rootOrgUnitSaxed) 1540 { 1541 OrgUnit orgUnit = _rootOrgUnitProvider.getRoot(); 1542 _orgunit2CDM(contentHandler, orgUnit, persons); 1543 } 1544 1545 for (String personId : persons) 1546 { 1547 Person person = _resolver.resolveById(personId); 1548 person2CDM(contentHandler, person); 1549 } 1550 1551 // Set content in request 1552 ContextHelper.getRequest(_context).setAttribute(Content.class.getName(), course); 1553 } 1554 1555 /** 1556 * Export this entity in CDM-fr format. 1557 * @param contentHandler the content handler to SAX into 1558 * @param course the course 1559 * @param orgUnits the org units 1560 * @param persons the persons 1561 * @return the saxed coursed 1562 * @throws SAXException if failed to generate CDM 1563 */ 1564 public Set<String> course2CDM(ContentHandler contentHandler, Course course, Set<String> orgUnits, Set<String> persons) throws SAXException 1565 { 1566 DataContext courseRichTextsContext = RepositoryDataContext.newInstance() 1567 .withObject(course); 1568 1569 if (!course.isPublishable() || !switchToLiveVersionIfNeeded(course)) 1570 { 1571 return new HashSet<>(); 1572 } 1573 1574 Request request = ContextHelper.getRequest(_context); 1575 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 1576 1577 try 1578 { 1579 request.setAttribute(Content.class.getName(), course); 1580 1581 AttributesImpl attrs = new AttributesImpl(); 1582 1583 // <course id="FR_RNE_{rootOrgUnitId}_CO_{code}" language="..."> 1584 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, course.getCDMId()); 1585 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LANGUAGE, course.getLanguage()); 1586 String erasmusCode = _refTableHelper.getItemCode(course.getErasmusCode()); 1587 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_IDENT, erasmusCode); 1588 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE, attrs); 1589 1590 // <courseID>code</courseID> 1591 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_ID, course.getCDMId()); 1592 1593 // <courseName><text>name</text></courseName> 1594 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_NAME); 1595 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, course.getTitle()); 1596 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_NAME); 1597 1598 // <courseCode codeSet="UE">code</couseCode> 1599 String courseType = _refTableHelper.getItemCode(course.getCourseType()); 1600 attrs = new AttributesImpl(); 1601 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, courseType); 1602 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_CODE, attrs, course.getCdmCode()); 1603 1604 // <webLink> 1605 // <href>href</href> 1606 // <linkName>linkName</linkName> 1607 // </webLink> 1608 String webLinkURL = course.getWebLinkUrl(); 1609 if (StringUtils.isNotEmpty(webLinkURL)) 1610 { 1611 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 1612 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, webLinkURL); 1613 String webLinkLabel = course.getWebLinkLabel(); 1614 if (StringUtils.isNotEmpty(webLinkLabel)) 1615 { 1616 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LINK_NAME, course.getWebLinkLabel()); 1617 } 1618 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 1619 } 1620 1621 // <level>level</level> 1622 attrs = new AttributesImpl(); 1623 String level = _refTableHelper.getItemCDMfrValue(course.getLevel(), true); 1624 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_LEVEL, level); 1625 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1626 1627 // <courseDescription>...</courseDescription> 1628 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_DESCRIPTION); 1629 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGITAL_USE); 1630 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PERCENTAGE, "0"); 1631 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LCMS); 1632 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_EXISTS, "false"); 1633 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_RESOURCE_MGT); 1634 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PERC_OF_USE, "0"); 1635 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LCMS); 1636 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROD_PEDA); 1637 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGIT_PROD_PERC, "0"); 1638 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGIT_PROD_UNT_PERC, "0"); 1639 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROD_PEDA); 1640 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGITAL_USE); 1641 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_INFO_BLOCK, course.getDescription(), courseRichTextsContext.cloneContext().withDataPath(Course.DESCRIPTION), _sourceResolver, true, isExportForAmetys()); 1642 1643 Set<String> courses = _courseLists2CDM(contentHandler, course); 1644 1645 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_DESCRIPTION); 1646 1647 // <teachingTerm term="" timeOfDay="" start=""/> 1648 attrs = new AttributesImpl(); 1649 LocalDate startDate = course.getStartDate(); 1650 if (startDate != null) 1651 { 1652 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_START, startDate.format(CDMHelper.CDM_DATE_FORMATTER)); 1653 } 1654 1655 String teachingTerm = _refTableHelper.getItemCDMfrValue(course.getTeachingTerm(), true); 1656 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TERM, teachingTerm); 1657 String timeSlot = _refTableHelper.getItemCDMfrValue(course.getTimeSlot(), true); 1658 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TIME_OF_DAY, timeSlot); 1659 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_TERM, attrs); 1660 1661 // <credits ECTScredits="" totalWorkLoad=""> 1662 // <infoBlock>...</infoBlock> 1663 // <globalVolume teachingType="CM/TP/TD">...</globalVolume> 1664 // </credits> 1665 _credits2CDM(contentHandler, course); 1666 1667 // <learningObjectives>...</learningObjectives> 1668 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES); 1669 CDMHelper.richText2CDM(contentHandler, course.getObjectives(), courseRichTextsContext.cloneContext().withDataPath(Course.OBJECTIVES), _sourceResolver, isExportForAmetys()); 1670 // <ametys-cdm:skills>...</ametys-cdm:skills> 1671 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skills", course.getSkills(), courseRichTextsContext.cloneContext().withDataPath(Course.SKILLS), _sourceResolver, false, isExportForAmetys()); 1672 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES); 1673 1674 // <admissionInfo> 1675 // <studentPlaces places=""/> 1676 // <teachingStart date=""/> 1677 // </admissionInfo> 1678 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1679 1680 String maxNumberOfStudents = course.getMaxNumberOfStudents(); 1681 if (StringUtils.isNotEmpty(maxNumberOfStudents)) 1682 { 1683 attrs = new AttributesImpl(); 1684 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_PLACES, maxNumberOfStudents); 1685 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_STUDENT_PLACES, attrs); 1686 } 1687 1688 if (startDate != null) 1689 { 1690 attrs = new AttributesImpl(); 1691 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_DATE, new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.asDate(startDate))); 1692 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_START, attrs); 1693 } 1694 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1695 1696 // <formalPrerequisites>...</formalPrerequisites> 1697 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORMAL_PREREQUISITES, course.getNeededPrerequisite(), courseRichTextsContext.cloneContext().withDataPath(Course.NEEDED_PREREQUISITE), _sourceResolver, true, isExportForAmetys()); 1698 1699 // <teachingPlace> 1700 // <cdmfr:refOrgUnit /> 1701 // <adr> 1702 // <pcode></pcode> 1703 // </adr> 1704 // </teachingPlace> 1705 _teachingLocation2CDM(contentHandler, course); 1706 1707 // <formOfTeaching method="" org=""/> 1708 String formOfTeachingMethod = _refTableHelper.getItemCDMfrValue(course.getFormOfTeachingMethod(), false); 1709 for (String formOfTeachingOrg: course.getFormOfTeachingOrgs()) 1710 { 1711 attrs = new AttributesImpl(); 1712 String formOfTeachingOrgValue = _refTableHelper.getItemCDMfrValue(formOfTeachingOrg, false); 1713 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, formOfTeachingMethod); 1714 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ORG, formOfTeachingOrgValue); 1715 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_TEACHING, attrs); 1716 } 1717 1718 // <formOfAssessment>...</formOfAssessment> 1719 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_ASSESSMENT, course.getFormOfAssessment(), courseRichTextsContext.cloneContext().withDataPath(Course.FORM_OF_ASSESSMENT), _sourceResolver, false, isExportForAmetys()); 1720 1721 // <instructionLanguage teachingLang=""/> 1722 String[] teachingLanguages = course.getTeachingLanguage(); 1723 for (String teachingLanguage : teachingLanguages) 1724 { 1725 String teachingLanguageValue = _refTableHelper.getItemCDMfrValue(teachingLanguage, true); 1726 attrs = new AttributesImpl(); 1727 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_LANG, teachingLanguageValue); 1728 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INSTRUCTION_LANGUAGE, attrs); 1729 } 1730 1731 // <syllabus> 1732 // ... 1733 // <webLink role="learningObjectMetadata"> 1734 // <href>...</href> 1735 // <linkName>...</linkName> 1736 // </webLink> 1737 // </syllabus> 1738 _syllabus2CDM(contentHandler, course, courseRichTextsContext); 1739 1740 // <teachingActivity method=""/> 1741 attrs = new AttributesImpl(); 1742 String teachingActivity = _refTableHelper.getItemCDMfrValue(course.getTeachingActivity(), true); 1743 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, teachingActivity); 1744 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_ACTIVITY, attrs); 1745 1746 // <contacts> 1747 // <refPerson idRef=ID/> 1748 // </contacts> 1749 _course2CDMContacts(contentHandler, course, persons, orgUnits); 1750 1751 // <infoBlock>...</infoBlock> 1752 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, course.getAdditionalInformations(), courseRichTextsContext.cloneContext().withDataPath(Course.ADDITIONAL_INFORMATIONS), _sourceResolver, false, isExportForAmetys()); 1753 1754 // <infoBlock userDefined="ametys-extension>...</infoBlock> 1755 saxExtensions(contentHandler, course, persons, orgUnits); 1756 1757 // <searchword>keyword</searchword> 1758 for (String keyword : course.getKeywords()) 1759 { 1760 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_SEARCH_WORD, keyword); 1761 } 1762 1763 // </course> 1764 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE); 1765 1766 return courses; 1767 } 1768 finally 1769 { 1770 request.setAttribute(Content.class.getName(), currentContent); 1771 } 1772 } 1773 1774 /** 1775 * Sax the courses lists for a course. 1776 * @param contentHandler the content handler to SAX into 1777 * @param course The courselist container. 1778 * @return The list of courses into the course list. 1779 * @throws SAXException if failed to generate CDM 1780 */ 1781 protected Set<String> _courseLists2CDM(ContentHandler contentHandler, Course course) throws SAXException 1782 { 1783 Set<String> courses = new HashSet<>(); 1784 1785 for (CourseList coursesList : course.getCourseLists()) 1786 { 1787 if (coursesList.isPublishable()) 1788 { 1789 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COURSE_CONTENTS); 1790 1791 // SAX infos on course list. This DO NOT respect the CDM-fr schema 1792 _courselist2CDM(contentHandler, coursesList); 1793 1794 for (Course childCourse : coursesList.getCourses()) 1795 { 1796 if (childCourse.isPublishable()) 1797 { 1798 courses.add(childCourse.getId()); 1799 AttributesImpl attrs = new AttributesImpl(); 1800 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, childCourse.getCDMId()); 1801 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_COURSE, attrs); 1802 } 1803 } 1804 1805 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COURSE_CONTENTS); 1806 } 1807 } 1808 1809 return courses; 1810 } 1811 1812 /** 1813 * Sax the course credits. 1814 * @param contentHandler the content handler to SAX into 1815 * @param course The course to sax 1816 * @throws SAXException if failed to generate CDM 1817 */ 1818 protected void _credits2CDM(ContentHandler contentHandler, Course course) throws SAXException 1819 { 1820 AttributesImpl attrs = new AttributesImpl(); 1821 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TOTAL_WORK_LOAD, course.getNumberOfHours()); 1822 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, course.getEcts()); 1823 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 1824 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, null, null, _sourceResolver, true, isExportForAmetys()); 1825 1826 Map<String, Double> hoursByNature = new HashMap<>(); 1827 List<CoursePart> courseParts = course.getCourseParts(); 1828 for (CoursePart coursePart : courseParts) 1829 { 1830 String nature = coursePart.getNature(); 1831 Double hours = MapUtils.getDouble(hoursByNature, nature, 0d) + coursePart.getNumberOfHours(); 1832 if (hours > 0) 1833 { 1834 hoursByNature.put(nature, hours); 1835 } 1836 } 1837 1838 for (String nature : hoursByNature.keySet()) 1839 { 1840 attrs = new AttributesImpl(); 1841 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_TYPE, _refTableHelper.getItemCDMfrValue(nature, true)); 1842 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_GLOBAL_VOLUME, attrs, String.valueOf(hoursByNature.get(nature))); 1843 } 1844 1845 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 1846 } 1847 1848 /** 1849 * SAX the syllabus elements of the course. 1850 * @param contentHandler The content handler 1851 * @param course The course to SAX 1852 * @param courseRichTextsContext the context for course's rich texts 1853 * @throws SAXException if an error occurs 1854 */ 1855 protected void _syllabus2CDM(ContentHandler contentHandler, Course course, DataContext courseRichTextsContext) throws SAXException 1856 { 1857 RichText syllabus = course.getSyllabus(); 1858 RichText bibliography = course.getBibliography(); 1859 Set<LOMSheet> lomSheets = course.getLOMSheets(); 1860 if (syllabus != null || bibliography != null || !lomSheets.isEmpty()) 1861 { 1862 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_SYLLABUS); 1863 1864 // Syllabus 1865 if (syllabus != null) 1866 { 1867 CDMHelper.richText2CDM(contentHandler, syllabus, courseRichTextsContext.cloneContext().withDataPath(Course.SYLLABUS), _sourceResolver, isExportForAmetys()); 1868 } 1869 1870 // Bibliography 1871 if (bibliography != null) 1872 { 1873 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CDMFRTagsConstants.TAG_BIBLIOGRAPHY, bibliography, courseRichTextsContext.cloneContext().withDataPath(Course.BIBLIOGRAPHY), _sourceResolver, false, isExportForAmetys()); 1874 } 1875 1876 // LOM sheets 1877 for (LOMSheet lomSheet : lomSheets) 1878 { 1879 lomSheet.toCDM(contentHandler); 1880 } 1881 1882 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_SYLLABUS); 1883 } 1884 } 1885 1886 /** 1887 * Sax the course teaching locations. 1888 * @param contentHandler the content handler to SAX into 1889 * @param course The course to sax 1890 * @throws SAXException if failed to generate CDM 1891 */ 1892 protected void _teachingLocation2CDM(ContentHandler contentHandler, Course course) throws SAXException 1893 { 1894 for (String id : course.getTeachingLocation()) 1895 { 1896 if (StringUtils.isNotEmpty(id)) 1897 { 1898 String postalCode = _refTableHelper.getItemCode(id); 1899 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 1900 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 1901 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 1902 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, postalCode); 1903 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 1904 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 1905 } 1906 } 1907 } 1908 1909 /** 1910 * SAX CDMfr events for a {@link Course} contacts 1911 * @param contentHandler the content handler to sax into 1912 * @param course the course 1913 * @param persons the contacts 1914 * @param orgUnits the orgunits 1915 * @throws SAXException if an error occurred 1916 */ 1917 protected void _course2CDMContacts(ContentHandler contentHandler, Course course, Set<String> persons, Set<String> orgUnits) throws SAXException 1918 { 1919 AttributesImpl attrs = new AttributesImpl(); 1920 1921 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1922 1923 Map<String, List<String>> contactsByRole = course.getContactsByRole(); 1924 1925 for (Entry<String, List<String>> entry : contactsByRole.entrySet()) 1926 { 1927 String role = entry.getKey(); 1928 List<String> contactIds = entry.getValue(); 1929 1930 String roleCode = null; 1931 if (StringUtils.isNotEmpty(role)) 1932 { 1933 roleCode = _refTableHelper.getItemCode(role); 1934 } 1935 1936 for (String personID : contactIds) 1937 { 1938 try 1939 { 1940 Person person = _resolver.resolveById(personID); 1941 persons.add(person.getId()); 1942 attrs = new AttributesImpl(); 1943 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 1944 if (roleCode != null) 1945 { 1946 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, roleCode); 1947 } 1948 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 1949 } 1950 catch (UnknownAmetysObjectException e) 1951 { 1952 // Contact does exist anymore, ignore it 1953 } 1954 } 1955 } 1956 1957 for (String orgUnitID : course.getOrgUnits()) 1958 { 1959 if (!"".equals(orgUnitID)) 1960 { 1961 try 1962 { 1963 OrgUnit orgUnit = _resolver.resolveById(orgUnitID); 1964 orgUnits.add(orgUnit.getId()); 1965 attrs = new AttributesImpl(); 1966 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 1967 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 1968 } 1969 catch (UnknownAmetysObjectException e) 1970 { 1971 // OrgUnit does exist anymore, ignore it 1972 } 1973 } 1974 } 1975 1976 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1977 } 1978 1979 1980 //***********************************************************************// 1981 // ORGUNIT // 1982 //***********************************************************************// 1983 1984 /** 1985 * Export this entity in CDM-fr format. 1986 * @param contentHandler the target handler 1987 * @param orgunit the orgunit 1988 * @throws SAXException if an error occurs during export. 1989 */ 1990 public void orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit) throws SAXException 1991 { 1992 Set<String> persons = new HashSet<>(); 1993 1994 _orgunit2CDM(contentHandler, orgunit, persons, true); 1995 1996 for (String personId : persons) 1997 { 1998 Person person = _resolver.resolveById(personId); 1999 person2CDM(contentHandler, person); 2000 } 2001 2002 if (!orgunit.getId().equals(_rootOrgUnitProvider.getRootId())) 2003 { 2004 OrgUnit rootOrgunit = _resolver.resolveById(_rootOrgUnitProvider.getRootId()); 2005 _orgunit2CDM(contentHandler, rootOrgunit, persons); 2006 } 2007 2008 // Set content in request 2009 ContextHelper.getRequest(_context).setAttribute(Content.class.getName(), orgunit); 2010 } 2011 2012 /** 2013 * SAX CDMfr event for a {@link OrgUnit} 2014 * @param contentHandler the content handler to sax into 2015 * @param orgunit the orgunit 2016 * @param persons the contacts of orgunit 2017 * @throws SAXException if an error occurred 2018 */ 2019 protected void _orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit, Set<String> persons) throws SAXException 2020 { 2021 _orgunit2CDM(contentHandler, orgunit, persons, false); 2022 } 2023 2024 /** 2025 * SAX CDMfr event for a {@link OrgUnit} 2026 * @param contentHandler the content handler to sax into 2027 * @param orgunit the orgunit 2028 * @param persons the contacts of orgunit 2029 * @param showChildren true to sax child orgunits 2030 * @throws SAXException if an error occurred 2031 */ 2032 protected void _orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit, Set<String> persons, boolean showChildren) throws SAXException 2033 { 2034 Request request = ContextHelper.getRequest(_context); 2035 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 2036 DataContext orgunitRichTextsContext = RepositoryDataContext.newInstance() 2037 .withObject(orgunit); 2038 2039 try 2040 { 2041 _odfHelper.switchToLiveVersionIfNeeded(orgunit); 2042 2043 request.setAttribute(Content.class.getName(), orgunit); 2044 2045 AttributesImpl attrs = new AttributesImpl(); 2046 2047 // <orgunit id="FR_RNE_{rootOrgUnitId}_OR_{login}"> 2048 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, orgunit.getCDMId()); 2049 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT, attrs); 2050 2051 // <orgUnitID>RNE</orgUnitID> 2052 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_ID, orgunit.getCDMId()); 2053 2054 // <orgUnitName><text>name</text></orgUnitID> 2055 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_NAME); 2056 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, orgunit.getTitle()); 2057 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_NAME); 2058 2059 // <orgUnitAcronym>acronyme</orgUnitAcronym> 2060 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_ACRONYM, orgunit.getAcronym()); 2061 2062 // <orgUnitCode codeSet="codeUAI">code</orgUnitCode> 2063 attrs = new AttributesImpl(); 2064 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "codeUAI"); 2065 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_CODE, attrs, orgunit.getUAICode()); 2066 2067 // <orgUnitKind orgUnitKindCodeValueSet=""/> 2068 attrs = new AttributesImpl(); 2069 String orgunitType = _refTableHelper.getItemCDMfrValue(orgunit.getType(), false); 2070 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ORG_UNIT_KIND_CODE_VALUESET, orgunitType); 2071 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_KIND); 2072 2073 // <webLink> 2074 // <href>href</href> 2075 // <linkName>linkName</linkName> 2076 // </webLink> 2077 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 2078 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, orgunit.getWebLinkURL()); 2079 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LINK_NAME, orgunit.getWebLinkLabel()); 2080 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 2081 2082 // <orgUnitDescription>...</orgUnitDescription> 2083 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_DESCRIPTION, orgunit.getDescription(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.DESCRIPTION), _sourceResolver, false, isExportForAmetys()); 2084 2085 // <admissionInfo> 2086 // <admissionDescription>...</admissionDescription> 2087 // </admissionInfo> 2088 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 2089 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ADMISSION_DESCRIPTION, orgunit.getAdmissionInfo(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.ADMISSION_INFO), _sourceResolver); 2090 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 2091 2092 // <regulations>...</regulations> 2093 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_REGULATIONS, orgunit.getRegulations(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.REGULATIONS), _sourceResolver, false, isExportForAmetys()); 2094 2095 // <expenses>...</expenses> 2096 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_EXPENSES, orgunit.getExpenses(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.EXPENSES), _sourceResolver, false, isExportForAmetys()); 2097 2098 // <studentFacilities>...</studentFacilities> 2099 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDENT_FACILITIES, orgunit.getStudentFacilities(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.STUDENT_FACILITIES), _sourceResolver, false, isExportForAmetys()); 2100 2101 // <universalAjustment>...</universalAjustment> 2102 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_UNIVERSAL_ADJUSTMENT, orgunit.getUniversalAdjustment(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.UNIVERSAL_ADJUSTMENT), _sourceResolver, false, isExportForAmetys()); 2103 2104 // <contacts> 2105 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 2106 2107 for (String contactID : orgunit.getContacts()) 2108 { 2109 if (StringUtils.isNotEmpty(contactID)) 2110 { 2111 try 2112 { 2113 Person person = _resolver.resolveById(contactID); 2114 persons.add(person.getId()); 2115 attrs = new AttributesImpl(); 2116 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 2117 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, "contact"); 2118 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 2119 } 2120 catch (UnknownAmetysObjectException e) 2121 { 2122 // Contact does exist anymore, ignore it 2123 } 2124 } 2125 } 2126 2127 // </contacts> 2128 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 2129 2130 // <infoBlock>...</infoBlock> 2131 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, orgunit.getAdditionnalInfos(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.ADDITIONNAL_INFOS), _sourceResolver, false, isExportForAmetys()); 2132 2133 Set<OrgUnit> orgUnits = new HashSet<>(); 2134 if (showChildren) 2135 { 2136 // <refOrgUnit IDref=""/> 2137 for (String orgUnitID : orgunit.getSubOrgUnits()) 2138 { 2139 try 2140 { 2141 OrgUnit orgUnit = _resolver.resolveById(orgUnitID); 2142 orgUnits.add(orgUnit); 2143 attrs = new AttributesImpl(); 2144 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 2145 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 2146 } 2147 catch (UnknownAmetysObjectException e) 2148 { 2149 // OrgUnit does exist anymore, ignore it 2150 } 2151 } 2152 } 2153 2154 // <infoBlock userDefined="ametys-extension>...</infoBlock> 2155 saxExtensions(contentHandler, orgunit, null, null); 2156 2157 // </orgunit> 2158 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT); 2159 2160 for (OrgUnit childOrgunit : orgUnits) 2161 { 2162 _orgunit2CDM(contentHandler, childOrgunit, persons); 2163 } 2164 } 2165 catch (NoLiveVersionException e) 2166 { 2167 getLogger().error("Orgunit {} ({}) is not validated so it cannot be exported to CDM-fr.", orgunit.getTitle(), orgunit.getId()); 2168 } 2169 finally 2170 { 2171 request.setAttribute(Content.class.getName(), currentContent); 2172 } 2173 } 2174 2175 2176 //***********************************************************************// 2177 // PERSON // 2178 //***********************************************************************// 2179 2180 /** 2181 * Export this entity in CDM-fr format. 2182 * @param contentHandler the target handler 2183 * @param person the person 2184 * @throws SAXException if an error occurs during export. 2185 */ 2186 public void person2CDM(ContentHandler contentHandler, Person person) throws SAXException 2187 { 2188 Request request = ContextHelper.getRequest(_context); 2189 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 2190 2191 try 2192 { 2193 _odfHelper.switchToLiveVersionIfNeeded(person); 2194 2195 request.setAttribute(Content.class.getName(), person); 2196 2197 AttributesImpl attrs = new AttributesImpl(); 2198 2199 // <person id="FRUAI{rootOrgUnitId}PE{login}"> 2200 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, person.getCDMId()); 2201 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_PERSON, attrs); 2202 2203 // <personID>login</personID> 2204 String login = person.getLogin(); 2205 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PERSON_ID, StringUtils.isNotEmpty(login) ? login : person.getName()); 2206 2207 // <name> 2208 // <given>prénom</given> 2209 // <family>nom</family> 2210 // </name> 2211 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_NAME); 2212 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_GIVEN_NAME, person.getGivenName()); 2213 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FAMILY_NAME, person.getLastName()); 2214 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_NAME); 2215 2216 // <title><text>titre</text></title> 2217 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TITLE); 2218 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, person.getPersonTitle()); 2219 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TITLE); 2220 2221 // <role><text>role</text></role> 2222 for (String role : person.getRole()) 2223 { 2224 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ROLE); 2225 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, role); 2226 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ROLE); 2227 } 2228 2229 // <affiliation> 2230 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_AFFILIATION); 2231 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 2232 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESS_FIELD); 2233 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_SECT_CNU); 2234 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_AFFILIATION); 2235 2236 2237 // <contactData> 2238 ContactData contactData = person.getContactData(); 2239 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACT_DATA); 2240 2241 // <adr> 2242 // <extadr>extadr</extadr> 2243 // <street>address</street> 2244 // <locality>locality</locality> 2245 // <pcode>pcode</pcode> 2246 // </adr> 2247 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 2248 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_EXTADR, contactData.getAdditionalAddress()); 2249 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_STREET, contactData.getAddress()); 2250 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LOCALITY, contactData.getTown()); 2251 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, contactData.getZipCode()); 2252 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 2253 2254 // <telephone>telephone</telephone> 2255 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PHONE, contactData.getPhone()); 2256 2257 // <fax>fax</fax> 2258 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FAX, contactData.getFax()); 2259 2260 // <email>email</email> 2261 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_EMAIL, contactData.getMail()); 2262 2263 // <webLink> 2264 // <href>href</href> 2265 // <linkName>linkName</linkName> 2266 // </webLink> 2267 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_WEB_LINK); 2268 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, contactData.getWebLinkUrl()); 2269 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LINK_NAME, contactData.getWebLinkLabel()); 2270 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_WEB_LINK); 2271 2272 // </contactData> 2273 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACT_DATA); 2274 2275 // <infoBlock>...</infoBlock> 2276 DataContext context = RepositoryDataContext.newInstance() 2277 .withObject(person) 2278 .withDataPath(Person.ADDITIONAL_INFORMATIONS); 2279 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, person.getAdditionalInformations(), context, _sourceResolver, false, isExportForAmetys()); 2280 2281 // <infoBlock userDefined="ametys-extension>...</infoBlock> 2282 saxExtensions(contentHandler, person, null, null); 2283 2284 // </person> 2285 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_PERSON); 2286 } 2287 catch (NoLiveVersionException e) 2288 { 2289 getLogger().error("Person {} ({}) is not validated so it cannot be exported to CDM-fr.", person.getTitle(), person.getId()); 2290 } 2291 finally 2292 { 2293 request.setAttribute(Content.class.getName(), currentContent); 2294 } 2295 } 2296 2297 private String _getMentionType(Program program) 2298 { 2299 return Optional.ofNullable(program.<ContentValue>getValue(AbstractProgram.DEGREE)) 2300 .flatMap(ContentValue::getContentIfExists) 2301 .map(c -> c.<String>getValue(OdfReferenceTableHelper.DEGREE_MENTION_TYPE)) 2302 .orElse(null); 2303 } 2304 2305 //***********************************************************************// 2306 // MISC // 2307 //***********************************************************************// 2308 2309 /** 2310 * SAX value as attributes if not null nor empty 2311 * @param attrs the XML attributes 2312 * @param localName the local name 2313 * @param value the value 2314 */ 2315 protected void _addNotNullAttribute(AttributesImpl attrs, String localName, String value) 2316 { 2317 if (StringUtils.isNotEmpty(value)) 2318 { 2319 attrs.addCDATAAttribute(localName, value); 2320 } 2321 } 2322 2323 /** 2324 * SAX value as attributes if not null nor empty 2325 * @param attrs the XML attributes 2326 * @param localName the local name 2327 * @param value the value 2328 */ 2329 protected void _addPositiveAttribute(AttributesImpl attrs, String localName, double value) 2330 { 2331 if (value > 0) 2332 { 2333 attrs.addCDATAAttribute(localName, String.valueOf(value)); 2334 } 2335 } 2336}