001/* 002 * Copyright 2010 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.program; 017 018import java.time.LocalDate; 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.HashSet; 022import java.util.LinkedHashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.Optional; 026import java.util.Set; 027import java.util.stream.Collectors; 028 029import javax.jcr.Node; 030 031import org.apache.commons.lang3.ArrayUtils; 032import org.apache.commons.lang3.StringUtils; 033 034import org.ametys.cms.data.ContentDataHelper; 035import org.ametys.cms.data.ContentValue; 036import org.ametys.cms.data.Geocode; 037import org.ametys.cms.data.RichText; 038import org.ametys.odf.courselist.CourseList; 039import org.ametys.odf.courselist.CourseListContainer; 040import org.ametys.odf.data.EducationalPath; 041import org.ametys.plugins.repository.AmetysObjectIterable; 042import org.ametys.plugins.repository.AmetysRepositoryException; 043import org.ametys.plugins.repository.RemovableAmetysObject; 044import org.ametys.plugins.repository.RepositoryIntegrityViolationException; 045import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeater; 046import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeaterEntry; 047import org.ametys.runtime.model.ElementDefinition; 048import org.ametys.runtime.model.exception.UndefinedItemPathException; 049 050/** 051 * Abstract common superclass for {@link Program} and {@link SubProgram}. 052 * @param <F> The actual type of the factory 053 */ 054public abstract class AbstractProgram<F extends ProgramFactory> extends AbstractTraversableProgramPart<F> implements CourseListContainer 055{ 056 // ------------------------------------------------// 057 // 058 // PROGRAM ATTRIBUTES 059 // 060 // -----------------------------------------------// 061 /** Constants for attribute 'degree' */ 062 public static final String DEGREE = "degree"; 063 064 /** Constants for attribute 'certified' */ 065 public static final String CERTIFIED = "certified"; 066 067 /** Constants for attribute 'domain' */ 068 public static final String DOMAIN = "domain"; 069 070 /** Constants for attribute 'mention' */ 071 public static final String MENTION = "mention"; 072 073 /** Constants for attribute 'speciality' */ 074 public static final String SPECIALITY = "speciality"; 075 076 /** Constants for attribute 'educationLevel' */ 077 public static final String LEVEL = "educationLevel"; 078 079 /** Constants for attribute 'duration' */ 080 public static final String DURATION = "duration"; 081 082 /** Constants for attribute 'educationLanguage' */ 083 public static final String EDUC_LANGUAGE = "educationLanguage"; 084 085 /** Constants for attribute 'presentation' */ 086 public static final String PRESENTATION = "presentation"; 087 088 /** Constants for attribute 'objectives' */ 089 public static final String OBJECTIVES = "objectives"; 090 091 /** Constants for attribute 'qualification' */ 092 public static final String QUALIFICATION = "qualification"; 093 094 /** Constants for attribute 'teachingOrganization' */ 095 public static final String TEACHING_ORGANIZATION = "teachingOrganization"; 096 097 /** Constants for attribute 'apprenticeshipModalities' */ 098 public static final String APPRENTICESHIP_MODALITIES = "apprenticeshipModalities"; 099 100 /** Constants for attribute 'accessCondition' */ 101 public static final String ACCESS_CONDITION = "accessCondition"; 102 103 /** Constants for attribute 'neededPrerequisite' */ 104 public static final String NEEDED_PREREQUISITE = "neededPrerequisite"; 105 106 /** Constants for attribute 'recommendedPrerequisite' */ 107 public static final String RECOMMENDED_PREREQUISITE = "recommendedPrerequisite"; 108 109 /** Constants for attribute 'expectedResults' */ 110 public static final String EXPECTED_RESULTS = "expectedResults"; 111 112 /** Constants for attribute 'furtherStudy' */ 113 public static final String FURTHER_STUDY = "furtherStudy"; 114 115 /** Constants for attribute 'studyAbroad' */ 116 public static final String STUDY_ABROAD = "studyAbroad"; 117 118 /** Constants for attribute 'targetGroup' */ 119 public static final String TARGET_GROUP = "targetGroup"; 120 121 /** Constants for attribute 'jobOpportunities' */ 122 public static final String JOB_OPPORTUNITIES = "jobOpportunities"; 123 124 /** Constants for attribute 'trainingStrategy' */ 125 public static final String TRAINING_STRATEGY = "trainingStrategy"; 126 127 /** Constants for attribute 'knowledgeCheck' */ 128 public static final String KNOWLEDGE_CHECK = "knowledgeCheck"; 129 130 /** Constants for attribute 'universalAdjustment' */ 131 public static final String UNIVERSAL_ADJUSTMENT = "universalAdjustment"; 132 133 /** Constants for attribute 'certifying' */ 134 public static final String CERTIFYING = "certifying"; 135 136 /** Constants for attribute 'expenses' */ 137 public static final String EXPENSES = "expenses"; 138 139 /** Constants for attribute 'additionalInformations' */ 140 public static final String ADDITIONNAL_INFORMATIONS = "additionalInformations"; 141 142 /** Constants for attribute 'jointOrgUnit' */ 143 public static final String JOINT_ORGUNIT = "jointOrgUnit"; 144 145 /** Constants for attribute 'place' */ 146 public static final String PLACE = "place"; 147 148 /** Constants for attribute 'distanceLearning' */ 149 public static final String DISTANCE_LEARNING = "distanceLearning"; 150 151 /** Constants for attribute 'educationKind' */ 152 public static final String EDUCATION_KIND = "educationKind"; 153 154 /** Constant for attribute 'formofteachingOrg' */ 155 public static final String FORM_OF_TEACHING_ORG = "formofteachingOrg"; 156 157 /** Constants for attribute 'ects' */ 158 public static final String ECTS = "ects"; 159 160 /** Constants for attribute 'internship' */ 161 public static final String INTERNSHIP = "internship"; 162 163 /** Constants for attribute 'internshipDuration' */ 164 public static final String INTERNSHIP_DURATION = "internshipDuration"; 165 166 /** Constants for attribute 'internshipAbroad' */ 167 public static final String INTERNSHIP_ABROAD = "internshipAbroad"; 168 169 /** Constants for attribute 'internshipAbroadDuration' */ 170 public static final String INTERNSHIP_ABROAD_DURATION = "internshipAbroadDuration"; 171 172 /** Constants for attribute 'registrationStart' */ 173 public static final String REGISTRATION_START = "registrationStart"; 174 175 /** Constants for attribute 'registrationDeadline' */ 176 public static final String REGISTRATION_DEADLINE = "registrationDeadline"; 177 178 /** Constants for attribute 'teachingStart' */ 179 public static final String TEACHING_START = "teachingStart"; 180 181 /** Constants for attribute 'teachingEnd' */ 182 public static final String TEACHING_END = "teachingEnd"; 183 184 /** Constants for attribute 'requiredSkills' */ 185 public static final String REQUIRED_SKILLS = "requiredSkills"; 186 187 /** Constants for attribute 'partnerSchools' */ 188 public static final String PARTNER_SCHOOLS = "partnerSchools"; 189 190 /** Constants for attribute 'partnerSchools/linkUrl' */ 191 public static final String PARTNER_SCHOOLS_LINK_URL = "linkUrl"; 192 193 /** Constants for attribute 'partnerSchools/linkLabel' */ 194 public static final String PARTNER_SCHOOLS_LINK_LABEL = "linkLabel"; 195 196 /** Constants for attribute 'partnerLaboratories' */ 197 public static final String PARTNER_LABORATORIES = "partnerLaboratories"; 198 199 /** Constants for attribute 'partnerLaboratories/linkUrl' */ 200 public static final String PARTNER_LABORATORIES_LINK_URL = "linkUrl"; 201 202 /** Constants for attribute 'partnerLaboratories/linkLabel' */ 203 public static final String PARTNER_LABORATORIES_LINK_LABEL = "linkLabel"; 204 205 /** Constants for attribute 'rncpCode' */ 206 public static final String RNCP_CODE = "rncpCode"; 207 208 /** Constants for attribute 'rncpLevel' */ 209 public static final String RNCP_LEVEL = "rncpLevel"; 210 211 /** Constants for attribute 'siseCode' */ 212 public static final String SISE_CODE = "siseCode"; 213 214 /** Constants for attribute 'Cite 97' */ 215 public static final String CITE97_CODE = "cite97Code"; 216 217 /** Constants for attribute 'erasmusCode' */ 218 public static final String ERASMUS_CODE = "erasmusCode"; 219 220 /** Constants for attribute 'erasmusCode' */ 221 public static final String DGESIP_CODE = "dgesipCode"; 222 223 /** Constants for attribute 'formacode' */ 224 public static final String FORMACODE = "formacode"; 225 226 /** Constants for attribute 'romeCode' */ 227 public static final String ROME_CODE = "romeCode"; 228 229 /** Constants for attribute 'fapCode' */ 230 public static final String FAP_CODE = "fapCode"; 231 232 /** Constants for attribute 'nsfCode' */ 233 public static final String NSF_CODE = "nsfCode"; 234 235 /** Constants for attribute 'programWebSite' */ 236 public static final String PROGRAM_WEBSITE = "programWebSite"; 237 238 /** Constants for attribute 'programWebSiteLabel' */ 239 public static final String PROGRAM_WEBSITE_LABEL = "programWebSiteLabel"; 240 241 /** Constants for attribute 'programWebSiteUrl' */ 242 public static final String PROGRAM_WEBSITE_URL = "programWebSiteUrl"; 243 244 /** Constants for attribute 'attachments' */ 245 public static final String ATTACHMENTS = "attachments"; 246 247 /** Constants for attribute 'attachments/attachment' */ 248 public static final String ATTACHMENTS_ATTACHMENT = "attachment"; 249 250 /** Constants for attribute 'attachments/attachment-text' */ 251 public static final String ATTACHMENTS_ATTACHMENT_TEXT = "attachment-text"; 252 253 /** Constants for attribute 'numberOfStudents' */ 254 public static final String NUMBER_OF_STUDENTS = "numberOfStudents"; 255 256 /** Constants for attribute 'successRate' */ 257 public static final String SUCCESSRATE = "successRate"; 258 259 /** Constants for attribute 'reorientation' */ 260 public static final String REORIENTATION = "reorientation"; 261 262 /** Constants for attribute 'keywords' */ 263 public static final String KEYWORDS = "keywords"; 264 265 /** Constants for attribute 'educationEntryLevel' */ 266 public static final String EDUCATION_ENTRY_LEVEL = "educationEntryLevel"; 267 268 /** Constants for attribute 'mandatoryEntryLevel' */ 269 public static final String MANDATORY_ENTRY_LEVEL = "mandatoryEntryLevel"; 270 271 /** Constants for attribute 'programField' */ 272 public static final String PROGRAM_FIELD = "programField"; 273 274 /** Constants for attribute 'availableCertification' */ 275 public static final String AVAILABLE_CERTIFICATION = "availableCertification"; 276 277 /** Constants for attribute 'disciplines' */ 278 public static final String DISCIPLINES = "disciplines"; 279 280 /** Constants for attribute 'sectors' */ 281 public static final String SECTORS = "sectors"; 282 283 /** Constants for attribute 'internshipOpen' */ 284 public static final String INTERNSHIP_OPEN = "internshipOpen"; 285 286 /** Constants for attribute 'internshipDescription' */ 287 public static final String INTERNSHIP_DESCRIPTION = "internshipDescription"; 288 289 /** Constants for attribute 'internshipDescription/title' */ 290 public static final String INTERNSHIP_DESCRIPTION_TITLE = "title"; 291 292 /** Constants for attribute 'internshipDescription/duration' */ 293 public static final String INTERNSHIP_DESCRIPTION_DURATION = "duration"; 294 295 /** Constants for attribute 'internshipDescription/period' */ 296 public static final String INTERNSHIP_DESCRIPTION_PERIOD = "period"; 297 298 /** Constants for attribute 'internshipDescription/kind' */ 299 public static final String INTERNSHIP_DESCRIPTION_KIND = "kind"; 300 301 /** Constants for attribute 'apprenticeshipOpen' */ 302 public static final String APPRENTICESHIP_OPEN = "apprenticeshipOpen"; 303 304 /** Constants for attribute 'apprenticeshipPeriod' */ 305 public static final String APPRENTICESHIP_PERIOD = "apprenticeshipPeriod"; 306 307 /** Constants for attribute 'apprenticeshipContract' */ 308 public static final String APPRENTICESHIP_CONTRACT = "apprenticeshipContract"; 309 310 /** Constants for attribute 'internationalEducation' */ 311 public static final String INTERNATIONAL_EDUCATION = "internationalEducation"; 312 313 /** Constants for attribute 'internationalDimension' */ 314 public static final String INTERNATIONAL_DIMENSION = "internationalDimension"; 315 316 /** Constants for attribute 'geoCode' */ 317 public static final String GEOCODE = "geoCode"; 318 319 /** Constants for attribute 'otherPartners' */ 320 public static final String OTHER_PARTNERS = "otherPartners"; 321 322 /** Constants for attribute 'otherPartners' */ 323 public static final String OTHER_CONTACT = "otherContact"; 324 325 /** Constants for attribute 'campus' */ 326 public static final String CAMPUS = "campus"; 327 328 /** Constants for attribute 'foreignPlace' */ 329 public static final String FOREIGN_PLACE = "foreignPlace"; 330 331 /** Constants for attribute 'inscription' */ 332 public static final String INSCRIPTION = "inscription"; 333 334 /** Constants for attribute 'furtherStudyPrograms' */ 335 public static final String FURTHER_STUDY_PROGRAMS = "furtherStudyPrograms"; 336 337 /** 338 * References 339 */ 340 341 /** Constants for attribute 'contacts' */ 342 public static final String CONTACTS = "contacts"; 343 344 /** Constants for attribute 'contacts/role' */ 345 public static final String CONTACTS_ROLE = "role"; 346 347 /** Constants for attribute 'contacts/persons' */ 348 public static final String CONTACTS_PERSONS = "persons"; 349 350 private String _contextPath; 351 352 private List<EducationalPath> _currentEducationalPaths; 353 354 // ------------------------------------------------// 355 // 356 // PROGRAM METHODS 357 // 358 // -----------------------------------------------// 359 /** 360 * Constructor 361 * @param node The JCR node 362 * @param parentPath The parent path 363 * @param factory The factory 364 */ 365 public AbstractProgram(Node node, String parentPath, F factory) 366 { 367 super(node, parentPath, factory); 368 } 369 370 @Override 371 public void remove() throws AmetysRepositoryException, RepositoryIntegrityViolationException 372 { 373 AmetysObjectIterable<RemovableAmetysObject> children = this.getChildren(); 374 375 for (RemovableAmetysObject child : children) 376 { 377 child.remove(); 378 } 379 380 super.remove(); 381 } 382 383 // --------------------------------------------------------------------------------------// 384 // CONTEXT 385 // --------------------------------------------------------------------------------------// 386 387 // Méthodes utilisées lors du parcours d'une maquette uniquement, afin de contextualiser l'élément 388 // A ne pas utiliser n'importe ou ni n'importe comment 389 390 /** 391 * Set the parent path for links and breadcrumb 392 * @param path the parent path 393 */ 394 public void setContextPath (String path) 395 { 396 _contextPath = path; 397 } 398 399 /** 400 * Get the parent path. Can be null. 401 * @return the parent path 402 */ 403 public String getContextPath () 404 { 405 return _contextPath; 406 } 407 408 /** 409 * Set the current educational path of this abstract program 410 * @param paths the current educational path 411 */ 412 public void setCurrentEducationalPaths(List<EducationalPath> paths) 413 { 414 _currentEducationalPaths = paths; 415 } 416 417 /** 418 * Get the current educational path of this abstract program 419 * @return the current educational path 420 */ 421 public List<EducationalPath> getCurrentEducationalPaths() 422 { 423 return _currentEducationalPaths; 424 } 425 426 // --------------------------------------------------------------------------------------// 427 // CONTACTS 428 // --------------------------------------------------------------------------------------// 429 430 /** 431 * Return the list of Persons in charge binded to this program 432 * @return a list of roles and UUID 433 */ 434 public Set<String> getContacts() 435 { 436 Set<String> contactIds = new HashSet<>(); 437 438 ModelAwareRepeater contacts = getRepeater(CONTACTS); 439 if (contacts != null) 440 { 441 for (ModelAwareRepeaterEntry contactEntry : contacts.getEntries()) 442 { 443 // Remove empty values 444 contactIds.addAll(ContentDataHelper.getContentIdsStreamFromMultipleContentData(contactEntry, CONTACTS_PERSONS) 445 .filter(contentId -> !contentId.isEmpty()) 446 .collect(Collectors.toSet())); 447 } 448 } 449 450 return contactIds; 451 } 452 453 /** 454 * Return the list of Persons in charge binded to this program 455 * @return a list of roles and UUID 456 */ 457 public Map<String, List<String>> getContactsByRole() 458 { 459 Map<String, List<String>> contactsByRole = new LinkedHashMap<>(); 460 461 ModelAwareRepeater contacts = getRepeater(CONTACTS); 462 if (contacts != null) 463 { 464 for (ModelAwareRepeaterEntry contactEntry : contacts.getEntries()) 465 { 466 // Remove empty values 467 List<String> persons = ContentDataHelper.getContentIdsStreamFromMultipleContentData(contactEntry, CONTACTS_PERSONS) 468 .filter(contentId -> !contentId.isEmpty()) 469 .collect(Collectors.toList()); 470 if (!persons.isEmpty()) 471 { 472 String role = ContentDataHelper.getContentIdFromContentData(contactEntry, CONTACTS_ROLE); 473 List<String> personList = contactsByRole.getOrDefault(role, new ArrayList<>()); 474 personList.addAll(persons); 475 contactsByRole.put(role, personList); 476 } 477 } 478 } 479 480 return contactsByRole; 481 } 482 483 // --------------------------------------------------------------------------------------// 484 // GETTERS AND SETTERS 485 // --------------------------------------------------------------------------------------// 486 /** 487 * Returns <code>true</code> if the {@link AbstractProgram} is certified 488 * @return <code>true</code> if certified or default value (true in the kernel) if not defined 489 */ 490 public boolean isCertified() 491 { 492 return getValue(CERTIFIED, true, true); 493 } 494 495 /** 496 * Get the domain 497 * @return the domain or an empty array 498 */ 499 public String[] getDomain() 500 { 501 try 502 { 503 ElementDefinition definition = (ElementDefinition) getDefinition(DOMAIN); 504 if (definition.isMultiple()) 505 { 506 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, DOMAIN); 507 } 508 else 509 { 510 return new String[] {ContentDataHelper.getContentIdFromContentData(this, DOMAIN)}; 511 } 512 } 513 catch (UndefinedItemPathException e) 514 { 515 return null; // this attribute is not part of model 516 } 517 518 } 519 520 /** 521 * Get the education presentation 522 * @return the education presentation or null if not set 523 */ 524 public RichText getPresentation() 525 { 526 try 527 { 528 return getValue(PRESENTATION); 529 } 530 catch (UndefinedItemPathException e) 531 { 532 return null; // this attribute is not part of model 533 } 534 } 535 536 /** 537 * Get the education objectives 538 * @return the education objectives or null if not set 539 */ 540 public RichText getObjectives() 541 { 542 try 543 { 544 return getValue(OBJECTIVES); 545 } 546 catch (UndefinedItemPathException e) 547 { 548 return null; // this attribute is not part of model 549 } 550 } 551 552 /** 553 * Get the education qualification 554 * @return the education qualification or null if not set 555 */ 556 public RichText getQualification() 557 { 558 try 559 { 560 return getValue(QUALIFICATION); 561 } 562 catch (UndefinedItemPathException e) 563 { 564 return null; // this attribute is not part of model 565 } 566 } 567 568 /** 569 * Get the education organization 570 * @return the education organization or null if not set 571 */ 572 public RichText getTeachingOrganization() 573 { 574 try 575 { 576 return getValue(TEACHING_ORGANIZATION); 577 } 578 catch (UndefinedItemPathException e) 579 { 580 return null; // this attribute is not part of model 581 } 582 } 583 584 /** 585 * Get the apprenticeship modalities 586 * @return the apprenticeship modalities or null if not set 587 */ 588 public RichText getApprenticeshipModalities() 589 { 590 try 591 { 592 return getValue(APPRENTICESHIP_MODALITIES); 593 } 594 catch (UndefinedItemPathException e) 595 { 596 return null; // this attribute is not part of model 597 } 598 } 599 600 /** 601 * Get the access conditions 602 * @return the access conditions or null if not set 603 */ 604 public RichText getAccessCondition() 605 { 606 try 607 { 608 return getValue(ACCESS_CONDITION); 609 } 610 catch (UndefinedItemPathException e) 611 { 612 return null; // this attribute is not part of model 613 } 614 } 615 616 /** 617 * Get the education requirements 618 * @return the education requirements or null if not set 619 */ 620 public RichText getNeededPrerequisite() 621 { 622 try 623 { 624 return getValue(NEEDED_PREREQUISITE); 625 } 626 catch (UndefinedItemPathException e) 627 { 628 return null; // this attribute is not part of model 629 } 630 } 631 632 /** 633 * Get the education recommended prerequisite 634 * @return the education recommended prerequisite or null if not set 635 */ 636 public RichText getRecommendedPrerequisite() 637 { 638 try 639 { 640 return getValue(RECOMMENDED_PREREQUISITE); 641 } 642 catch (UndefinedItemPathException e) 643 { 644 return null; // this attribute is not part of model 645 } 646 } 647 648 /** 649 * Get the education expected results 650 * @return the education expected results or null if not set 651 */ 652 public RichText getExpectedResults() 653 { 654 try 655 { 656 return getValue(EXPECTED_RESULTS); 657 } 658 catch (UndefinedItemPathException e) 659 { 660 return null; // this attribute is not part of model 661 } 662 } 663 664 /** 665 * Get the education further study 666 * @return the education further study or null if not set 667 */ 668 public RichText getFurtherStudy() 669 { 670 try 671 { 672 return getValue(FURTHER_STUDY); 673 } 674 catch (UndefinedItemPathException e) 675 { 676 return null; // this attribute is not part of model 677 } 678 } 679 680 /** 681 * Get the education study abroard 682 * @return the education study abroard or null if not set 683 */ 684 public RichText getStudyAbroad() 685 { 686 try 687 { 688 return getValue(STUDY_ABROAD); 689 } 690 catch (UndefinedItemPathException e) 691 { 692 return null; // this attribute is not part of model 693 } 694 } 695 696 /** 697 * Get the education target 698 * @return the education target or null if not set 699 */ 700 public RichText getTargetGroup() 701 { 702 try 703 { 704 return getValue(TARGET_GROUP); 705 } 706 catch (UndefinedItemPathException e) 707 { 708 return null; // this attribute is not part of model 709 } 710 } 711 712 /** 713 * Get the job opportunities 714 * @return the job opportunities or null if not set 715 */ 716 public RichText getJobOpportunities() 717 { 718 try 719 { 720 return getValue(JOB_OPPORTUNITIES); 721 } 722 catch (UndefinedItemPathException e) 723 { 724 return null; // this attribute is not part of model 725 } 726 } 727 728 /** 729 * Get the training strategy 730 * @return the training strategy or null if not set 731 */ 732 public RichText getTrainingStrategy() 733 { 734 try 735 { 736 return getValue(TRAINING_STRATEGY); 737 } 738 catch (UndefinedItemPathException e) 739 { 740 return null; // this attribute is not part of model 741 } 742 } 743 744 /** 745 * Get acknowledgments 746 * @return acknowledgments or null if not set 747 */ 748 public RichText getKnowledgeCheck() 749 { 750 try 751 { 752 return getValue(KNOWLEDGE_CHECK); 753 } 754 catch (UndefinedItemPathException e) 755 { 756 return null; // this attribute is not part of model 757 } 758 } 759 760 /** 761 * Get universal adjustment 762 * @return universal adjustment or null if not set 763 */ 764 public RichText getUniversalAdjustment() 765 { 766 try 767 { 768 return getValue(UNIVERSAL_ADJUSTMENT); 769 } 770 catch (UndefinedItemPathException e) 771 { 772 return null; // this attribute is not part of model 773 } 774 } 775 776 /** 777 * Is certifying 778 * @return <code>true</code> if the progam is certifying 779 */ 780 public boolean isCertifying() 781 { 782 try 783 { 784 return getValue(CERTIFYING, false, false); 785 } 786 catch (UndefinedItemPathException e) 787 { 788 return false; // this attribute is not part of model 789 } 790 } 791 792 /** 793 * Get the additional informations 794 * @return the additional informations or null if not set 795 */ 796 public RichText getAdditionalInformations() 797 { 798 try 799 { 800 return getValue(ADDITIONNAL_INFORMATIONS); 801 } 802 catch (UndefinedItemPathException e) 803 { 804 return null; // this attribute is not part of model 805 } 806 } 807 808 /** 809 * Get the education level 810 * @return the education level or null 811 */ 812 public String getEducationLevel() 813 { 814 try 815 { 816 return ContentDataHelper.getContentIdFromContentData(this, LEVEL); 817 } 818 catch (UndefinedItemPathException e) 819 { 820 return null; // this attribute is not part of model 821 } 822 } 823 824 /** 825 * Get the RNCP code 826 * @return the RNCP code 827 */ 828 public String[] getRncpCode() 829 { 830 try 831 { 832 return getValue(RNCP_CODE, false, ArrayUtils.EMPTY_STRING_ARRAY); 833 } 834 catch (UndefinedItemPathException e) 835 { 836 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 837 } 838 } 839 840 /** 841 * Get the RNCP level 842 * @return the RNCP level 843 */ 844 public String[] getRncpLevel() 845 { 846 try 847 { 848 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, RNCP_LEVEL); 849 } 850 catch (UndefinedItemPathException e) 851 { 852 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 853 } 854 } 855 856 /** 857 * Get the SISE code 858 * @return the SISE code 859 */ 860 public String[] getSiseCode() 861 { 862 try 863 { 864 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, SISE_CODE); 865 } 866 catch (UndefinedItemPathException e) 867 { 868 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 869 } 870 } 871 872 /** 873 * Get the CITE97 code 874 * @return the CITE97 code 875 */ 876 public String[] getCite97Code() 877 { 878 try 879 { 880 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, CITE97_CODE); 881 } 882 catch (UndefinedItemPathException e) 883 { 884 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 885 } 886 } 887 888 /** 889 * Get the DGESIP code 890 * @return the DGESIP code 891 */ 892 public String[] getDGESIPCode() 893 { 894 try 895 { 896 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, DGESIP_CODE); 897 } 898 catch (UndefinedItemPathException e) 899 { 900 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 901 } 902 } 903 904 /** 905 * Get the Erasmus code 906 * @return the Erasmus code 907 */ 908 public String[] getErasmusCode() 909 { 910 try 911 { 912 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, ERASMUS_CODE); 913 } 914 catch (UndefinedItemPathException e) 915 { 916 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 917 } 918 } 919 920 /** 921 * Get the FORMACODE 922 * @return the FORMACODE 923 */ 924 public String[] getFORMACODE() 925 { 926 try 927 { 928 return getValue(FORMACODE, false, ArrayUtils.EMPTY_STRING_ARRAY); 929 } 930 catch (UndefinedItemPathException e) 931 { 932 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 933 } 934 } 935 936 /** 937 * Get the ROME code 938 * @return the ROME code 939 */ 940 public String[] getRomeCode() 941 { 942 try 943 { 944 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, ROME_CODE); 945 } 946 catch (UndefinedItemPathException e) 947 { 948 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 949 } 950 } 951 952 /** 953 * Get the FAP code 954 * @return the FAP code 955 */ 956 public String[] getFapCode() 957 { 958 try 959 { 960 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, FAP_CODE); 961 } 962 catch (UndefinedItemPathException e) 963 { 964 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 965 } 966 } 967 968 /** 969 * Get the NSF code 970 * @return the NSF code 971 */ 972 public String getNSFCode() 973 { 974 try 975 { 976 return ContentDataHelper.getContentIdFromContentData(this, NSF_CODE); 977 } 978 catch (UndefinedItemPathException e) 979 { 980 return null; // this attribute is not part of model 981 } 982 } 983 984 /** 985 * Get the mention 986 * @return the mention or null 987 */ 988 public String getMention() 989 { 990 try 991 { 992 return ContentDataHelper.getContentIdFromContentData(this, MENTION); 993 } 994 catch (UndefinedItemPathException e) 995 { 996 return null; // this attribute is not part of model 997 } 998 } 999 1000 /** 1001 * Get the speciality 1002 * @return the speciality or null 1003 */ 1004 public String getSpeciality() 1005 { 1006 try 1007 { 1008 return getValue(SPECIALITY, false, StringUtils.EMPTY); 1009 } 1010 catch (UndefinedItemPathException e) 1011 { 1012 return null; // this attribute is not part of model 1013 } 1014 } 1015 1016 /** 1017 * Get the org units 1018 * @return the org units 1019 */ 1020 public String[] getJointOrgUnit() 1021 { 1022 try 1023 { 1024 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, JOINT_ORGUNIT); 1025 } 1026 catch (UndefinedItemPathException e) 1027 { 1028 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1029 } 1030 } 1031 1032 /** 1033 * Get the places 1034 * @return the places as an Array of String 1035 */ 1036 public String[] getPlace() 1037 { 1038 try 1039 { 1040 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, PLACE); 1041 } 1042 catch (UndefinedItemPathException e) 1043 { 1044 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1045 } 1046 } 1047 1048 /** 1049 * Get the list of websites 1050 * @return the list of website or an empty list 1051 */ 1052 public Set<WebsiteLink> getWebsiteLinks() 1053 { 1054 Set<WebsiteLink> websites = new HashSet<>(); 1055 1056 try 1057 { 1058 ModelAwareRepeater webSites = getRepeater(PROGRAM_WEBSITE); 1059 if (webSites != null) 1060 { 1061 for (ModelAwareRepeaterEntry entry : webSites.getEntries()) 1062 { 1063 WebsiteLink website = new WebsiteLink(entry.getValue(PROGRAM_WEBSITE_URL, false, StringUtils.EMPTY), entry.getValue(PROGRAM_WEBSITE_LABEL, false, StringUtils.EMPTY)); 1064 websites.add(website); 1065 } 1066 } 1067 } 1068 catch (UndefinedItemPathException e) 1069 { 1070 // this attribute is not part of model 1071 } 1072 1073 return websites; 1074 } 1075 1076 /** 1077 * Get the ECTS credits 1078 * @return the ECTS credits 1079 */ 1080 public String getEcts() 1081 { 1082 try 1083 { 1084 return ContentDataHelper.getContentIdFromContentData(this, ECTS); 1085 } 1086 catch (UndefinedItemPathException e) 1087 { 1088 return null; // this attribute is not part of model 1089 } 1090 } 1091 1092 /** 1093 * Get the kind of education 1094 * @return the kind of education or null 1095 */ 1096 public String getEducationKind() 1097 { 1098 try 1099 { 1100 return ContentDataHelper.getContentIdFromContentData(this, EDUCATION_KIND); 1101 } 1102 catch (UndefinedItemPathException e) 1103 { 1104 return null; // this attribute is not part of model 1105 } 1106 } 1107 1108 /** 1109 * Get the duration 1110 * @return the duration 1111 */ 1112 public String getDuration() 1113 { 1114 try 1115 { 1116 return ContentDataHelper.getContentIdFromContentData(this, DURATION); 1117 } 1118 catch (UndefinedItemPathException e) 1119 { 1120 return null; // this attribute is not part of model 1121 } 1122 } 1123 1124 /** 1125 * Get the education languages 1126 * @return the education languages 1127 */ 1128 public String[] getEducationLanguage() 1129 { 1130 try 1131 { 1132 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, EDUC_LANGUAGE); 1133 } 1134 catch (UndefinedItemPathException e) 1135 { 1136 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1137 } 1138 } 1139 1140 /** 1141 * Get the effectives 1142 * @return the effectives 1143 */ 1144 public RichText getEffectives() 1145 { 1146 try 1147 { 1148 return getValue(NUMBER_OF_STUDENTS); 1149 } 1150 catch (UndefinedItemPathException e) 1151 { 1152 return null; // this attribute is not part of model 1153 } 1154 } 1155 1156 /** 1157 * Get the SuccessRate 1158 * @return the SuccessRate 1159 */ 1160 public String getSuccessRate() 1161 { 1162 try 1163 { 1164 return getValue(SUCCESSRATE, false, StringUtils.EMPTY); 1165 } 1166 catch (UndefinedItemPathException e) 1167 { 1168 return null; // this attribute is not part of model 1169 } 1170 } 1171 1172 /** 1173 * Get the expenses 1174 * @return the expenses 1175 */ 1176 public RichText getExpenses() 1177 { 1178 try 1179 { 1180 return getValue(EXPENSES); 1181 } 1182 catch (UndefinedItemPathException e) 1183 { 1184 return null; // this attribute is not part of model 1185 } 1186 } 1187 1188 /** 1189 * Get the form of teaching organization 1190 * @return the form of teaching organization 1191 */ 1192 public String[] getFormOfTeachingOrgs() 1193 { 1194 try 1195 { 1196 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, FORM_OF_TEACHING_ORG); 1197 } 1198 catch (UndefinedItemPathException e) 1199 { 1200 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1201 } 1202 } 1203 1204 /** 1205 * Get the REORIENTATION 1206 * @return RichText 1207 */ 1208 public RichText getReorientation() 1209 { 1210 try 1211 { 1212 return getValue(REORIENTATION); 1213 } 1214 catch (UndefinedItemPathException e) 1215 { 1216 return null; // this attribute is not part of model 1217 } 1218 } 1219 1220 /** 1221 * Get the distance learning 1222 * @return the distance learning or null 1223 */ 1224 public String getDistanceLearning() 1225 { 1226 try 1227 { 1228 return ContentDataHelper.getContentIdFromContentData(this, DISTANCE_LEARNING); 1229 } 1230 catch (UndefinedItemPathException e) 1231 { 1232 return null; // this attribute is not part of model 1233 } 1234 } 1235 1236 /** 1237 * Get the internship 1238 * @return the internship or null 1239 */ 1240 public String getInternship() 1241 { 1242 try 1243 { 1244 return ContentDataHelper.getContentIdFromContentData(this, INTERNSHIP); 1245 } 1246 catch (UndefinedItemPathException e) 1247 { 1248 return null; // this attribute is not part of model 1249 } 1250 } 1251 1252 /** 1253 * Get the internship duration 1254 * @return the internship duration or null 1255 */ 1256 public String getInternshipDuration() 1257 { 1258 try 1259 { 1260 return getValue(INTERNSHIP_DURATION, false, StringUtils.EMPTY); 1261 } 1262 catch (UndefinedItemPathException e) 1263 { 1264 return null; // this attribute is not part of model 1265 } 1266 } 1267 1268 /** 1269 * Get the internship abroad 1270 * @return the internship abroad or null 1271 */ 1272 public String getInternshipAbroad() 1273 { 1274 try 1275 { 1276 return ContentDataHelper.getContentIdFromContentData(this, INTERNSHIP_ABROAD); 1277 } 1278 catch (UndefinedItemPathException e) 1279 { 1280 return null; // this attribute is not part of model 1281 } 1282 } 1283 1284 /** 1285 * Get the internship abroad duration 1286 * @return the internship abroad duration or null 1287 */ 1288 public String getAbroadInternshipDuration() 1289 { 1290 try 1291 { 1292 return getValue(INTERNSHIP_ABROAD_DURATION, false, StringUtils.EMPTY); 1293 } 1294 catch (UndefinedItemPathException e) 1295 { 1296 return null; // this attribute is not part of model 1297 } 1298 } 1299 1300 /** 1301 * Get the registration start date. 1302 * @return The registration start date, can be null. 1303 */ 1304 public LocalDate getRegistrationStart() 1305 { 1306 try 1307 { 1308 return getValue(REGISTRATION_START); 1309 } 1310 catch (UndefinedItemPathException e) 1311 { 1312 return null; // this attribute is not part of model 1313 } 1314 } 1315 1316 /** 1317 * Get the registration deadline date. 1318 * @return The registration deadline date, can be null. 1319 */ 1320 public LocalDate getRegistrationDeadline() 1321 { 1322 try 1323 { 1324 return getValue(REGISTRATION_DEADLINE); 1325 } 1326 catch (UndefinedItemPathException e) 1327 { 1328 return null; // this attribute is not part of model 1329 } 1330 } 1331 1332 /** 1333 * Get the teaching start date. 1334 * @return The teaching start date, can be null. 1335 */ 1336 public LocalDate getTeachingStart() 1337 { 1338 try 1339 { 1340 return getValue(TEACHING_START); 1341 } 1342 catch (UndefinedItemPathException e) 1343 { 1344 return null; // this attribute is not part of model 1345 } 1346 } 1347 1348 /** 1349 * Get the teaching end date. 1350 * @return The teaching end date, can be null. 1351 */ 1352 public LocalDate getTeachingEnd() 1353 { 1354 try 1355 { 1356 return getValue(TEACHING_END); 1357 } 1358 catch (UndefinedItemPathException e) 1359 { 1360 return null; // this attribute is not part of model 1361 } 1362 } 1363 1364 /** 1365 * Get the keywords 1366 * @return the keywords 1367 */ 1368 public String[] getKeywords() 1369 { 1370 try 1371 { 1372 return getValue(KEYWORDS, false, ArrayUtils.EMPTY_STRING_ARRAY); 1373 } 1374 catch (UndefinedItemPathException e) 1375 { 1376 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1377 } 1378 } 1379 1380 /** 1381 * Get the education level entry 1382 * @return the education level entry 1383 */ 1384 public String[] getEducationLevelEntry() 1385 { 1386 try 1387 { 1388 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, EDUCATION_ENTRY_LEVEL); 1389 } 1390 catch (UndefinedItemPathException e) 1391 { 1392 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1393 } 1394 } 1395 1396 /** 1397 * Is the entry level mandatory 1398 * @return <code>true</code> if the entry level is mandatory 1399 */ 1400 public boolean isMandatoryEntryLevel() 1401 { 1402 try 1403 { 1404 return getValue(MANDATORY_ENTRY_LEVEL, false, false); 1405 } 1406 catch (UndefinedItemPathException e) 1407 { 1408 return false; // this attribute is not part of model 1409 } 1410 } 1411 1412 /** 1413 * Get the program fields 1414 * @return the program fields 1415 */ 1416 public String[] getProgramField() 1417 { 1418 try 1419 { 1420 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, PROGRAM_FIELD); 1421 } 1422 catch (UndefinedItemPathException e) 1423 { 1424 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1425 } 1426 } 1427 1428 /** 1429 * Get the available certifications 1430 * @return the available certifications 1431 */ 1432 public String[] getAvailableCertification() 1433 { 1434 try 1435 { 1436 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, AVAILABLE_CERTIFICATION); 1437 } 1438 catch (UndefinedItemPathException e) 1439 { 1440 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1441 } 1442 } 1443 1444 /** 1445 * Get the disciplines 1446 * @return the disciplines 1447 */ 1448 public String[] getDisciplines() 1449 { 1450 try 1451 { 1452 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, DISCIPLINES); 1453 } 1454 catch (UndefinedItemPathException e) 1455 { 1456 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1457 } 1458 } 1459 1460 /** 1461 * Get the required skills 1462 * @return the required skills 1463 */ 1464 public String[] getRequiredSkills() 1465 { 1466 try 1467 { 1468 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, REQUIRED_SKILLS); 1469 } 1470 catch (UndefinedItemPathException e) 1471 { 1472 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1473 } 1474 } 1475 1476 /** 1477 * Get the sectors 1478 * @return the sectors 1479 */ 1480 public String[] getSectors() 1481 { 1482 try 1483 { 1484 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, SECTORS); 1485 } 1486 catch (UndefinedItemPathException e) 1487 { 1488 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1489 } 1490 } 1491 1492 /** 1493 * Is intership open 1494 * @return <code>true</code> if internship is open 1495 */ 1496 public boolean isInternshipOpen() 1497 { 1498 try 1499 { 1500 return getValue(INTERNSHIP_OPEN, false, false); 1501 } 1502 catch (UndefinedItemPathException e) 1503 { 1504 return false; // this attribute is not part of model 1505 } 1506 } 1507 1508 /** 1509 * Is apprenticeship open 1510 * @return <code>true</code> if apprenticeship is open 1511 */ 1512 public boolean isApprenticeshipOpen() 1513 { 1514 try 1515 { 1516 return getValue(APPRENTICESHIP_OPEN, false, false); 1517 } 1518 catch (UndefinedItemPathException e) 1519 { 1520 return false; // this attribute is not part of model 1521 } 1522 } 1523 1524 /** 1525 * Get the apprenticeship period description 1526 * @return the apprenticeship period 1527 */ 1528 public RichText getApprenticeshipPeriod() 1529 { 1530 try 1531 { 1532 return getValue(APPRENTICESHIP_PERIOD); 1533 } 1534 catch (UndefinedItemPathException e) 1535 { 1536 return null; // this attribute is not part of model 1537 } 1538 } 1539 1540 /** 1541 * Get the available apprenticeship contracts 1542 * @return the apprenticeship contracts 1543 */ 1544 public String[] getApprenticeshipContract() 1545 { 1546 try 1547 { 1548 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, APPRENTICESHIP_CONTRACT); 1549 } 1550 catch (UndefinedItemPathException e) 1551 { 1552 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1553 } 1554 } 1555 1556 /** 1557 * Get the international education 1558 * @return the international education 1559 */ 1560 public String[] getInternationalEducation() 1561 { 1562 try 1563 { 1564 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, INTERNATIONAL_EDUCATION); 1565 } 1566 catch (UndefinedItemPathException e) 1567 { 1568 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1569 } 1570 } 1571 1572 /** 1573 * Get the international dimension 1574 * @return the international dimension 1575 */ 1576 public RichText getInternationalDimension() 1577 { 1578 try 1579 { 1580 return getValue(INTERNATIONAL_DIMENSION); 1581 } 1582 catch (UndefinedItemPathException e) 1583 { 1584 return null; // this attribute is not part of model 1585 } 1586 } 1587 1588 /** 1589 * Get the geocode latitude and longitude 1590 * @return the geocode 1591 */ 1592 public Geocode getGeocode() 1593 { 1594 try 1595 { 1596 return getValue(GEOCODE); 1597 } 1598 catch (UndefinedItemPathException e) 1599 { 1600 return null; // this attribute is not part of model 1601 } 1602 } 1603 1604 /** 1605 * Get the other partners 1606 * @return the other partners 1607 */ 1608 public RichText getOtherPartners() 1609 { 1610 try 1611 { 1612 return getValue(OTHER_PARTNERS); 1613 } 1614 catch (UndefinedItemPathException e) 1615 { 1616 return null; // this attribute is not part of model 1617 } 1618 } 1619 1620 /** 1621 * Get the campus 1622 * @return the campus 1623 */ 1624 public String[] getCampus() 1625 { 1626 try 1627 { 1628 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, CAMPUS); 1629 } 1630 catch (UndefinedItemPathException e) 1631 { 1632 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1633 } 1634 } 1635 1636 /** 1637 * Get the foreign places 1638 * @return the foreign places 1639 */ 1640 public String[] getForeignPlace() 1641 { 1642 try 1643 { 1644 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, FOREIGN_PLACE); 1645 } 1646 catch (UndefinedItemPathException e) 1647 { 1648 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1649 } 1650 } 1651 1652 /** 1653 * Get the inscription 1654 * @return the inscription 1655 */ 1656 public RichText getInscription() 1657 { 1658 try 1659 { 1660 return getValue(INSCRIPTION); 1661 } 1662 catch (UndefinedItemPathException e) 1663 { 1664 return null; // this attribute is not part of model 1665 } 1666 } 1667 1668 /** 1669 * Get the further study programs 1670 * @return the further study programs 1671 */ 1672 public String[] getFurtherStudyPrograms() 1673 { 1674 try 1675 { 1676 return ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, FURTHER_STUDY_PROGRAMS); 1677 } 1678 catch (UndefinedItemPathException e) 1679 { 1680 return ArrayUtils.EMPTY_STRING_ARRAY; // this attribute is not part of model 1681 } 1682 } 1683 1684 // --------------------------------------------------------------------------------------// 1685 // Methods of CourseListContainer 1686 // --------------------------------------------------------------------------------------// 1687 @Override 1688 public List<CourseList> getCourseLists() 1689 { 1690 return Arrays.stream(getValue(CHILD_PROGRAM_PARTS, false, new ContentValue[0])) 1691 .map(ContentValue::getContentIfExists) 1692 .flatMap(Optional::stream) 1693 // This cast is not checked because an exception must be thrown if the retrieved content is not a program part 1694 // TODO: change this behavior to throw our own exception and not a CassCastException 1695 .map(ProgramPart.class::cast) 1696 // Program parts that are not course lists are simply ignored 1697 .filter(CourseList.class::isInstance) 1698 .map(CourseList.class::cast) 1699 .collect(Collectors.toList()); 1700 } 1701 1702 @Override 1703 public boolean containsCourseList(String clId) 1704 { 1705 return ArrayUtils.contains(ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, CHILD_PROGRAM_PARTS), clId); 1706 } 1707 1708 @Override 1709 public boolean hasCourseLists() 1710 { 1711 return !getCourseLists().isEmpty(); 1712 } 1713 1714 // --------------------------------------------------------------------------------------// 1715 // CDMfr 1716 // --------------------------------------------------------------------------------------// 1717 @Override 1718 protected String getCDMType() 1719 { 1720 return "PR"; 1721 } 1722 1723 /** 1724 * Returns the surrounding tag name in the CDM-fr representation. 1725 * @return the surrounding tag name 1726 */ 1727 public abstract String getCDMTagName(); 1728}