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