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.util.Set; 019 020import org.apache.avalon.framework.service.ServiceException; 021import org.apache.avalon.framework.service.ServiceManager; 022import org.apache.avalon.framework.service.Serviceable; 023import org.apache.cocoon.xml.AttributesImpl; 024import org.apache.cocoon.xml.XMLUtils; 025import org.apache.commons.lang3.ArrayUtils; 026import org.apache.commons.lang3.StringUtils; 027import org.apache.excalibur.source.SourceResolver; 028import org.xml.sax.ContentHandler; 029import org.xml.sax.SAXException; 030 031import org.ametys.cms.data.ContentValue; 032import org.ametys.cms.data.File; 033import org.ametys.cms.data.Geocode; 034import org.ametys.cms.data.RichText; 035import org.ametys.cms.data.type.ModelItemTypeConstants; 036import org.ametys.cms.repository.Content; 037import org.ametys.core.util.FilenameUtils; 038import org.ametys.core.util.URIUtils; 039import org.ametys.odf.catalog.Catalog; 040import org.ametys.odf.catalog.CatalogsManager; 041import org.ametys.odf.course.Course; 042import org.ametys.odf.coursepart.CoursePart; 043import org.ametys.odf.enumeration.MonthEnumerator; 044import org.ametys.odf.enumeration.OdfReferenceTableHelper; 045import org.ametys.odf.orgunit.OrgUnit; 046import org.ametys.odf.person.Person; 047import org.ametys.odf.program.AbstractProgram; 048import org.ametys.odf.program.Container; 049import org.ametys.odf.program.Program; 050import org.ametys.odf.program.ProgramFactory; 051import org.ametys.plugins.repository.AmetysObjectResolver; 052import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeater; 053import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeaterEntry; 054import org.ametys.runtime.config.Config; 055 056/** 057 * base CDMfr extension for Ametys 058 */ 059public class AmetysCDMfrExtension implements CDMfrExtension, Serviceable 060{ 061 private OdfReferenceTableHelper _refTableHelper; 062 private CatalogsManager _catalogsManager; 063 private SourceResolver _sourceResolver; 064 private AmetysObjectResolver _resolver; 065 private MonthEnumerator _monthEnumerator; 066 067 @Override 068 public void service(ServiceManager manager) throws ServiceException 069 { 070 _refTableHelper = (OdfReferenceTableHelper) manager.lookup(OdfReferenceTableHelper.ROLE); 071 _catalogsManager = (CatalogsManager) manager.lookup(CatalogsManager.ROLE); 072 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 073 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 074 _monthEnumerator = (MonthEnumerator) manager.lookup(MonthEnumerator.ROLE); 075 } 076 077 @Override 078 public void abstractProgram2CDM(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program, Set<String> persons, Set<String> orgUnits) throws SAXException 079 { 080 AttributesImpl attrs = new AttributesImpl(); 081 082 // Certified 083 // <ametys-cdm:certified/> 084 if (program.isCertified()) 085 { 086 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.CERTIFIED); 087 } 088 089 // Passerelle et réorientation 090 // <ametys-cdm:reorientation>...</ametys-cdm:reorientation> 091 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.REORIENTATION, program.getReorientation(), _sourceResolver, attrs); 092 093 // Ouvert en stage 094 // <ametys-cdm:internshipOpen/> 095 if (program.isInternshipOpen()) 096 { 097 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.INTERNSHIP_OPEN); 098 } 099 100 // Stages 101 // <ametys-cdm:training> 102 // <ametys-cdm:trainingInfo value="internship_mandatory">Obligatoire</ametys-cdm:trainingInfo> 103 // <ametys-cdm:trainingDuration>6 mois</ametys-cdm:trainingInfo> 104 // <ametys-cdm:trainingAbroadInfo value="internship_mandatory">Obligatoire</ametys-cdm:trainingAbroadInfo> 105 // <ametys-cdm:trainingAbroadDuration>6 mois</ametys-cdm:trainingAbroadDuration> 106 // <ametys-cdm:trainingDetails> 107 // <ametys-cdm:trainingDetail> 108 // <ametys-cdm:title>...</ametys-cmd:title> 109 // <ametys-cdm:duration>...</ametys-cmd:duration> 110 // <ametys-cdm:period>...</ametys-cmd:period> 111 // <ametys-cdm:kind>...</ametys-cmd:kind> 112 // </ametys-cdm:trainingDetail> 113 // </ametys-cdm:trainingDetails> 114 // </ametys-cdm:training> 115 saxTraining(contentHandler, program); 116 117 // Etablissement partenaires 118 // <ametys-cdm:partnerSchools/> 119 saxPartnerSchools(contentHandler, program); 120 121 // Laboratoires partenaires 122 // <ametys-cdm:partnerLaboratories/> 123 saxPartnerLaboratories(contentHandler, program); 124 125 // Fichier attachés 126 // <ametys-cdm:attachments/> 127 saxAttachments(contentHandler, program); 128 129 // Niveau RNCP 130 // <ametys-cdm:rncpLevel/> 131 if (program instanceof Program) 132 { 133 String[] rncpLevels = program.getRncpLevel(); 134 135 if (rncpLevels.length > 0) 136 { 137 for (String rncpLevel : rncpLevels) 138 { 139 String rncpValue = _refTableHelper.getItemCDMfrValue(rncpLevel, true); 140 String rncpLabel = _refTableHelper.getItemLabel(rncpLevel, program.getLanguage()); 141 142 attrs = new AttributesImpl(); 143 attrs.addCDATAAttribute("value", rncpValue); 144 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.RNCP_LEVEL, attrs, rncpLabel); 145 } 146 } 147 else 148 { 149 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.RNCP_LEVEL); 150 } 151 } 152 153 // RNCP code 154 // <ametys-cdm:rncpCode>Code RNCP</ametys-cdm:rncpCode> 155 for (String rncpCode : program.getRncpCode()) 156 { 157 if (StringUtils.isNotEmpty(rncpCode)) 158 { 159 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "rncpCode", rncpCode); 160 } 161 } 162 163 // Parcours partagée 164 // <ametys-cdm:sharedWith>FRUAIXXXXXPRYYYYY</ametys-cdm:sharedWith> 165 for (String sharedProgram : program.getSharedWith()) 166 { 167 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.SHARED_WITH, sharedProgram); 168 } 169 170 // Niveau(x) d'entrée 171 // <ametys-cdm:educationEntryLevel code="code">Label</ametys-cdm:educationEntryLevel> 172 _saxMultipleEnumeration(contentHandler, program.getEducationLevelEntry(), AbstractProgram.EDUCATION_ENTRY_LEVEL, program.getLanguage()); 173 174 // Campus 175 // <ametys-cdm:campus code="code">Label</ametys-cdm:campus> 176 _saxMultipleEnumeration(contentHandler, program.getCampus(), AbstractProgram.CAMPUS, program.getLanguage()); 177 178 // Lieu(x) à l'étranger 179 // <ametys-cdm:foreignPlace code="code">Label</ametys-cdm:foreignPlace> 180 _saxMultipleEnumeration(contentHandler, program.getForeignPlace(), AbstractProgram.FOREIGN_PLACE, program.getLanguage()); 181 182 // Champ(s) de formation 183 // <ametys-cdm:programField code="code">Label</ametys-cdm:programField> 184 _saxMultipleEnumeration(contentHandler, program.getProgramField(), AbstractProgram.PROGRAM_FIELD, program.getLanguage()); 185 186 // Disciplines 187 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 188 _saxMultipleEnumeration(contentHandler, program.getDisciplines(), AbstractProgram.DISCIPLINES, program.getLanguage()); 189 190 // Compétences requises 191 // <ametys-cdm:requiredskills code="code">Label</ametys-cdm:disciplines> 192 _saxMultipleEnumeration(contentHandler, program.getRequiredSkills(), AbstractProgram.REQUIRED_SKILLS, program.getLanguage()); 193 194 // Poursuite d'études dans l'établissement 195 // <ametys-cdm:furtherStudyPrograms code="cdm-code">Label</ametys-cdm:furtherStudyPrograms> 196 for (String furtherStudyProgramId : program.getFurtherStudyPrograms()) 197 { 198 AbstractProgram furtherStudyProgram = _resolver.resolveById(furtherStudyProgramId); 199 attrs = new AttributesImpl(); 200 attrs.addCDATAAttribute("code", furtherStudyProgram.getCdmCode()); 201 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.FURTHER_STUDY_PROGRAMS, attrs, furtherStudyProgram.getTitle()); 202 } 203 204 // Secteurs d'activité 205 // <ametys-cdm:sectors code="code">Label</ametys-cdm:sectors> 206 _saxMultipleEnumeration(contentHandler, program.getSectors(), AbstractProgram.SECTORS, program.getLanguage()); 207 208 // Ouvert en alternance 209 // <ametys-cdm:apprenticeshipOpen /> 210 if (program.isApprenticeshipOpen()) 211 { 212 XMLUtils.createElement(contentHandler, AbstractProgram.APPRENTICESHIP_OPEN); 213 } 214 215 // Rythme d'alternance 216 // <ametys-cdm:apprenticeshipPeriod>...</ametys-cdm:apprenticeshipPeriod> 217 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.APPRENTICESHIP_PERIOD, program.getApprenticeshipPeriod(), _sourceResolver); 218 219 // Type(s) de contrat 220 // <ametys-cdm:apprenticeshipContract code="code">Label</ametys-cdm:apprenticeshipContract> 221 _saxMultipleEnumeration(contentHandler, program.getApprenticeshipContract(), AbstractProgram.APPRENTICESHIP_CONTRACT, program.getLanguage()); 222 223 // Formation internationale 224 // <ametys-cdm:internationalEducation code="code">Label</ametys-cdm:internationalEducation> 225 _saxMultipleEnumeration(contentHandler, program.getInternationalEducation(), AbstractProgram.INTERNATIONAL_EDUCATION, program.getLanguage()); 226 227 // Dimension internationale 228 // <ametys-cdm:internationalDimension>...</ametys-cdm:internationalDimension> 229 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.INTERNATIONAL_DIMENSION, program.getInternationalDimension(), _sourceResolver); 230 231 // Géolocalisation 232 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 233 Geocode geocode = program.getGeocode(); 234 if (geocode != null) 235 { 236 Double latitude = geocode.getLatitude(); 237 Double longitude = geocode.getLongitude(); 238 if (latitude != null && longitude != null) 239 { 240 attrs = new AttributesImpl(); 241 attrs.addCDATAAttribute("latitude", String.valueOf(latitude)); 242 attrs.addCDATAAttribute("longitude", String.valueOf(longitude)); 243 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.GEOCODE, attrs); 244 } 245 } 246 247 // Autres structures partenaires 248 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.OTHER_PARTNERS, program.getOtherPartners(), _sourceResolver); 249 250 // Certifications possibles 251 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 252 _saxMultipleEnumeration(contentHandler, program.getAvailableCertification(), AbstractProgram.AVAILABLE_CERTIFICATION, program.getLanguage()); 253 254 // Autre contact 255 // <ametys-cdm:otherContact>...</ametys-cdm:otherContact> 256 RichText otherContact = program.getValue(AbstractProgram.OTHER_CONTACT, false, null); 257 if (otherContact != null) 258 { 259 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.OTHER_CONTACT, otherContact, _sourceResolver); 260 } 261 } 262 263 /** 264 * SAX a multiple metadata based on an reference table. 265 * <ametys-cdm:tagName code="code">Label</ametys-cdm:tagName> 266 * @param contentHandler The handler 267 * @param values Values to SAX 268 * @param tagName The tag name 269 * @param lang The language to translate the label 270 * @throws SAXException if an error occurs 271 */ 272 private void _saxMultipleEnumeration(ContentHandler contentHandler, String[] values, String tagName, String lang) throws SAXException 273 { 274 for (String value : values) 275 { 276 _saxSingleEnumeration(contentHandler, value, tagName, lang); 277 } 278 } 279 280 private void _saxSingleEnumeration(ContentHandler contentHandler, String value, String tagName, String lang) throws SAXException 281 { 282 String code = _refTableHelper.getItemCDMfrValue(value, true); 283 String label = _refTableHelper.getItemLabel(value, lang); 284 285 AttributesImpl attrs = new AttributesImpl(); 286 attrs.addCDATAAttribute("code", code); 287 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + tagName, attrs, label); 288 } 289 290 /** 291 * Sax training and internship informations. 292 * @param contentHandler the receiving contentHandler. 293 * @param program the abstract program (common for program and subprogram) 294 * @throws SAXException if an error occurs during CDM processing. 295 */ 296 protected void saxTraining(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 297 { 298 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "training"); 299 300 String internship = program.getInternship(); 301 if (!internship.isEmpty()) 302 { 303 AttributesImpl attrs = new AttributesImpl(); 304 attrs.addCDATAAttribute("value", _refTableHelper.getItemCDMfrValue(internship, true)); 305 String internshipLabel = _refTableHelper.getItemLabel(internship, program.getLanguage()); 306 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingInfo", attrs, internshipLabel); 307 } 308 else 309 { 310 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingInfo"); 311 } 312 313 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDuration", program.getInternshipDuration()); 314 315 String internshipAbroad = program.getInternshipAbroad(); 316 if (!internshipAbroad.isEmpty()) 317 { 318 AttributesImpl attrs = new AttributesImpl(); 319 attrs.addCDATAAttribute("value", _refTableHelper.getItemCDMfrValue(internshipAbroad, true)); 320 String internshipLabel = _refTableHelper.getItemLabel(internshipAbroad, program.getLanguage()); 321 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadInfo", attrs, internshipLabel); 322 } 323 else 324 { 325 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadInfo"); 326 } 327 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadDuration", program.getAbroadInternshipDuration()); 328 329 if (program.hasValue(AbstractProgram.INTERNSHIP_DESCRIPTION)) 330 { 331 ModelAwareRepeater internshipDescriptions = program.getRepeater(AbstractProgram.INTERNSHIP_DESCRIPTION); 332 if (internshipDescriptions.getSize() > 0) 333 { 334 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetails"); 335 for (ModelAwareRepeaterEntry internshipDescription : internshipDescriptions.getEntries()) 336 { 337 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetail"); 338 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "title", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_TITLE, false, StringUtils.EMPTY)); 339 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "duration", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_DURATION, false, StringUtils.EMPTY)); 340 341 for (String value : internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_PERIOD, false, ArrayUtils.EMPTY_STRING_ARRAY)) 342 { 343 AttributesImpl attrs = new AttributesImpl(); 344 attrs.addCDATAAttribute("code", value); 345 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "period", attrs, _monthEnumerator.getLabel(value, program.getLanguage())); 346 } 347 348 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "kind", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_KIND), _sourceResolver); 349 350 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetail"); 351 } 352 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetails"); 353 } 354 } 355 356 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "training"); 357 } 358 359 /** 360 * Sax partner schools (<ametys-cdm:partnerSchools/>). 361 * @param contentHandler the receiving contentHandler. 362 * @param program the abstract program (common for program and subprogram) 363 * @throws SAXException if an error occurs during CDM processing. 364 */ 365 protected void saxPartnerSchools(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 366 { 367 if (program.hasValue(AbstractProgram.PARTNER_SCHOOLS)) 368 { 369 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_SCHOOLS); 370 371 ModelAwareRepeater partnerSchools = program.getRepeater(AbstractProgram.PARTNER_SCHOOLS); 372 for (ModelAwareRepeaterEntry partnerSchool : partnerSchools.getEntries()) 373 { 374 String linkUrl = partnerSchool.getValue(AbstractProgram.PARTNER_SCHOOLS_LINK_URL, false, StringUtils.EMPTY); 375 String linkLabel = partnerSchool.getValue(AbstractProgram.PARTNER_SCHOOLS_LINK_LABEL, false, StringUtils.EMPTY); 376 377 if (!linkUrl.isEmpty() || !linkLabel.isEmpty()) 378 { 379 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerSchool"); 380 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkUrl", linkUrl); 381 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkLabel", linkLabel); 382 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerSchool"); 383 } 384 } 385 386 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_SCHOOLS); 387 } 388 } 389 390 /** 391 * Sax partner laboratories (<ametys-cdm:partnerLaboratories/>). 392 * @param contentHandler the receiving contentHandler. 393 * @param program the abstract program (common for program and subprogram) 394 * @throws SAXException if an error occurs during CDM processing. 395 */ 396 protected void saxPartnerLaboratories(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 397 { 398 if (program.hasValue(AbstractProgram.PARTNER_LABORATORIES)) 399 { 400 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_LABORATORIES); 401 402 ModelAwareRepeater partnerLaboratories = program.getRepeater(AbstractProgram.PARTNER_LABORATORIES); 403 for (ModelAwareRepeaterEntry partnerLaboratory : partnerLaboratories.getEntries()) 404 { 405 String linkUrl = partnerLaboratory.getValue(AbstractProgram.PARTNER_LABORATORIES_LINK_URL, false, StringUtils.EMPTY); 406 String linkLabel = partnerLaboratory.getValue(AbstractProgram.PARTNER_LABORATORIES_LINK_LABEL, false, StringUtils.EMPTY); 407 408 if (!linkUrl.isEmpty() || !linkLabel.isEmpty()) 409 { 410 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerLaboratory"); 411 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkUrl", linkUrl); 412 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkLabel", linkLabel); 413 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerLaboratory"); 414 } 415 } 416 417 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_LABORATORIES); 418 } 419 } 420 421 /** 422 * Sax attachments (<ametys-cdm:attachments/>). 423 * @param contentHandler the receiving contentHandler. 424 * @param program the abstract program (common for program and subprogram) 425 * @throws SAXException if an error occurs during CDM processing. 426 */ 427 protected void saxAttachments(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 428 { 429 if (program.hasValue(AbstractProgram.ATTACHMENTS)) 430 { 431 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.ATTACHMENTS); 432 433 ModelAwareRepeater attachments = program.getRepeater(AbstractProgram.ATTACHMENTS); 434 for (ModelAwareRepeaterEntry entry: attachments.getEntries()) 435 { 436 if (entry.hasNonEmptyValue(AbstractProgram.ATTACHMENTS_ATTACHMENT)) 437 { 438 String url = null; 439 if (ModelItemTypeConstants.FILE_ELEMENT_TYPE_ID.equals(entry.getType(AbstractProgram.ATTACHMENTS_ATTACHMENT).getId())) 440 { 441 File file = entry.getValue(AbstractProgram.ATTACHMENTS_ATTACHMENT); 442 url = _getFileAbsoluteUrl(program, file, "attachments[" + entry.getPosition() + "]/attachment"); 443 } 444 445 String text = entry.getValue(AbstractProgram.ATTACHMENTS_ATTACHMENT_TEXT, false, StringUtils.EMPTY); 446 447 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "attachment"); 448 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "text", text); 449 if (url != null) 450 { 451 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "href", url); 452 } 453 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "attachment"); 454 } 455 } 456 457 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.ATTACHMENTS); 458 } 459 } 460 461 /** 462 * Sax the acquired skills 463 * @param contentHandler the receiving contentHandler. 464 * @param course the course 465 * @throws SAXException if an error occurs during CDM processing. 466 */ 467 protected void saxAcquiredSkills(ContentHandler contentHandler, Course course) throws SAXException 468 { 469 if (course.hasValue(Course.ACQUIRED_SKILLS)) 470 { 471 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.ACQUIRED_SKILLS); 472 473 ModelAwareRepeater repeater = course.getRepeater(Course.ACQUIRED_SKILLS); 474 for (ModelAwareRepeaterEntry entry : repeater.getEntries()) 475 { 476 ContentValue skillSet = entry.getValue("skillSet", false, null); 477 if (skillSet != null) 478 { 479 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "acquiredSkill"); 480 481 _saxSingleEnumeration(contentHandler, skillSet.getContentId(), "skillSet", course.getLanguage()); 482 483 ModelAwareRepeater skillRep = entry.getRepeater("skills"); 484 if (skillRep != null) 485 { 486 for (ModelAwareRepeaterEntry skillEntry : skillRep.getEntries()) 487 { 488 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skill"); 489 490 ContentValue skill = skillEntry.getValue("skill", false, null); 491 if (skill != null) 492 { 493 _saxSingleEnumeration(contentHandler, skill.getContentId(), "skill", course.getLanguage()); 494 } 495 ContentValue acquisitionLevel = skillEntry.getValue("acquisitionLevel", false, null); 496 if (acquisitionLevel != null) 497 { 498 _saxSingleEnumeration(contentHandler, acquisitionLevel.getContentId(), "acquisitionLevel", course.getLanguage()); 499 } 500 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skill"); 501 } 502 } 503 504 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "acquiredSkill"); 505 506 } 507 } 508 509 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.ACQUIRED_SKILLS); 510 } 511 } 512 513 private String _getFileAbsoluteUrl(AbstractProgram<? extends ProgramFactory> program, File file, String dataPath) 514 { 515 StringBuilder uri = new StringBuilder(); 516 uri.append("/_odf") 517 .append("/_contents") 518 .append(FilenameUtils.encodePath(program.getPath())) 519 .append("/_attribute/") 520 .append(dataPath) 521 .append("/").append(FilenameUtils.encodeName(file.getName())); 522 523 StringBuilder resultPath = new StringBuilder(); 524 resultPath.append(StringUtils.stripEnd(StringUtils.removeEndIgnoreCase(Config.getInstance().getValue("cms.url"), "index.html"), "/")) 525 .append(URIUtils.encodePath(uri.toString())) 526 .append("?objectId=" + URIUtils.encodeParameter(program.getId())); 527 528 return resultPath.toString(); 529 } 530 531 @Override 532 public void program2CDM(ContentHandler contentHandler, Program program, Set<String> persons, Set<String> orgUnits) throws SAXException 533 { 534 // Catalogue de formation 535 String catalogCode = program.getCatalog(); 536 if (StringUtils.isNotEmpty(catalogCode)) 537 { 538 AttributesImpl attrs = new AttributesImpl(); 539 attrs.addCDATAAttribute("value", catalogCode); 540 541 Catalog catalog = _catalogsManager.getCatalog(catalogCode); 542 String catalogLabel = catalog != null ? catalog.getTitle() : catalogCode; 543 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "catalog", attrs, catalogLabel); 544 } 545 } 546 547 @Override 548 public void course2CDM(ContentHandler contentHandler, Course course, Set<String> persons, Set<String> orgUnits) throws SAXException 549 { 550 // Catalogue de formation 551 String catalogCode = course.getCatalog(); 552 if (StringUtils.isNotEmpty(catalogCode)) 553 { 554 AttributesImpl attrs = new AttributesImpl(); 555 attrs.addCDATAAttribute("value", catalogCode); 556 557 Catalog catalog = _catalogsManager.getCatalog(catalogCode); 558 String catalogLabel = catalog != null ? catalog.getTitle() : catalogCode; 559 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "catalog", attrs, catalogLabel); 560 } 561 562 // Ouvert aux étudiants en échange 563 // <ametys-cdm:openToExchangeStudents /> 564 if (course.isOpenToExchangeStudents()) 565 { 566 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.OPEN_TO_EXCHANGE_STUDENTS); 567 } 568 569 // <ametys-cdm:requiredSkills/> 570 _saxMultipleEnumeration(contentHandler, course.getRequiredSkills(), Course.REQUIRED_SKILLS, course.getLanguage()); 571 572 // Compétence acquises 573 saxAcquiredSkills(contentHandler, course); 574 575 // Course parts 576 for (CoursePart coursePart : course.getCourseParts()) 577 { 578 _coursePart2CDM(contentHandler, coursePart); 579 } 580 } 581 582 /** 583 * Sax a {@link CoursePart} with the following structure : 584 * <ametys-cdm:coursePart @ametys-cdm:code="code"> 585 * <ametys-cdm:title>Title</ametys-cdm:title> 586 * <ametys-cdm:nature>Nature CDM-fr value or code</ametys-cdm:nature> 587 * <ametys-cdm:nbHours>Number of hours</ametys-cdm:nbHours> 588 * <ametys-cdm:courseHolder>CDM ID of the course holder</ametys-cdm:courseHolder> 589 * </ametys-cdm:coursePart> 590 * @param contentHandler The content handler 591 * @param coursePart The {@link CoursePart} to sax 592 * @throws SAXException if an error occurs 593 */ 594 protected void _coursePart2CDM(ContentHandler contentHandler, CoursePart coursePart) throws SAXException 595 { 596 AttributesImpl attrs = new AttributesImpl(); 597 attrs.addCDATAAttribute("code", coursePart.getCode()); 598 599 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "coursePart", attrs); 600 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Content.ATTRIBUTE_TITLE, coursePart.getTitle()); 601 String nature = _refTableHelper.getItemCDMfrValue(coursePart.getNature(), true); 602 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.NATURE, nature); 603 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.NB_HOURS, String.valueOf(coursePart.getNumberOfHours())); 604 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.COURSE_HOLDER, coursePart.getCourseHolder().getCDMId()); 605 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "coursePart"); 606 } 607 608 @Override 609 public void orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit) throws SAXException 610 { 611 // nothing 612 } 613 614 @Override 615 public void person2CDM(ContentHandler contentHandler, Person person) throws SAXException 616 { 617 // Titre du contenu (à ne pas confondre avec personTitle) 618 String title = person.getTitle(); 619 if (StringUtils.isNotEmpty(title)) 620 { 621 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "title", title); 622 } 623 } 624 625 @Override 626 public void container2CDM(ContentHandler contentHandler, Container container, Set<String> persons, Set<String> orgUnits) throws SAXException 627 { 628 // Période 629 // <ametys-cdm:period code="code">Label</ametys-cdm:period> 630 String period = container.getPeriod(); 631 if (StringUtils.isNotEmpty(period)) 632 { 633 String code = _refTableHelper.getItemCDMfrValue(period, true); 634 String label = _refTableHelper.getItemLabel(period, container.getLanguage()); 635 636 AttributesImpl attrs = new AttributesImpl(); 637 attrs.addCDATAAttribute("code", code); 638 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Container.PERIOD, attrs, label); 639 } 640 } 641}