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