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