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