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 // Niveau(x) d'entrée 164 // <ametys-cdm:educationEntryLevel code="code">Label</ametys-cdm:educationEntryLevel> 165 _saxMultipleEnumeration(contentHandler, program.getEducationLevelEntry(), AbstractProgram.EDUCATION_ENTRY_LEVEL, program.getLanguage()); 166 167 // Campus 168 // <ametys-cdm:campus code="code">Label</ametys-cdm:campus> 169 _saxMultipleEnumeration(contentHandler, program.getCampus(), AbstractProgram.CAMPUS, program.getLanguage()); 170 171 // Lieu(x) à l'étranger 172 // <ametys-cdm:foreignPlace code="code">Label</ametys-cdm:foreignPlace> 173 _saxMultipleEnumeration(contentHandler, program.getForeignPlace(), AbstractProgram.FOREIGN_PLACE, program.getLanguage()); 174 175 // Champ(s) de formation 176 // <ametys-cdm:programField code="code">Label</ametys-cdm:programField> 177 _saxMultipleEnumeration(contentHandler, program.getProgramField(), AbstractProgram.PROGRAM_FIELD, program.getLanguage()); 178 179 // Disciplines 180 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 181 _saxMultipleEnumeration(contentHandler, program.getDisciplines(), AbstractProgram.DISCIPLINES, program.getLanguage()); 182 183 // Compétences requises 184 // <ametys-cdm:requiredskills code="code">Label</ametys-cdm:disciplines> 185 _saxMultipleEnumeration(contentHandler, program.getRequiredSkills(), AbstractProgram.REQUIRED_SKILLS, program.getLanguage()); 186 187 // Poursuite d'études dans l'établissement 188 // <ametys-cdm:furtherStudyPrograms code="cdm-code">Label</ametys-cdm:furtherStudyPrograms> 189 for (String furtherStudyProgramId : program.getFurtherStudyPrograms()) 190 { 191 AbstractProgram furtherStudyProgram = _resolver.resolveById(furtherStudyProgramId); 192 attrs = new AttributesImpl(); 193 attrs.addCDATAAttribute("code", furtherStudyProgram.getCdmCode()); 194 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.FURTHER_STUDY_PROGRAMS, attrs, furtherStudyProgram.getTitle()); 195 } 196 197 // Secteurs d'activité 198 // <ametys-cdm:sectors code="code">Label</ametys-cdm:sectors> 199 _saxMultipleEnumeration(contentHandler, program.getSectors(), AbstractProgram.SECTORS, program.getLanguage()); 200 201 // Ouvert en alternance 202 // <ametys-cdm:apprenticeshipOpen /> 203 if (program.isApprenticeshipOpen()) 204 { 205 XMLUtils.createElement(contentHandler, AbstractProgram.APPRENTICESHIP_OPEN); 206 } 207 208 // Rythme d'alternance 209 // <ametys-cdm:apprenticeshipPeriod>...</ametys-cdm:apprenticeshipPeriod> 210 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.APPRENTICESHIP_PERIOD, program.getApprenticeshipPeriod(), _sourceResolver); 211 212 // Type(s) de contrat 213 // <ametys-cdm:apprenticeshipContract code="code">Label</ametys-cdm:apprenticeshipContract> 214 _saxMultipleEnumeration(contentHandler, program.getApprenticeshipContract(), AbstractProgram.APPRENTICESHIP_CONTRACT, program.getLanguage()); 215 216 // Formation internationale 217 // <ametys-cdm:internationalEducation code="code">Label</ametys-cdm:internationalEducation> 218 _saxMultipleEnumeration(contentHandler, program.getInternationalEducation(), AbstractProgram.INTERNATIONAL_EDUCATION, program.getLanguage()); 219 220 // Dimension internationale 221 // <ametys-cdm:internationalDimension>...</ametys-cdm:internationalDimension> 222 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.INTERNATIONAL_DIMENSION, program.getInternationalDimension(), _sourceResolver); 223 224 // Géolocalisation 225 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 226 Geocode geocode = program.getGeocode(); 227 if (geocode != null) 228 { 229 Double latitude = geocode.getLatitude(); 230 Double longitude = geocode.getLongitude(); 231 if (latitude != null && longitude != null) 232 { 233 attrs = new AttributesImpl(); 234 attrs.addCDATAAttribute("latitude", String.valueOf(latitude)); 235 attrs.addCDATAAttribute("longitude", String.valueOf(longitude)); 236 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.GEOCODE, attrs); 237 } 238 } 239 240 // Autres structures partenaires 241 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.OTHER_PARTNERS, program.getOtherPartners(), _sourceResolver); 242 243 // Certifications possibles 244 // <ametys-cdm:disciplines code="code">Label</ametys-cdm:disciplines> 245 _saxMultipleEnumeration(contentHandler, program.getAvailableCertification(), AbstractProgram.AVAILABLE_CERTIFICATION, program.getLanguage()); 246 247 // Autre contact 248 // <ametys-cdm:otherContact>...</ametys-cdm:otherContact> 249 RichText otherContact = program.getValue(AbstractProgram.OTHER_CONTACT, false, null); 250 if (otherContact != null) 251 { 252 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.OTHER_CONTACT, otherContact, _sourceResolver); 253 } 254 } 255 256 /** 257 * SAX a multiple metadata based on an reference table. 258 * <ametys-cdm:tagName code="code">Label</ametys-cdm:tagName> 259 * @param contentHandler The handler 260 * @param values Values to SAX 261 * @param tagName The tag name 262 * @param lang The language to translate the label 263 * @throws SAXException if an error occurs 264 */ 265 private void _saxMultipleEnumeration(ContentHandler contentHandler, String[] values, String tagName, String lang) throws SAXException 266 { 267 for (String value : values) 268 { 269 _saxSingleEnumeration(contentHandler, value, tagName, lang); 270 } 271 } 272 273 private void _saxSingleEnumeration(ContentHandler contentHandler, String value, String tagName, String lang) throws SAXException 274 { 275 String code = _refTableHelper.getItemCDMfrValue(value, true); 276 String label = _refTableHelper.getItemLabel(value, lang); 277 278 AttributesImpl attrs = new AttributesImpl(); 279 attrs.addCDATAAttribute("code", code); 280 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + tagName, attrs, label); 281 } 282 283 /** 284 * Sax training and internship informations. 285 * @param contentHandler the receiving contentHandler. 286 * @param program the abstract program (common for program and subprogram) 287 * @throws SAXException if an error occurs during CDM processing. 288 */ 289 protected void saxTraining(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 290 { 291 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "training"); 292 293 String internship = program.getInternship(); 294 if (!internship.isEmpty()) 295 { 296 AttributesImpl attrs = new AttributesImpl(); 297 attrs.addCDATAAttribute("value", _refTableHelper.getItemCDMfrValue(internship, true)); 298 String internshipLabel = _refTableHelper.getItemLabel(internship, program.getLanguage()); 299 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingInfo", attrs, internshipLabel); 300 } 301 else 302 { 303 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingInfo"); 304 } 305 306 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDuration", program.getInternshipDuration()); 307 308 String internshipAbroad = program.getInternshipAbroad(); 309 if (!internshipAbroad.isEmpty()) 310 { 311 AttributesImpl attrs = new AttributesImpl(); 312 attrs.addCDATAAttribute("value", _refTableHelper.getItemCDMfrValue(internshipAbroad, true)); 313 String internshipLabel = _refTableHelper.getItemLabel(internshipAbroad, program.getLanguage()); 314 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadInfo", attrs, internshipLabel); 315 } 316 else 317 { 318 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadInfo"); 319 } 320 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingAbroadDuration", program.getAbroadInternshipDuration()); 321 322 if (program.hasValue(AbstractProgram.INTERNSHIP_DESCRIPTION)) 323 { 324 ModelAwareRepeater internshipDescriptions = program.getRepeater(AbstractProgram.INTERNSHIP_DESCRIPTION); 325 if (internshipDescriptions.getSize() > 0) 326 { 327 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetails"); 328 for (ModelAwareRepeaterEntry internshipDescription : internshipDescriptions.getEntries()) 329 { 330 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetail"); 331 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "title", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_TITLE, false, StringUtils.EMPTY)); 332 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "duration", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_DURATION, false, StringUtils.EMPTY)); 333 334 for (String value : internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_PERIOD, false, ArrayUtils.EMPTY_STRING_ARRAY)) 335 { 336 AttributesImpl attrs = new AttributesImpl(); 337 attrs.addCDATAAttribute("code", value); 338 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "period", attrs, _monthEnumerator.getLabel(value, program.getLanguage())); 339 } 340 341 CDMHelper.richText2CDM(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "kind", internshipDescription.getValue(AbstractProgram.INTERNSHIP_DESCRIPTION_KIND), _sourceResolver); 342 343 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetail"); 344 } 345 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "trainingDetails"); 346 } 347 } 348 349 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "training"); 350 } 351 352 /** 353 * Sax partner schools (<ametys-cdm:partnerSchools/>). 354 * @param contentHandler the receiving contentHandler. 355 * @param program the abstract program (common for program and subprogram) 356 * @throws SAXException if an error occurs during CDM processing. 357 */ 358 protected void saxPartnerSchools(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 359 { 360 if (program.hasValue(AbstractProgram.PARTNER_SCHOOLS)) 361 { 362 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_SCHOOLS); 363 364 ModelAwareRepeater partnerSchools = program.getRepeater(AbstractProgram.PARTNER_SCHOOLS); 365 for (ModelAwareRepeaterEntry partnerSchool : partnerSchools.getEntries()) 366 { 367 String linkUrl = partnerSchool.getValue(AbstractProgram.PARTNER_SCHOOLS_LINK_URL, false, StringUtils.EMPTY); 368 String linkLabel = partnerSchool.getValue(AbstractProgram.PARTNER_SCHOOLS_LINK_LABEL, false, StringUtils.EMPTY); 369 370 if (!linkUrl.isEmpty() || !linkLabel.isEmpty()) 371 { 372 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerSchool"); 373 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkUrl", linkUrl); 374 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkLabel", linkLabel); 375 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerSchool"); 376 } 377 } 378 379 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_SCHOOLS); 380 } 381 } 382 383 /** 384 * Sax partner laboratories (<ametys-cdm:partnerLaboratories/>). 385 * @param contentHandler the receiving contentHandler. 386 * @param program the abstract program (common for program and subprogram) 387 * @throws SAXException if an error occurs during CDM processing. 388 */ 389 protected void saxPartnerLaboratories(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 390 { 391 if (program.hasValue(AbstractProgram.PARTNER_LABORATORIES)) 392 { 393 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_LABORATORIES); 394 395 ModelAwareRepeater partnerLaboratories = program.getRepeater(AbstractProgram.PARTNER_LABORATORIES); 396 for (ModelAwareRepeaterEntry partnerLaboratory : partnerLaboratories.getEntries()) 397 { 398 String linkUrl = partnerLaboratory.getValue(AbstractProgram.PARTNER_LABORATORIES_LINK_URL, false, StringUtils.EMPTY); 399 String linkLabel = partnerLaboratory.getValue(AbstractProgram.PARTNER_LABORATORIES_LINK_LABEL, false, StringUtils.EMPTY); 400 401 if (!linkUrl.isEmpty() || !linkLabel.isEmpty()) 402 { 403 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerLaboratory"); 404 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkUrl", linkUrl); 405 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "linkLabel", linkLabel); 406 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "partnerLaboratory"); 407 } 408 } 409 410 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.PARTNER_LABORATORIES); 411 } 412 } 413 414 /** 415 * Sax attachments (<ametys-cdm:attachments/>). 416 * @param contentHandler the receiving contentHandler. 417 * @param program the abstract program (common for program and subprogram) 418 * @throws SAXException if an error occurs during CDM processing. 419 */ 420 protected void saxAttachments(ContentHandler contentHandler, AbstractProgram<? extends ProgramFactory> program) throws SAXException 421 { 422 if (program.hasValue(AbstractProgram.ATTACHMENTS)) 423 { 424 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.ATTACHMENTS); 425 426 ModelAwareRepeater attachments = program.getRepeater(AbstractProgram.ATTACHMENTS); 427 for (ModelAwareRepeaterEntry entry: attachments.getEntries()) 428 { 429 if (entry.hasValue(AbstractProgram.ATTACHMENTS_ATTACHMENT)) 430 { 431 String url = null; 432 if (ModelItemTypeConstants.FILE_ELEMENT_TYPE_ID.equals(entry.getType(AbstractProgram.ATTACHMENTS_ATTACHMENT).getId())) 433 { 434 File file = entry.getValue(AbstractProgram.ATTACHMENTS_ATTACHMENT); 435 url = _getFileAbsoluteUrl(program, file, "attachments[" + entry.getPosition() + "]/attachment"); 436 } 437 438 String text = entry.getValue(AbstractProgram.ATTACHMENTS_ATTACHMENT_TEXT, false, StringUtils.EMPTY); 439 440 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "attachment"); 441 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "text", text); 442 if (url != null) 443 { 444 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "href", url); 445 } 446 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "attachment"); 447 } 448 } 449 450 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + AbstractProgram.ATTACHMENTS); 451 } 452 } 453 454 /** 455 * Sax the acquired skills 456 * @param contentHandler the receiving contentHandler. 457 * @param course the course 458 * @throws SAXException if an error occurs during CDM processing. 459 */ 460 protected void saxAcquiredSkills(ContentHandler contentHandler, Course course) throws SAXException 461 { 462 if (course.hasValue(Course.ACQUIRED_SKILLS)) 463 { 464 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.ACQUIRED_SKILLS); 465 466 ModelAwareRepeater repeater = course.getRepeater(Course.ACQUIRED_SKILLS); 467 for (ModelAwareRepeaterEntry entry : repeater.getEntries()) 468 { 469 ContentValue skillSet = entry.getValue("skillSet", false, null); 470 if (skillSet != null) 471 { 472 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "acquiredSkill"); 473 474 _saxSingleEnumeration(contentHandler, skillSet.getContentId(), "skillSet", course.getLanguage()); 475 476 ModelAwareRepeater skillRep = entry.getRepeater("skills"); 477 if (skillRep != null) 478 { 479 for (ModelAwareRepeaterEntry skillEntry : skillRep.getEntries()) 480 { 481 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skill"); 482 483 ContentValue skill = skillEntry.getValue("skill", false, null); 484 if (skill != null) 485 { 486 _saxSingleEnumeration(contentHandler, skill.getContentId(), "skill", course.getLanguage()); 487 } 488 ContentValue acquisitionLevel = skillEntry.getValue("acquisitionLevel", false, null); 489 if (acquisitionLevel != null) 490 { 491 _saxSingleEnumeration(contentHandler, acquisitionLevel.getContentId(), "acquisitionLevel", course.getLanguage()); 492 } 493 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "skill"); 494 } 495 } 496 497 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "acquiredSkill"); 498 499 } 500 } 501 502 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.ACQUIRED_SKILLS); 503 } 504 } 505 506 private String _getFileAbsoluteUrl(AbstractProgram<? extends ProgramFactory> program, File file, String dataPath) 507 { 508 StringBuilder uri = new StringBuilder(); 509 uri.append("/_odf") 510 .append("/_contents") 511 .append(FilenameUtils.encodePath(program.getPath())) 512 .append("/_attribute/") 513 .append(dataPath) 514 .append("/").append(FilenameUtils.encodeName(file.getName())); 515 516 StringBuilder resultPath = new StringBuilder(); 517 resultPath.append(StringUtils.stripEnd(StringUtils.removeEndIgnoreCase(Config.getInstance().getValue("cms.url"), "index.html"), "/")) 518 .append(URIUtils.encodePath(uri.toString())) 519 .append("?objectId=" + URIUtils.encodeParameter(program.getId())); 520 521 return resultPath.toString(); 522 } 523 524 @Override 525 public void program2CDM(ContentHandler contentHandler, Program program, Set<String> persons, Set<String> orgUnits) throws SAXException 526 { 527 // Catalogue de formation 528 String catalogCode = program.getCatalog(); 529 if (StringUtils.isNotEmpty(catalogCode)) 530 { 531 AttributesImpl attrs = new AttributesImpl(); 532 attrs.addCDATAAttribute("value", catalogCode); 533 534 Catalog catalog = _catalogsManager.getCatalog(catalogCode); 535 String catalogLabel = catalog != null ? catalog.getTitle() : catalogCode; 536 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "catalog", attrs, catalogLabel); 537 } 538 } 539 540 @Override 541 public void course2CDM(ContentHandler contentHandler, Course course, Set<String> persons, Set<String> orgUnits) throws SAXException 542 { 543 // Catalogue de formation 544 String catalogCode = course.getCatalog(); 545 if (StringUtils.isNotEmpty(catalogCode)) 546 { 547 AttributesImpl attrs = new AttributesImpl(); 548 attrs.addCDATAAttribute("value", catalogCode); 549 550 Catalog catalog = _catalogsManager.getCatalog(catalogCode); 551 String catalogLabel = catalog != null ? catalog.getTitle() : catalogCode; 552 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "catalog", attrs, catalogLabel); 553 } 554 555 // Ouvert aux étudiants en échange 556 // <ametys-cdm:openToExchangeStudents /> 557 if (course.isOpenToExchangeStudents()) 558 { 559 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Course.OPEN_TO_EXCHANGE_STUDENTS); 560 } 561 562 // <ametys-cdm:requiredSkills/> 563 _saxMultipleEnumeration(contentHandler, course.getRequiredSkills(), Course.REQUIRED_SKILLS, course.getLanguage()); 564 565 // Compétence acquises 566 saxAcquiredSkills(contentHandler, course); 567 568 // Course parts 569 for (CoursePart coursePart : course.getCourseParts()) 570 { 571 _coursePart2CDM(contentHandler, coursePart); 572 } 573 } 574 575 /** 576 * Sax a {@link CoursePart} with the following structure : 577 * <ametys-cdm:coursePart @ametys-cdm:code="code"> 578 * <ametys-cdm:title>Title</ametys-cdm:title> 579 * <ametys-cdm:nature>Nature CDM-fr value or code</ametys-cdm:nature> 580 * <ametys-cdm:nbHours>Number of hours</ametys-cdm:nbHours> 581 * <ametys-cdm:courseHolder>CDM ID of the course holder</ametys-cdm:courseHolder> 582 * </ametys-cdm:coursePart> 583 * @param contentHandler The content handler 584 * @param coursePart The {@link CoursePart} to sax 585 * @throws SAXException if an error occurs 586 */ 587 protected void _coursePart2CDM(ContentHandler contentHandler, CoursePart coursePart) throws SAXException 588 { 589 AttributesImpl attrs = new AttributesImpl(); 590 attrs.addCDATAAttribute("code", coursePart.getCode()); 591 592 XMLUtils.startElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "coursePart", attrs); 593 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Content.ATTRIBUTE_TITLE, coursePart.getTitle()); 594 String nature = _refTableHelper.getItemCDMfrValue(coursePart.getNature(), true); 595 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.NATURE, nature); 596 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.NB_HOURS, String.valueOf(coursePart.getNumberOfHours())); 597 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + CoursePart.COURSE_HOLDER, coursePart.getCourseHolder().getCDMId()); 598 XMLUtils.endElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "coursePart"); 599 } 600 601 @Override 602 public void orgunit2CDM(ContentHandler contentHandler, OrgUnit orgunit) throws SAXException 603 { 604 // nothing 605 } 606 607 @Override 608 public void person2CDM(ContentHandler contentHandler, Person person) throws SAXException 609 { 610 // Titre du contenu (à ne pas confondre avec personTitle) 611 String title = person.getTitle(); 612 if (StringUtils.isNotEmpty(title)) 613 { 614 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + "title", title); 615 } 616 } 617 618 @Override 619 public void container2CDM(ContentHandler contentHandler, Container container, Set<String> persons, Set<String> orgUnits) throws SAXException 620 { 621 // Période 622 // <ametys-cdm:period code="code">Label</ametys-cdm:period> 623 String period = container.getPeriod(); 624 if (StringUtils.isNotEmpty(period)) 625 { 626 String code = _refTableHelper.getItemCDMfrValue(period, true); 627 String label = _refTableHelper.getItemLabel(period, container.getLanguage()); 628 629 AttributesImpl attrs = new AttributesImpl(); 630 attrs.addCDATAAttribute("code", code); 631 XMLUtils.createElement(contentHandler, CDMFRTagsConstants.NAMESPACE_AMETYS_CDM + Container.PERIOD, attrs, label); 632 } 633 } 634}