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 _websiteLinks2CDM(contentHandler, program); 673 674 // <programDescription>...</programDescription> 675 attrs = new AttributesImpl(); 676 String programType = program.getEducationKind(); 677 if (StringUtils.isNotEmpty(programType)) 678 { 679 programType = _refTableHelper.getItemCDMfrValue(programType, false); 680 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_NATURE, programType); 681 } 682 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION, attrs); 683 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getPresentation(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.PRESENTATION), _sourceResolver, false, isExportForAmetys()); 684 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION); 685 686 // <qualification>...</qualification> 687 _qualification2CDM(contentHandler, program, programRichTextsContext); 688 689 // <levelCode @codeSet="bac|bac+1|bac+2|bac+3|..."/> 690 // <level @level="L|M|Doc"/> 691 _level2CDM(contentHandler, program); 692 693 // <learningObjectives>...</learningObjectives> 694 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES, program.getObjectives(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.OBJECTIVES), _sourceResolver, false, isExportForAmetys()); 695 696 // <admissionInfo> 697 // <cdmfr:admissionDescription>...</cdmfr:admissionDescription> 698 // </admissionInfo> 699 _admissionInfo2CDM(contentHandler, program, programRichTextsContext); 700 701 // <recommendedPrerequisites>...</recommendedPrerequisites> 702 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_RECOMMANDED_PREREQUISITES, program.getRecommendedPrerequisite(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.RECOMMENDED_PREREQUISITE), _sourceResolver, false, isExportForAmetys()); 703 704 // <formalPrerequisites>...</formalPrerequisites> 705 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORMAL_PREREQUISITES, program.getNeededPrerequisite(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.NEEDED_PREREQUISITE), _sourceResolver, true, isExportForAmetys()); 706 707 // <teachingPlace>...</teachingPlace> 708 _place2CDM(contentHandler, program); 709 710 // <targetGroup>...</targetGroup> 711 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_TARGET_GROUP, program.getTargetGroup(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.TARGET_GROUP), _sourceResolver, false, isExportForAmetys()); 712 713 // <formOfTeaching org="" method=""/> 714 String formOfTeachingMethod = _refTableHelper.getItemCDMfrValue(program.getDistanceLearning(), false); 715 for (String formOfTeachingOrg: program.getFormOfTeachingOrgs()) 716 { 717 attrs = new AttributesImpl(); 718 String formOfTeachingOrgValue = _refTableHelper.getItemCDMfrValue(formOfTeachingOrg, false); 719 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, formOfTeachingMethod); 720 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ORG, formOfTeachingOrgValue); 721 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_TEACHING, attrs); 722 } 723 724 // <instructionLanguage teachingLang="fr"/> 725 String[] langs = program.getEducationLanguage(); 726 for (String lang : langs) 727 { 728 String teachingLanguageValue = _refTableHelper.getItemCDMfrValue(lang, true); 729 attrs = new AttributesImpl(); 730 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_LANG, teachingLanguageValue); 731 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INSTRUCTION_LANGUAGE, attrs); 732 } 733 734 // <studyAbroad>...</studoAbroad> 735 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDY_ABROAD, program.getStudyAbroad(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.STUDY_ABROAD), _sourceResolver, false, isExportForAmetys()); 736 737 // <programDuration>...</programDuration> 738 String duration = program.getDuration(); 739 if (StringUtils.isNotBlank(duration)) 740 { 741 String durationValue = _refTableHelper.getItemCDMfrValue(duration, true); 742 if (durationValue != null) 743 { 744 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PROGRAM_DURATION, durationValue); 745 } 746 } 747 748 // <cdmfr:programStructure>...</cdmfr:programStructure> 749 RichText teachingOrganization = program.getTeachingOrganization(); 750 if (teachingOrganization != null && teachingOrganization.getLength() > 0) 751 { 752 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 753 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getTeachingOrganization(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.TEACHING_ORGANIZATION), _sourceResolver, false, isExportForAmetys()); 754 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 755 } 756 757 // Sax courses list 758 ContentValue[] children = program.getValueOrDefault(TraversableProgramPart.CHILD_PROGRAM_PARTS, new ContentValue[0]); 759 for (ContentValue child : children) 760 { 761 Optional<ModifiableContent> content = child.getContentIfExists(); 762 if (content.isPresent() && content.get() instanceof CourseList courseList) 763 { 764 courselist2CDM(contentHandler, courseList, courses); 765 } 766 } 767 768 // <regulations/> 769 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REGULATIONS); 770 771 // <expenses>...</expenses> 772 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_EXPENSES, program.getExpenses(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.EXPENSES), _sourceResolver, false, isExportForAmetys()); 773 774 // <universalAjustment>...</universalAjustment> 775 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_UNIVERSAL_ADJUSTMENT, program.getUniversalAdjustment(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.UNIVERSAL_ADJUSTMENT), _sourceResolver, false, isExportForAmetys()); 776 777 // <contacts> 778 // <refPerson idRef="ID"/> 779 // <refOrgUnit idRef="ID"/> 780 // </contacts> 781 _abstractProgram2CDMContacts(contentHandler, program, persons, orgUnits); 782 783 // <infoBlock>...</infoBlock> 784 attrs = new AttributesImpl(); 785 if (tagName.equals(CDMFRTagsConstants.TAG_SUB_PROGRAM)) 786 { 787 attrs.addCDATAAttribute("userDefined", "subProgram"); 788 } 789 790 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getAdditionalInformations(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.ADDITIONNAL_INFORMATIONS), _sourceResolver, false, isExportForAmetys(), attrs); 791 792 // <infoBlock userDefined="ametys-extension>...</infoBlock> 793 saxExtensions(contentHandler, program, persons, orgUnits); 794 795 // <programStructure>...</programStructure> 796 _programPart2CDMSubPrograms(contentHandler, program, persons, orgUnits, courses); 797 798 // <searchword>keyword</searchword> 799 for (String keyword : program.getKeywords()) 800 { 801 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_SEARCH_WORD, keyword); 802 } 803 804 // </program> 805 XMLUtils.endElement(contentHandler, tagName); 806 } 807 finally 808 { 809 request.setAttribute(Content.class.getName(), currentContent); 810 } 811 } 812 } 813 814 /** 815 * Export CDM extensions handling all elements that do not belong to the CDM-fr schema 816 * @param contentHandler the receiving contentHandler. 817 * @param content the current ODF Content 818 * @param persons collected {@link Person} ids. 819 * @param orgUnits collected {@link OrgUnit} ids. 820 * @throws SAXException if an error occurs during CDM processing. 821 */ 822 protected void saxExtensions(ContentHandler contentHandler, Content content, Set<String> persons, Set<String> orgUnits) throws SAXException 823 { 824 AttributesImpl attrs = new AttributesImpl(); 825 attrs.addCDATAAttribute("userDefined", "ametys-extension"); 826 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs); 827 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_EXTENSION_BLOCK); 828 829 for (String id : _cdmFrExtensionPoint.getExtensionsIds()) 830 { 831 CDMfrExtension cdmFrExtension = _cdmFrExtensionPoint.getExtension(id); 832 833 if (content instanceof AbstractProgram<?> abstractProgram) 834 { 835 if (abstractProgram instanceof Program program) 836 { 837 cdmFrExtension.program2CDM(contentHandler, program, persons, orgUnits); 838 } 839 else if (abstractProgram instanceof SubProgram subProgram) 840 { 841 cdmFrExtension.subProgram2CDM(contentHandler, subProgram, persons, orgUnits); 842 } 843 844 cdmFrExtension.abstractProgram2CDM(contentHandler, abstractProgram, persons, orgUnits); 845 } 846 else if (content instanceof Container container) 847 { 848 cdmFrExtension.container2CDM(contentHandler, container, persons, orgUnits); 849 } 850 else if (content instanceof Course course) 851 { 852 cdmFrExtension.course2CDM(contentHandler, course, persons, orgUnits); 853 } 854 else if (content instanceof Person person) 855 { 856 cdmFrExtension.person2CDM(contentHandler, person); 857 } 858 else if (content instanceof OrgUnit orgunit) 859 { 860 cdmFrExtension.orgunit2CDM(contentHandler, orgunit); 861 } 862 } 863 864 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_EXTENSION_BLOCK); 865 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK); 866 } 867 868 /** 869 * SAX CDM-fr website links 870 * @param contentHandler the content handler to sax into 871 * @param program the program or subprogram 872 * @throws SAXException if an error occurred 873 */ 874 protected void _websiteLinks2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 875 { 876 // <webLink> 877 // <href>href</href> 878 // <linkName>linkName</linkName> 879 // </webLink> 880 for (WebsiteLink website : program.getWebsiteLinks()) 881 { 882 website.toCDM(contentHandler); 883 } 884 } 885 886 /** 887 * SAX CDM-fr teaching places 888 * @param contentHandler the content handler to sax into 889 * @param program the program or subprogram 890 * @throws SAXException if an error occurred 891 */ 892 protected void _place2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 893 { 894 // <teachingPlace> 895 // <cdmfr:refOrgUnit /> 896 // <adr> 897 // <pcode></pcode> 898 // </adr> 899 // </teachingPlace> 900 String[] places = program.getPlace(); 901 for (String id : places) 902 { 903 if (StringUtils.isNotEmpty(id)) 904 { 905 String postalCode = _refTableHelper.getItemCode(id); 906 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 907 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 908 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 909 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, postalCode); 910 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 911 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 912 } 913 } 914 } 915 916 /** 917 * SAX CDM-fr qualification 918 * @param contentHandler the content handler to sax into 919 * @param program the program or subprogram 920 * @param programRichTextsContext the context for program's rich texts 921 * @throws SAXException if an error occurred 922 */ 923 protected void _qualification2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, DataContext programRichTextsContext) throws SAXException 924 { 925 // <qualification> 926 // <qualificatioName><text></text></qualificationName> 927 // <qualificationDescription> 928 // <infoBlock>...</infoBlock> 929 // <statistics>success rate</statistics> 930 // </qualificationDescription> 931 // <degree degree=""/> 932 // <profession>...</profession> 933 // <studyQualification>...</studyQualification> 934 // </qualification> 935 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 936 937 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION_NAME); 938 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT); 939 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION_NAME); 940 941 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_QUALIFICATION_DESCRIPTION); 942 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getQualification(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.QUALIFICATION), _sourceResolver, true, isExportForAmetys()); 943 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STATISTICS, program.getSuccessRate()); 944 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_QUALIFICATION_DESCRIPTION); 945 946 AttributesImpl attrs = new AttributesImpl(); 947 String ects = _refTableHelper.getItemCDMfrValue(program.getEcts(), true); 948 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, ects); 949 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 950 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getKnowledgeCheck(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.KNOWLEDGE_CHECK), _sourceResolver, true, isExportForAmetys()); 951 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 952 953 _degree2CDM(contentHandler, program); 954 955 // <profession> 956 // <infoBlock>...</infoBlock> 957 // <romeData romeCode="code" romeLibel=""/> 958 // </profession> 959 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESSION); 960 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getJobOpportunities(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.JOB_OPPORTUNITIES), _sourceResolver, true, isExportForAmetys()); 961 _romeCodes2CDM(contentHandler, program); 962 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESSION); 963 964 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDY_QUALIFICATION); 965 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, program.getFurtherStudy(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.FURTHER_STUDY), _sourceResolver, true, isExportForAmetys()); 966 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COMPETENCE_DESC); 967 attrs = new AttributesImpl(); 968 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIMITED, "false"); 969 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COMPETENCE_VALIDITY, attrs); 970 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDY_QUALIFICATION); 971 972 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 973 } 974 975 /** 976 * SAX CDMfr degree 977 * @param contentHandler the content handler to sax into 978 * @param abstractProgram the program or subprogram 979 * @throws SAXException if an error occurred 980 */ 981 protected void _degree2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> abstractProgram) throws SAXException 982 { 983 if (abstractProgram instanceof Program program) 984 { 985 AttributesImpl attrs = new AttributesImpl(); 986 String degreeId = program.getDegree(); 987 if (StringUtils.isNotEmpty(degreeId)) 988 { 989 String cdmCode = _refTableHelper.getItemCDMfrValue(degreeId, false); 990 if (StringUtils.isNotEmpty(cdmCode)) 991 { 992 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_DEGREE, cdmCode); 993 } 994 else 995 { 996 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_DEGREE_NOT_LMD, _refTableHelper.getItemCode(degreeId)); 997 } 998 999 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DEGREE, attrs); 1000 } 1001 } 1002 } 1003 1004 /** 1005 * SAX CDMfr rome codes 1006 * @param contentHandler the content handler to sax into 1007 * @param program the program or subprogram 1008 * @throws SAXException if an error occurred 1009 */ 1010 protected void _romeCodes2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1011 { 1012 String[] romeCode = program.getRomeCode(); 1013 for (String id : romeCode) 1014 { 1015 AttributesImpl attrs = new AttributesImpl(); 1016 String code = _refTableHelper.getItemCode(id); 1017 attrs.addCDATAAttribute("romeCode", code); 1018 String label = _refTableHelper.getItemCDMfrValue(id, false); 1019 if (StringUtils.isNotBlank(label)) 1020 { 1021 attrs.addCDATAAttribute("romeLibel", label); 1022 } 1023 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ROME_DATA, attrs); 1024 } 1025 } 1026 1027 /** 1028 * SAX CDMfr level 1029 * @param contentHandler the content handler to sax into 1030 * @param program the program or subprogram 1031 * @throws SAXException if an error occurred 1032 */ 1033 protected void _level2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1034 { 1035 AttributesImpl attrs = new AttributesImpl(); 1036 String educationLevel = program.getEducationLevel(); 1037 _addNotNullAttribute(attrs, "codeSet", _refTableHelper.getItemCDMfrValue(educationLevel, true)); 1038 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL_CODE, attrs); 1039 1040 attrs = new AttributesImpl(); 1041 String educationLevelCode = _refTableHelper.getItemCode(educationLevel); 1042 if (educationLevelCode.startsWith("licence")) 1043 { 1044 _addNotNullAttribute(attrs, "level", "L"); 1045 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1046 } 1047 else if (educationLevelCode.startsWith("master")) 1048 { 1049 _addNotNullAttribute(attrs, "level", "M"); 1050 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1051 } 1052 else if (educationLevelCode.startsWith("doctorat")) 1053 { 1054 _addNotNullAttribute(attrs, "level", "Doc"); 1055 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1056 } 1057 } 1058 1059 /** 1060 * SAX CDMfr admission info 1061 * @param contentHandler the content handler to sax into 1062 * @param program the program or subprogram 1063 * @param programRichTextsContext the context for program's rich texts 1064 * @throws SAXException if an error occurred 1065 */ 1066 protected void _admissionInfo2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, DataContext programRichTextsContext) throws SAXException 1067 { 1068 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1069 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ADMISSION_DESCRIPTION, program.getAccessCondition(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.ACCESS_CONDITION), _sourceResolver, false, isExportForAmetys()); 1070 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_STUDENT_STATUS, ""); 1071 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ECTS_REQUIRED, ""); 1072 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDENT_PLACES, program.getEffectives(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.NUMBER_OF_STUDENTS), _sourceResolver, false, isExportForAmetys()); 1073 1074 LocalDate teachingStart = program.getTeachingStart(); 1075 if (teachingStart != null) 1076 { 1077 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_TEACHING_START, teachingStart); 1078 } 1079 1080 LocalDate registrationDeadline = program.getRegistrationDeadline(); 1081 if (registrationDeadline != null) 1082 { 1083 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_REGISTRATION_DEADLINE, registrationDeadline); 1084 } 1085 1086 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_DETAIL); 1087 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_PROCESS); 1088 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_MODALITIES, program.getInscription(), programRichTextsContext.cloneContext().withDataPath(AbstractProgram.INSCRIPTION), _sourceResolver, false, isExportForAmetys()); 1089 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_PROCESS); 1090 LocalDate registrationStart = program.getRegistrationStart(); 1091 if (registrationStart != null) 1092 { 1093 CDMHelper.date2CDM(contentHandler, CDMFRTagsConstants.TAG_REGISTRATION_START, registrationStart); 1094 } 1095 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REGISTRATION_DETAIL); 1096 1097 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1098 } 1099 1100 /** 1101 * SAX CDMfr events for a {@link AbstractProgram} codes 1102 * @param contentHandler the content handler to sax into 1103 * @param program the program or subprogram 1104 * @throws SAXException if an error occurred 1105 */ 1106 protected void _abstractProgram2CDMCode(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 1107 { 1108 AttributesImpl attrs = new AttributesImpl(); 1109 1110 // <programCode codeSet="userDefined">code</programCode> 1111 String code = program.getCode(); 1112 if (StringUtils.isNotBlank(code)) 1113 { 1114 attrs = new AttributesImpl(); 1115 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "userDefined"); 1116 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, code); 1117 } 1118 1119 // <programCode codeSet="codeCNIS-NSF">code</programCode> 1120 // <programCode libSet="codeCNIS-NSF">label</programCode> 1121 String nsfId = ContentDataHelper.getContentIdFromContentData(program, "nsfCode"); 1122 if (StringUtils.isNotBlank(nsfId)) 1123 { 1124 attrs = new AttributesImpl(); 1125 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "codeCNIS-NSF"); 1126 1127 String nsfCode = _refTableHelper.getItemCode(nsfId); 1128 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, nsfCode); 1129 1130 String codeLib = _refTableHelper.getItemCDMfrValue(nsfId, false); 1131 if (StringUtils.isNotEmpty(codeLib)) 1132 { 1133 attrs = new AttributesImpl(); 1134 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "codeCNIS-NSF"); 1135 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1136 } 1137 } 1138 1139 // <programCode codeSet="sectDGESIP">code</programCode> 1140 // <programCode libSet="sectDGESIP">label</programCode> 1141 for (String id : program.getDGESIPCode()) 1142 { 1143 attrs = new AttributesImpl(); 1144 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "sectDGESIP"); 1145 1146 String dgesipCode = _refTableHelper.getItemCode(id); 1147 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, dgesipCode); 1148 1149 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1150 if (StringUtils.isNotEmpty(codeLib)) 1151 { 1152 attrs = new AttributesImpl(); 1153 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "sectDGESIP"); 1154 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1155 } 1156 } 1157 1158 // <programCode codeSet="ERASMUS">code</programCode> 1159 // <programCode libSet="ERASMUS">label</programCode> 1160 for (String id : program.getErasmusCode()) 1161 { 1162 attrs = new AttributesImpl(); 1163 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "ERASMUS"); 1164 1165 String erasmusCode = _refTableHelper.getItemCode(id); 1166 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, erasmusCode); 1167 1168 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1169 if (StringUtils.isNotEmpty(codeLib)) 1170 { 1171 attrs = new AttributesImpl(); 1172 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "ERASMUS"); 1173 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1174 } 1175 } 1176 1177 // <programCode codeSet="cite97">code</programCode> 1178 // <programCode libSet="cite97">label</programCode> 1179 for (String id : program.getCite97Code()) 1180 { 1181 attrs = new AttributesImpl(); 1182 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "cite97"); 1183 String cite97Code = _refTableHelper.getItemCode(id); 1184 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, cite97Code); 1185 1186 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1187 if (StringUtils.isNotEmpty(codeLib)) 1188 { 1189 attrs = new AttributesImpl(); 1190 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "cite97"); 1191 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1192 } 1193 } 1194 1195 // <programCode codeSet="FAP">code</programCode> 1196 // <programCode libSet="FAP">label</programCode> 1197 for (String id : program.getFapCode()) 1198 { 1199 attrs = new AttributesImpl(); 1200 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "FAP"); 1201 String fapCode = _refTableHelper.getItemCode(id); 1202 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, fapCode); 1203 1204 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1205 if (StringUtils.isNotEmpty(codeLib)) 1206 { 1207 attrs = new AttributesImpl(); 1208 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "FAP"); 1209 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1210 } 1211 } 1212 1213 // <programCode codeSet="codeSectDiscipSISE">code</programCode> 1214 // <programCode libSet="codeSectDiscipSISE">label</programCode> 1215 for (String id : program.getSiseCode()) 1216 { 1217 attrs = new AttributesImpl(); 1218 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "sectDiscipSISE"); 1219 1220 String siseCode = _refTableHelper.getItemCode(id); 1221 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, siseCode); 1222 1223 String codeLib = _refTableHelper.getItemCDMfrValue(id, false); 1224 if (StringUtils.isNotEmpty(codeLib)) 1225 { 1226 attrs = new AttributesImpl(); 1227 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LIB_SET, "sectDiscipSISE"); 1228 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, codeLib); 1229 } 1230 } 1231 } 1232 1233 /** 1234 * SAX CDMfr events for a {@link AbstractProgram} contacts 1235 * @param contentHandler the content handler to sax into 1236 * @param program the program or subprogram 1237 * @param persons the contacts 1238 * @param orgUnits the orgunits 1239 * @throws SAXException if an error occurred 1240 */ 1241 protected void _abstractProgram2CDMContacts(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, Set<String> persons, Set<String> orgUnits) throws SAXException 1242 { 1243 AttributesImpl attrs = new AttributesImpl(); 1244 1245 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1246 1247 Map<String, List<String>> contactsByRole = program.getContactsByRole(); 1248 1249 for (Entry<String, List<String>> entry : contactsByRole.entrySet()) 1250 { 1251 String role = entry.getKey(); 1252 List<String> contactIds = entry.getValue(); 1253 1254 String roleCode = null; 1255 if (StringUtils.isNotEmpty(role)) 1256 { 1257 roleCode = _refTableHelper.getItemCode(role); 1258 } 1259 1260 for (String personID : contactIds) 1261 { 1262 try 1263 { 1264 Person person = _resolver.resolveById(personID); 1265 persons.add(person.getId()); 1266 attrs = new AttributesImpl(); 1267 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 1268 if (roleCode != null) 1269 { 1270 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, roleCode); 1271 } 1272 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 1273 } 1274 catch (UnknownAmetysObjectException e) 1275 { 1276 // Contact does exist anymore, ignore it 1277 } 1278 } 1279 } 1280 1281 for (String orgUnitId : program.getOrgUnits()) 1282 { 1283 if (!"".equals(orgUnitId)) 1284 { 1285 try 1286 { 1287 OrgUnit orgUnit = _resolver.resolveById(orgUnitId); 1288 orgUnits.add(orgUnit.getId()); 1289 attrs = new AttributesImpl(); 1290 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 1291 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 1292 } 1293 catch (UnknownAmetysObjectException e) 1294 { 1295 // OrgUnit does exist anymore, ignore it 1296 } 1297 } 1298 } 1299 1300 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1301 } 1302 1303 /** 1304 * SAX CDMfr events for a {@link ProgramPart} strcuture 1305 * @param contentHandler the content handler to sax into 1306 * @param programPart the program part 1307 * @param persons the contacts 1308 * @param orgUnits the orgunits 1309 * @param courses the courses 1310 * @throws SAXException if an error occurred 1311 */ 1312 protected void _programPart2CDMSubPrograms(ContentHandler contentHandler, TraversableProgramPart programPart, Set<String> persons, Set<String> orgUnits, Set<String> courses) throws SAXException 1313 { 1314 ContentValue[] children = programPart.getValueOrDefault(TraversableProgramPart.CHILD_PROGRAM_PARTS, new ContentValue[0]); 1315 for (ContentValue child : children) 1316 { 1317 Optional<ModifiableContent> content = child.getContentIfExists(); 1318 if (content.isPresent()) 1319 { 1320 if (content.get() instanceof AbstractProgram<?> program) 1321 { 1322 abstractProgram2CDM(contentHandler, program, persons, orgUnits, courses); 1323 } 1324 else if (content.get() instanceof Container container) 1325 { 1326 container2CDM(contentHandler, container, persons, orgUnits, courses); 1327 } 1328 } 1329 } 1330 } 1331 1332 1333 //***********************************************************************// 1334 // CONTAINER // 1335 //***********************************************************************// 1336 1337 /** 1338 * Send the CDM-fr representation of their ProgramPart to the given Contenthandler.<br> 1339 * Also collects referenced orgUnits, persons and courses, so that they could be sent afterwards. 1340 * @param contentHandler the receiving contentHandler. 1341 * @param container The container 1342 * @param persons collected {@link Person} ids. 1343 * @param orgUnits collected {@link OrgUnit} ids. 1344 * @param courses collected {@link Course} ids. 1345 * @throws SAXException if an error occurs during CDM processing. 1346 */ 1347 public void container2CDM(ContentHandler contentHandler, Container container, Set<String> persons, Set<String> orgUnits, Set<String> courses) throws SAXException 1348 { 1349 if (container.isPublishable() && switchToLiveVersionIfNeeded(container)) 1350 { 1351 Request request = ContextHelper.getRequest(_context); 1352 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 1353 1354 try 1355 { 1356 request.setAttribute(Content.class.getName(), container); 1357 1358 AttributesImpl attrs = new AttributesImpl(); 1359 1360 // <program id="FR_RNE_{rootOrgUnitId}_PR_{code}"> 1361 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, container.getCDMId()); 1362 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_SUB_PROGRAM, attrs); 1363 1364 // <programID>code</programID> 1365 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PROGRAM_ID, container.getCDMId()); 1366 1367 // <programName><text>name</text></programName> 1368 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 1369 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_TEXT, container.getTitle()); 1370 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_NAME); 1371 1372 // <programCode codeSet="userDefined">code</programCode> 1373 String code = container.getCode(); 1374 if (StringUtils.isNotBlank(code)) 1375 { 1376 attrs = new AttributesImpl(); 1377 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "userDefined"); 1378 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_CODE, attrs, code); 1379 } 1380 1381 // <programDescription>...</programDescription> 1382 attrs = new AttributesImpl(); 1383 String nature = container.getNature(); 1384 if (StringUtils.isNotEmpty(nature)) 1385 { 1386 nature = _refTableHelper.getItemCDMfrValue(nature, true); 1387 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_NATURE, nature); 1388 } 1389 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_DESCRIPTION, attrs); 1390 1391 // <qualification>...</qualification> 1392 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 1393 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, container.getEcts()); 1394 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 1395 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, null, null, null, true, isExportForAmetys()); 1396 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 1397 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_QUALIFICATION); 1398 1399 // <programStructure>...</programStructure> 1400 ContentValue[] children = container.getValueOrDefault(TraversableProgramPart.CHILD_PROGRAM_PARTS, new ContentValue[0]); 1401 for (ContentValue child : children) 1402 { 1403 Optional<ModifiableContent> content = child.getContentIfExists(); 1404 if (content.isPresent() && content.get() instanceof CourseList courseList) 1405 { 1406 courselist2CDM(contentHandler, courseList, courses); 1407 } 1408 } 1409 1410 // <infoBlock>...</infoBlock> 1411 attrs = new AttributesImpl(); 1412 attrs.addCDATAAttribute("userDefined", "container"); 1413 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs); 1414 1415 // <infoBlock userDefined="ametys-extension>...</infoBlock> 1416 saxExtensions(contentHandler, container, persons, orgUnits); 1417 1418 // <subProgram>...</subProgram> 1419 _programPart2CDMSubPrograms(contentHandler, container, persons, orgUnits, courses); 1420 1421 // </program> 1422 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_SUB_PROGRAM); 1423 } 1424 finally 1425 { 1426 request.setAttribute(Content.class.getName(), currentContent); 1427 } 1428 } 1429 } 1430 1431 /** 1432 * SAX the course list structure 1433 * @param contentHandler The content handler to SAX into 1434 * @param cl The course list 1435 * @param courses References of saxed courses 1436 * @throws SAXException if an error occurs 1437 */ 1438 public void courselist2CDM (ContentHandler contentHandler, CourseList cl, Set<String> courses) throws SAXException 1439 { 1440 if (cl.isPublishable() && switchToLiveVersionIfNeeded(cl)) 1441 { 1442 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 1443 1444 _courselist2CDM (contentHandler, cl); 1445 1446 for (Course course : cl.getCourses()) 1447 { 1448 if (course.isPublishable()) 1449 { 1450 courses.add(course.getId()); 1451 AttributesImpl attrs = new AttributesImpl(); 1452 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, course.getCDMId()); 1453 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_COURSE, attrs); 1454 } 1455 } 1456 1457 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROGRAM_STRUCTURE); 1458 } 1459 } 1460 1461 /** 1462 * Convert course list info to CDM (without child courses) 1463 * @param contentHandler The content handler to sax into 1464 * @param cl The course list 1465 * @throws SAXException if an error occurs 1466 */ 1467 protected void _courselist2CDM (ContentHandler contentHandler, CourseList cl) throws SAXException 1468 { 1469 if (switchToLiveVersionIfNeeded(cl)) 1470 { 1471 AttributesImpl attrs = new AttributesImpl(); 1472 attrs.addCDATAAttribute("userDefined", "listCode"); 1473 String code = cl.getCode(); 1474 if (StringUtils.isEmpty(code)) 1475 { 1476 code = org.ametys.core.util.StringUtils.generateKey().toUpperCase(); 1477 } 1478 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, code); 1479 1480 attrs = new AttributesImpl(); 1481 attrs.addCDATAAttribute("userDefined", "listName"); 1482 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, cl.getTitle()); 1483 1484 ChoiceType type = cl.getType(); 1485 if (type != null) 1486 { 1487 attrs = new AttributesImpl(); 1488 attrs.addCDATAAttribute("userDefined", "listChoiceType"); 1489 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, cl.getType().toString().toLowerCase()); 1490 } 1491 1492 if (type != null && type.equals(ChoiceType.CHOICE)) 1493 { 1494 attrs = new AttributesImpl(); 1495 attrs.addCDATAAttribute("userDefined", "listMinNumberOfCourses"); 1496 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, String.valueOf(cl.getMinNumberOfCourses())); 1497 1498 attrs = new AttributesImpl(); 1499 attrs.addCDATAAttribute("userDefined", "listMaxNumberOfCourses"); 1500 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, attrs, String.valueOf(cl.getMaxNumberOfCourses())); 1501 } 1502 } 1503 } 1504 1505 //***********************************************************************// 1506 // COURSE // 1507 //***********************************************************************// 1508 1509 /** 1510 * Export this entity in CDM-fr format. 1511 * @param contentHandler the target handler 1512 * @param course The course 1513 * @throws SAXException if an error occurs during export. 1514 */ 1515 public void course2CDM(ContentHandler contentHandler, Course course) throws SAXException 1516 { 1517 boolean rootOrgUnitSaxed = false; 1518 1519 Set<String> orgUnits = new HashSet<>(); 1520 Set<String> persons = new HashSet<>(); 1521 1522 Set<String> coursesAlreadySax = new HashSet<>(); 1523 Set<String> coursesToSax = new HashSet<>(); 1524 coursesToSax.add(course.getId()); 1525 1526 while (!coursesToSax.isEmpty()) 1527 { 1528 Set<String> courses = new HashSet<>(); 1529 for (String courseId : coursesToSax) 1530 { 1531 coursesAlreadySax.add(courseId); 1532 Course courseToSax = _resolver.resolveById(courseId); 1533 courses.addAll(course2CDM(contentHandler, courseToSax, orgUnits, persons)); 1534 } 1535 coursesToSax.clear(); 1536 coursesToSax.addAll(courses); 1537 coursesToSax.removeAll(coursesAlreadySax); 1538 } 1539 1540 for (String orgUnitId : orgUnits) 1541 { 1542 OrgUnit orgUnit = _resolver.resolveById(orgUnitId); 1543 if (orgUnitId.equals(_rootOrgUnitProvider.getRootId())) 1544 { 1545 rootOrgUnitSaxed = true; 1546 } 1547 _orgunit2CDM(contentHandler, orgUnit, persons); 1548 } 1549 1550 if (!rootOrgUnitSaxed) 1551 { 1552 OrgUnit orgUnit = _rootOrgUnitProvider.getRoot(); 1553 _orgunit2CDM(contentHandler, orgUnit, persons); 1554 } 1555 1556 for (String personId : persons) 1557 { 1558 Person person = _resolver.resolveById(personId); 1559 person2CDM(contentHandler, person); 1560 } 1561 1562 // Set content in request 1563 ContextHelper.getRequest(_context).setAttribute(Content.class.getName(), course); 1564 } 1565 1566 /** 1567 * Export this entity in CDM-fr format. 1568 * @param contentHandler the content handler to SAX into 1569 * @param course the course 1570 * @param orgUnits the org units 1571 * @param persons the persons 1572 * @return the saxed coursed 1573 * @throws SAXException if failed to generate CDM 1574 */ 1575 public Set<String> course2CDM(ContentHandler contentHandler, Course course, Set<String> orgUnits, Set<String> persons) throws SAXException 1576 { 1577 DataContext courseRichTextsContext = RepositoryDataContext.newInstance() 1578 .withObject(course); 1579 1580 if (!course.isPublishable() || !switchToLiveVersionIfNeeded(course)) 1581 { 1582 return new HashSet<>(); 1583 } 1584 1585 Request request = ContextHelper.getRequest(_context); 1586 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 1587 1588 try 1589 { 1590 request.setAttribute(Content.class.getName(), course); 1591 1592 AttributesImpl attrs = new AttributesImpl(); 1593 1594 // <course id="FR_RNE_{rootOrgUnitId}_CO_{code}" language="..."> 1595 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, course.getCDMId()); 1596 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_LANGUAGE, course.getLanguage()); 1597 String erasmusCode = _refTableHelper.getItemCode(course.getErasmusCode()); 1598 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_IDENT, erasmusCode); 1599 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE, attrs); 1600 1601 // <courseID>code</courseID> 1602 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_ID, course.getCDMId()); 1603 1604 // <courseName><text>name</text></courseName> 1605 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_NAME); 1606 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, course.getTitle()); 1607 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_NAME); 1608 1609 // <courseCode codeSet="UE">code</couseCode> 1610 String courseType = _refTableHelper.getItemCode(course.getCourseType()); 1611 attrs = new AttributesImpl(); 1612 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, courseType); 1613 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_CODE, attrs, course.getCdmCode()); 1614 1615 // <webLink> 1616 // <href>href</href> 1617 // <linkName>linkName</linkName> 1618 // </webLink> 1619 String webLinkURL = course.getWebLinkUrl(); 1620 if (StringUtils.isNotEmpty(webLinkURL)) 1621 { 1622 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 1623 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, webLinkURL); 1624 String webLinkLabel = course.getWebLinkLabel(); 1625 if (StringUtils.isNotEmpty(webLinkLabel)) 1626 { 1627 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LINK_NAME, course.getWebLinkLabel()); 1628 } 1629 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 1630 } 1631 1632 // <level>level</level> 1633 attrs = new AttributesImpl(); 1634 String level = _refTableHelper.getItemCDMfrValue(course.getLevel(), true); 1635 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_LEVEL, level); 1636 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LEVEL, attrs); 1637 1638 // <courseDescription>...</courseDescription> 1639 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_DESCRIPTION); 1640 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGITAL_USE); 1641 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PERCENTAGE, "0"); 1642 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LCMS); 1643 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_EXISTS, "false"); 1644 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_RESOURCE_MGT); 1645 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PERC_OF_USE, "0"); 1646 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LCMS); 1647 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROD_PEDA); 1648 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGIT_PROD_PERC, "0"); 1649 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGIT_PROD_UNT_PERC, "0"); 1650 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROD_PEDA); 1651 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_DIGITAL_USE); 1652 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_INFO_BLOCK, course.getDescription(), courseRichTextsContext.cloneContext().withDataPath(Course.DESCRIPTION), _sourceResolver, true, isExportForAmetys()); 1653 1654 Set<String> courses = _courseLists2CDM(contentHandler, course); 1655 1656 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE_DESCRIPTION); 1657 1658 // <teachingTerm term="" timeOfDay="" start=""/> 1659 attrs = new AttributesImpl(); 1660 LocalDate startDate = course.getStartDate(); 1661 if (startDate != null) 1662 { 1663 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_START, startDate.format(CDMHelper.CDM_DATE_FORMATTER)); 1664 } 1665 1666 String teachingTerm = _refTableHelper.getItemCDMfrValue(course.getTeachingTerm(), true); 1667 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TERM, teachingTerm); 1668 String timeSlot = _refTableHelper.getItemCDMfrValue(course.getTimeSlot(), true); 1669 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TIME_OF_DAY, timeSlot); 1670 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_TERM, attrs); 1671 1672 // <credits ECTScredits="" totalWorkLoad=""> 1673 // <infoBlock>...</infoBlock> 1674 // <globalVolume teachingType="CM/TP/TD">...</globalVolume> 1675 // </credits> 1676 _credits2CDM(contentHandler, course); 1677 1678 // <learningObjectives>...</learningObjectives> 1679 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES); 1680 CDMHelper.richText2CDM(contentHandler, course.getObjectives(), courseRichTextsContext.cloneContext().withDataPath(Course.OBJECTIVES), _sourceResolver, isExportForAmetys()); 1681 // <ametys-cdm:skills>...</ametys-cdm:skills> 1682 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skills", course.getSkills(), courseRichTextsContext.cloneContext().withDataPath(Course.SKILLS), _sourceResolver, false, isExportForAmetys()); 1683 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_LEARNING_OBJECTIVES); 1684 1685 // <admissionInfo> 1686 // <studentPlaces places=""/> 1687 // <teachingStart date=""/> 1688 // </admissionInfo> 1689 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1690 1691 String maxNumberOfStudents = course.getMaxNumberOfStudents(); 1692 if (StringUtils.isNotEmpty(maxNumberOfStudents)) 1693 { 1694 attrs = new AttributesImpl(); 1695 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_PLACES, maxNumberOfStudents); 1696 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_STUDENT_PLACES, attrs); 1697 } 1698 1699 if (startDate != null) 1700 { 1701 attrs = new AttributesImpl(); 1702 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_DATE, new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.asDate(startDate))); 1703 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_START, attrs); 1704 } 1705 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 1706 1707 // <formalPrerequisites>...</formalPrerequisites> 1708 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORMAL_PREREQUISITES, course.getNeededPrerequisite(), courseRichTextsContext.cloneContext().withDataPath(Course.NEEDED_PREREQUISITE), _sourceResolver, true, isExportForAmetys()); 1709 1710 // <teachingPlace> 1711 // <cdmfr:refOrgUnit /> 1712 // <adr> 1713 // <pcode></pcode> 1714 // </adr> 1715 // </teachingPlace> 1716 _teachingLocation2CDM(contentHandler, course); 1717 1718 // <formOfTeaching method="" org=""/> 1719 String formOfTeachingMethod = _refTableHelper.getItemCDMfrValue(course.getFormOfTeachingMethod(), false); 1720 for (String formOfTeachingOrg: course.getFormOfTeachingOrgs()) 1721 { 1722 attrs = new AttributesImpl(); 1723 String formOfTeachingOrgValue = _refTableHelper.getItemCDMfrValue(formOfTeachingOrg, false); 1724 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, formOfTeachingMethod); 1725 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ORG, formOfTeachingOrgValue); 1726 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_TEACHING, attrs); 1727 } 1728 1729 // <formOfAssessment>...</formOfAssessment> 1730 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_FORM_OF_ASSESSMENT, course.getFormOfAssessment(), courseRichTextsContext.cloneContext().withDataPath(Course.FORM_OF_ASSESSMENT), _sourceResolver, false, isExportForAmetys()); 1731 1732 // <instructionLanguage teachingLang=""/> 1733 String[] teachingLanguages = course.getTeachingLanguage(); 1734 for (String teachingLanguage : teachingLanguages) 1735 { 1736 String teachingLanguageValue = _refTableHelper.getItemCDMfrValue(teachingLanguage, true); 1737 attrs = new AttributesImpl(); 1738 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_LANG, teachingLanguageValue); 1739 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_INSTRUCTION_LANGUAGE, attrs); 1740 } 1741 1742 // <syllabus> 1743 // ... 1744 // <webLink role="learningObjectMetadata"> 1745 // <href>...</href> 1746 // <linkName>...</linkName> 1747 // </webLink> 1748 // </syllabus> 1749 _syllabus2CDM(contentHandler, course, courseRichTextsContext); 1750 1751 // <teachingActivity method=""/> 1752 attrs = new AttributesImpl(); 1753 String teachingActivity = _refTableHelper.getItemCDMfrValue(course.getTeachingActivity(), true); 1754 _addNotNullAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_METHOD, teachingActivity); 1755 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_ACTIVITY, attrs); 1756 1757 // <contacts> 1758 // <refPerson idRef=ID/> 1759 // </contacts> 1760 _course2CDMContacts(contentHandler, course, persons, orgUnits); 1761 1762 // <infoBlock>...</infoBlock> 1763 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, course.getAdditionalInformations(), courseRichTextsContext.cloneContext().withDataPath(Course.ADDITIONAL_INFORMATIONS), _sourceResolver, false, isExportForAmetys()); 1764 1765 // <infoBlock userDefined="ametys-extension>...</infoBlock> 1766 saxExtensions(contentHandler, course, persons, orgUnits); 1767 1768 // <searchword>keyword</searchword> 1769 for (String keyword : course.getKeywords()) 1770 { 1771 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_SEARCH_WORD, keyword); 1772 } 1773 1774 // </course> 1775 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_COURSE); 1776 1777 return courses; 1778 } 1779 finally 1780 { 1781 request.setAttribute(Content.class.getName(), currentContent); 1782 } 1783 } 1784 1785 /** 1786 * Sax the courses lists for a course. 1787 * @param contentHandler the content handler to SAX into 1788 * @param course The courselist container. 1789 * @return The list of courses into the course list. 1790 * @throws SAXException if failed to generate CDM 1791 */ 1792 protected Set<String> _courseLists2CDM(ContentHandler contentHandler, Course course) throws SAXException 1793 { 1794 Set<String> courses = new HashSet<>(); 1795 1796 for (CourseList coursesList : course.getCourseLists()) 1797 { 1798 if (coursesList.isPublishable()) 1799 { 1800 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COURSE_CONTENTS); 1801 1802 // SAX infos on course list. This DO NOT respect the CDM-fr schema 1803 _courselist2CDM(contentHandler, coursesList); 1804 1805 for (Course childCourse : coursesList.getCourses()) 1806 { 1807 if (childCourse.isPublishable()) 1808 { 1809 courses.add(childCourse.getId()); 1810 AttributesImpl attrs = new AttributesImpl(); 1811 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, childCourse.getCDMId()); 1812 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_COURSE, attrs); 1813 } 1814 } 1815 1816 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_COURSE_CONTENTS); 1817 } 1818 } 1819 1820 return courses; 1821 } 1822 1823 /** 1824 * Sax the course credits. 1825 * @param contentHandler the content handler to SAX into 1826 * @param course The course to sax 1827 * @throws SAXException if failed to generate CDM 1828 */ 1829 protected void _credits2CDM(ContentHandler contentHandler, Course course) throws SAXException 1830 { 1831 AttributesImpl attrs = new AttributesImpl(); 1832 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_TOTAL_WORK_LOAD, course.getNumberOfHours()); 1833 _addPositiveAttribute(attrs, CDMFRTagsConstants.ATTRIBUTE_ECTS_CREDITS, course.getEcts()); 1834 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS, attrs); 1835 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, null, null, _sourceResolver, true, isExportForAmetys()); 1836 1837 Map<String, Double> hoursByNature = new HashMap<>(); 1838 List<CoursePart> courseParts = course.getCourseParts(); 1839 for (CoursePart coursePart : courseParts) 1840 { 1841 String nature = coursePart.getNature(); 1842 Double hours = MapUtils.getDouble(hoursByNature, nature, 0d) + coursePart.getNumberOfHours(); 1843 if (hours > 0) 1844 { 1845 hoursByNature.put(nature, hours); 1846 } 1847 } 1848 1849 for (String nature : hoursByNature.keySet()) 1850 { 1851 attrs = new AttributesImpl(); 1852 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_TEACHING_TYPE, _refTableHelper.getItemCDMfrValue(nature, true)); 1853 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_GLOBAL_VOLUME, attrs, String.valueOf(hoursByNature.get(nature))); 1854 } 1855 1856 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_CREDITS); 1857 } 1858 1859 /** 1860 * SAX the syllabus elements of the course. 1861 * @param contentHandler The content handler 1862 * @param course The course to SAX 1863 * @param courseRichTextsContext the context for course's rich texts 1864 * @throws SAXException if an error occurs 1865 */ 1866 protected void _syllabus2CDM(ContentHandler contentHandler, Course course, DataContext courseRichTextsContext) throws SAXException 1867 { 1868 RichText syllabus = course.getSyllabus(); 1869 RichText bibliography = course.getBibliography(); 1870 Set<LOMSheet> lomSheets = course.getLOMSheets(); 1871 if (syllabus != null || bibliography != null || !lomSheets.isEmpty()) 1872 { 1873 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_SYLLABUS); 1874 1875 // Syllabus 1876 if (syllabus != null) 1877 { 1878 CDMHelper.richText2CDM(contentHandler, syllabus, courseRichTextsContext.cloneContext().withDataPath(Course.SYLLABUS), _sourceResolver, isExportForAmetys()); 1879 } 1880 1881 // Bibliography 1882 if (bibliography != null) 1883 { 1884 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CDMFRTagsConstants.TAG_BIBLIOGRAPHY, bibliography, courseRichTextsContext.cloneContext().withDataPath(Course.BIBLIOGRAPHY), _sourceResolver, false, isExportForAmetys()); 1885 } 1886 1887 // LOM sheets 1888 for (LOMSheet lomSheet : lomSheets) 1889 { 1890 lomSheet.toCDM(contentHandler); 1891 } 1892 1893 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_SYLLABUS); 1894 } 1895 } 1896 1897 /** 1898 * Sax the course teaching locations. 1899 * @param contentHandler the content handler to SAX into 1900 * @param course The course to sax 1901 * @throws SAXException if failed to generate CDM 1902 */ 1903 protected void _teachingLocation2CDM(ContentHandler contentHandler, Course course) throws SAXException 1904 { 1905 for (String id : course.getTeachingLocation()) 1906 { 1907 if (StringUtils.isNotEmpty(id)) 1908 { 1909 String postalCode = _refTableHelper.getItemCode(id); 1910 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 1911 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 1912 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 1913 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, postalCode); 1914 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 1915 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TEACHING_PLACE); 1916 } 1917 } 1918 } 1919 1920 /** 1921 * SAX CDMfr events for a {@link Course} contacts 1922 * @param contentHandler the content handler to sax into 1923 * @param course the course 1924 * @param persons the contacts 1925 * @param orgUnits the orgunits 1926 * @throws SAXException if an error occurred 1927 */ 1928 protected void _course2CDMContacts(ContentHandler contentHandler, Course course, Set<String> persons, Set<String> orgUnits) throws SAXException 1929 { 1930 AttributesImpl attrs = new AttributesImpl(); 1931 1932 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1933 1934 Map<String, List<String>> contactsByRole = course.getContactsByRole(); 1935 1936 for (Entry<String, List<String>> entry : contactsByRole.entrySet()) 1937 { 1938 String role = entry.getKey(); 1939 List<String> contactIds = entry.getValue(); 1940 1941 String roleCode = null; 1942 if (StringUtils.isNotEmpty(role)) 1943 { 1944 roleCode = _refTableHelper.getItemCode(role); 1945 } 1946 1947 for (String personID : contactIds) 1948 { 1949 try 1950 { 1951 Person person = _resolver.resolveById(personID); 1952 persons.add(person.getId()); 1953 attrs = new AttributesImpl(); 1954 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 1955 if (roleCode != null) 1956 { 1957 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, roleCode); 1958 } 1959 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 1960 } 1961 catch (UnknownAmetysObjectException e) 1962 { 1963 // Contact does exist anymore, ignore it 1964 } 1965 } 1966 } 1967 1968 for (String orgUnitID : course.getOrgUnits()) 1969 { 1970 if (!"".equals(orgUnitID)) 1971 { 1972 try 1973 { 1974 OrgUnit orgUnit = _resolver.resolveById(orgUnitID); 1975 orgUnits.add(orgUnit.getId()); 1976 attrs = new AttributesImpl(); 1977 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 1978 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 1979 } 1980 catch (UnknownAmetysObjectException e) 1981 { 1982 // OrgUnit does exist anymore, ignore it 1983 } 1984 } 1985 } 1986 1987 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 1988 } 1989 1990 1991 //***********************************************************************// 1992 // ORGUNIT // 1993 //***********************************************************************// 1994 1995 /** 1996 * Export this entity in CDM-fr format. 1997 * @param contentHandler the target handler 1998 * @param orgunit the orgunit 1999 * @throws SAXException if an error occurs during export. 2000 */ 2001 public void orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit) throws SAXException 2002 { 2003 Set<String> persons = new HashSet<>(); 2004 2005 _orgunit2CDM(contentHandler, orgunit, persons, true); 2006 2007 for (String personId : persons) 2008 { 2009 Person person = _resolver.resolveById(personId); 2010 person2CDM(contentHandler, person); 2011 } 2012 2013 if (!orgunit.getId().equals(_rootOrgUnitProvider.getRootId())) 2014 { 2015 OrgUnit rootOrgunit = _resolver.resolveById(_rootOrgUnitProvider.getRootId()); 2016 _orgunit2CDM(contentHandler, rootOrgunit, persons); 2017 } 2018 2019 // Set content in request 2020 ContextHelper.getRequest(_context).setAttribute(Content.class.getName(), orgunit); 2021 } 2022 2023 /** 2024 * SAX CDMfr event for a {@link OrgUnit} 2025 * @param contentHandler the content handler to sax into 2026 * @param orgunit the orgunit 2027 * @param persons the contacts of orgunit 2028 * @throws SAXException if an error occurred 2029 */ 2030 protected void _orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit, Set<String> persons) throws SAXException 2031 { 2032 _orgunit2CDM(contentHandler, orgunit, persons, false); 2033 } 2034 2035 /** 2036 * SAX CDMfr event for a {@link OrgUnit} 2037 * @param contentHandler the content handler to sax into 2038 * @param orgunit the orgunit 2039 * @param persons the contacts of orgunit 2040 * @param showChildren true to sax child orgunits 2041 * @throws SAXException if an error occurred 2042 */ 2043 protected void _orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit, Set<String> persons, boolean showChildren) throws SAXException 2044 { 2045 Request request = ContextHelper.getRequest(_context); 2046 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 2047 DataContext orgunitRichTextsContext = RepositoryDataContext.newInstance() 2048 .withObject(orgunit); 2049 2050 try 2051 { 2052 _odfHelper.switchToLiveVersionIfNeeded(orgunit); 2053 2054 request.setAttribute(Content.class.getName(), orgunit); 2055 2056 AttributesImpl attrs = new AttributesImpl(); 2057 2058 // <orgunit id="FR_RNE_{rootOrgUnitId}_OR_{login}"> 2059 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, orgunit.getCDMId()); 2060 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT, attrs); 2061 2062 // <orgUnitID>RNE</orgUnitID> 2063 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_ID, orgunit.getCDMId()); 2064 2065 // <orgUnitName><text>name</text></orgUnitID> 2066 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_NAME); 2067 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, orgunit.getTitle()); 2068 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_NAME); 2069 2070 // <orgUnitAcronym>acronyme</orgUnitAcronym> 2071 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_ACRONYM, orgunit.getAcronym()); 2072 2073 // <orgUnitCode codeSet="codeUAI">code</orgUnitCode> 2074 attrs = new AttributesImpl(); 2075 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_CODE_SET, "codeUAI"); 2076 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_CODE, attrs, orgunit.getUAICode()); 2077 2078 // <orgUnitKind orgUnitKindCodeValueSet=""/> 2079 attrs = new AttributesImpl(); 2080 String orgunitType = _refTableHelper.getItemCDMfrValue(orgunit.getType(), false); 2081 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ORG_UNIT_KIND_CODE_VALUESET, orgunitType); 2082 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_KIND); 2083 2084 // <webLink> 2085 // <href>href</href> 2086 // <linkName>linkName</linkName> 2087 // </webLink> 2088 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 2089 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, orgunit.getWebLinkURL()); 2090 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_LINK_NAME, orgunit.getWebLinkLabel()); 2091 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_WEB_LINK); 2092 2093 // <orgUnitDescription>...</orgUnitDescription> 2094 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT_DESCRIPTION, orgunit.getDescription(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.DESCRIPTION), _sourceResolver, false, isExportForAmetys()); 2095 2096 // <admissionInfo> 2097 // <admissionDescription>...</admissionDescription> 2098 // </admissionInfo> 2099 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 2100 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_ADMISSION_DESCRIPTION, orgunit.getAdmissionInfo(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.ADMISSION_INFO), _sourceResolver); 2101 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADMISSION_INFO); 2102 2103 // <regulations>...</regulations> 2104 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_REGULATIONS, orgunit.getRegulations(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.REGULATIONS), _sourceResolver, false, isExportForAmetys()); 2105 2106 // <expenses>...</expenses> 2107 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_EXPENSES, orgunit.getExpenses(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.EXPENSES), _sourceResolver, false, isExportForAmetys()); 2108 2109 // <studentFacilities>...</studentFacilities> 2110 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_STUDENT_FACILITIES, orgunit.getStudentFacilities(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.STUDENT_FACILITIES), _sourceResolver, false, isExportForAmetys()); 2111 2112 // <universalAjustment>...</universalAjustment> 2113 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_UNIVERSAL_ADJUSTMENT, orgunit.getUniversalAdjustment(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.UNIVERSAL_ADJUSTMENT), _sourceResolver, false, isExportForAmetys()); 2114 2115 // <contacts> 2116 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 2117 2118 for (String contactID : orgunit.getContacts()) 2119 { 2120 if (StringUtils.isNotEmpty(contactID)) 2121 { 2122 try 2123 { 2124 Person person = _resolver.resolveById(contactID); 2125 persons.add(person.getId()); 2126 attrs = new AttributesImpl(); 2127 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, person.getCDMId()); 2128 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ROLE, "contact"); 2129 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_PERSON, attrs); 2130 } 2131 catch (UnknownAmetysObjectException e) 2132 { 2133 // Contact does exist anymore, ignore it 2134 } 2135 } 2136 } 2137 2138 // </contacts> 2139 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACTS); 2140 2141 // <infoBlock>...</infoBlock> 2142 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, orgunit.getAdditionnalInfos(), orgunitRichTextsContext.cloneContext().withDataPath(OrgUnit.ADDITIONNAL_INFOS), _sourceResolver, false, isExportForAmetys()); 2143 2144 Set<OrgUnit> orgUnits = new HashSet<>(); 2145 if (showChildren) 2146 { 2147 // <refOrgUnit IDref=""/> 2148 for (String orgUnitID : orgunit.getSubOrgUnits()) 2149 { 2150 try 2151 { 2152 OrgUnit orgUnit = _resolver.resolveById(orgUnitID); 2153 orgUnits.add(orgUnit); 2154 attrs = new AttributesImpl(); 2155 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID_REF, orgUnit.getCDMId()); 2156 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_REF_ORG_UNIT, attrs); 2157 } 2158 catch (UnknownAmetysObjectException e) 2159 { 2160 // OrgUnit does exist anymore, ignore it 2161 } 2162 } 2163 } 2164 2165 // <infoBlock userDefined="ametys-extension>...</infoBlock> 2166 saxExtensions(contentHandler, orgunit, null, null); 2167 2168 // </orgunit> 2169 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ORG_UNIT); 2170 2171 for (OrgUnit childOrgunit : orgUnits) 2172 { 2173 _orgunit2CDM(contentHandler, childOrgunit, persons); 2174 } 2175 } 2176 catch (NoLiveVersionException e) 2177 { 2178 getLogger().error("Orgunit {} ({}) is not validated so it cannot be exported to CDM-fr.", orgunit.getTitle(), orgunit.getId()); 2179 } 2180 finally 2181 { 2182 request.setAttribute(Content.class.getName(), currentContent); 2183 } 2184 } 2185 2186 2187 //***********************************************************************// 2188 // PERSON // 2189 //***********************************************************************// 2190 2191 /** 2192 * Export this entity in CDM-fr format. 2193 * @param contentHandler the target handler 2194 * @param person the person 2195 * @throws SAXException if an error occurs during export. 2196 */ 2197 public void person2CDM(ContentHandler contentHandler, Person person) throws SAXException 2198 { 2199 Request request = ContextHelper.getRequest(_context); 2200 Content currentContent = (Content) request.getAttribute(Content.class.getName()); 2201 2202 try 2203 { 2204 _odfHelper.switchToLiveVersionIfNeeded(person); 2205 2206 request.setAttribute(Content.class.getName(), person); 2207 2208 AttributesImpl attrs = new AttributesImpl(); 2209 2210 // <person id="FRUAI{rootOrgUnitId}PE{login}"> 2211 attrs.addCDATAAttribute(CDMFRTagsConstants.ATTRIBUTE_ID, person.getCDMId()); 2212 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_PERSON, attrs); 2213 2214 // <personID>login</personID> 2215 String login = person.getLogin(); 2216 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PERSON_ID, StringUtils.isNotEmpty(login) ? login : person.getName()); 2217 2218 // <name> 2219 // <given>prénom</given> 2220 // <family>nom</family> 2221 // </name> 2222 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_NAME); 2223 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_GIVEN_NAME, person.getGivenName()); 2224 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FAMILY_NAME, person.getLastName()); 2225 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_NAME); 2226 2227 // <title><text>titre</text></title> 2228 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_TITLE); 2229 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, person.getPersonTitle()); 2230 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_TITLE); 2231 2232 // <role><text>role</text></role> 2233 for (String role : person.getRole()) 2234 { 2235 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ROLE); 2236 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_TEXT, role); 2237 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ROLE); 2238 } 2239 2240 // <affiliation> 2241 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_AFFILIATION); 2242 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_REF_ORG_UNIT); 2243 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_PROFESS_FIELD); 2244 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_SECT_CNU); 2245 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_CDMFR + CDMFRTagsConstants.TAG_AFFILIATION); 2246 2247 2248 // <contactData> 2249 ContactData contactData = person.getContactData(); 2250 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_CONTACT_DATA); 2251 2252 // <adr> 2253 // <extadr>extadr</extadr> 2254 // <street>address</street> 2255 // <locality>locality</locality> 2256 // <pcode>pcode</pcode> 2257 // </adr> 2258 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 2259 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_EXTADR, contactData.getAdditionalAddress()); 2260 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_STREET, contactData.getAddress()); 2261 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LOCALITY, contactData.getTown()); 2262 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PCODE, contactData.getZipCode()); 2263 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_ADDRESS); 2264 2265 // <telephone>telephone</telephone> 2266 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_PHONE, contactData.getPhone()); 2267 2268 // <fax>fax</fax> 2269 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_FAX, contactData.getFax()); 2270 2271 // <email>email</email> 2272 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_EMAIL, contactData.getMail()); 2273 2274 // <webLink> 2275 // <href>href</href> 2276 // <linkName>linkName</linkName> 2277 // </webLink> 2278 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.TAG_WEB_LINK); 2279 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_HREF, contactData.getWebLinkUrl()); 2280 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.TAG_LINK_NAME, contactData.getWebLinkLabel()); 2281 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_WEB_LINK); 2282 2283 // </contactData> 2284 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_CONTACT_DATA); 2285 2286 // <infoBlock>...</infoBlock> 2287 DataContext context = RepositoryDataContext.newInstance() 2288 .withObject(person) 2289 .withDataPath(Person.ADDITIONAL_INFORMATIONS); 2290 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.TAG_INFO_BLOCK, person.getAdditionalInformations(), context, _sourceResolver, false, isExportForAmetys()); 2291 2292 // <infoBlock userDefined="ametys-extension>...</infoBlock> 2293 saxExtensions(contentHandler, person, null, null); 2294 2295 // </person> 2296 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.TAG_PERSON); 2297 } 2298 catch (NoLiveVersionException e) 2299 { 2300 getLogger().error("Person {} ({}) is not validated so it cannot be exported to CDM-fr.", person.getTitle(), person.getId()); 2301 } 2302 finally 2303 { 2304 request.setAttribute(Content.class.getName(), currentContent); 2305 } 2306 } 2307 2308 private String _getMentionType(Program program) 2309 { 2310 return Optional.ofNullable(program.<ContentValue>getValue(AbstractProgram.DEGREE)) 2311 .flatMap(ContentValue::getContentIfExists) 2312 .map(c -> c.<String>getValue(OdfReferenceTableHelper.DEGREE_MENTION_TYPE)) 2313 .orElse(null); 2314 } 2315 2316 //***********************************************************************// 2317 // MISC // 2318 //***********************************************************************// 2319 2320 /** 2321 * SAX value as attributes if not null nor empty 2322 * @param attrs the XML attributes 2323 * @param localName the local name 2324 * @param value the value 2325 */ 2326 protected void _addNotNullAttribute(AttributesImpl attrs, String localName, String value) 2327 { 2328 if (StringUtils.isNotEmpty(value)) 2329 { 2330 attrs.addCDATAAttribute(localName, value); 2331 } 2332 } 2333 2334 /** 2335 * SAX value as attributes if not null nor empty 2336 * @param attrs the XML attributes 2337 * @param localName the local name 2338 * @param value the value 2339 */ 2340 protected void _addPositiveAttribute(AttributesImpl attrs, String localName, double value) 2341 { 2342 if (value > 0) 2343 { 2344 attrs.addCDATAAttribute(localName, String.valueOf(value)); 2345 } 2346 } 2347}