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