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