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