001/* 002 * Copyright 2015 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; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Optional; 021import java.util.Set; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.service.Serviceable; 026import org.apache.commons.lang3.StringUtils; 027import org.w3c.dom.Node; 028import org.w3c.dom.NodeList; 029 030import org.ametys.cms.repository.Content; 031import org.ametys.core.util.dom.AmetysNodeList; 032import org.ametys.odf.enumeration.OdfReferenceTableEntry; 033import org.ametys.odf.enumeration.OdfReferenceTableHelper; 034import org.ametys.odf.orgunit.RootOrgUnitProvider; 035import org.ametys.odf.program.AbstractProgram; 036import org.ametys.odf.program.Program; 037import org.ametys.odf.program.SubProgram; 038import org.ametys.odf.xslt.OdfReferenceTableElement; 039import org.ametys.odf.xslt.ProgramElement; 040import org.ametys.odf.xslt.SubProgramElement; 041import org.ametys.plugins.repository.AmetysObjectResolver; 042import org.ametys.plugins.repository.AmetysRepositoryException; 043import org.ametys.runtime.config.Config; 044 045/** 046 * Helper component to be used from XSL stylesheets. 047 */ 048public class OdfXSLTHelper implements Serviceable 049{ 050 /** The ODF reference helper */ 051 protected static OdfReferenceTableHelper _odfRefTableHelper; 052 /** The Ametys resolver */ 053 protected static AmetysObjectResolver _ametysObjectResolver; 054 /** The orgunit root provider */ 055 protected static RootOrgUnitProvider _rootOrgUnitProvider; 056 057 @Override 058 public void service(ServiceManager smanager) throws ServiceException 059 { 060 _odfRefTableHelper = (OdfReferenceTableHelper) smanager.lookup(OdfReferenceTableHelper.ROLE); 061 _ametysObjectResolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 062 _rootOrgUnitProvider = (RootOrgUnitProvider) smanager.lookup(RootOrgUnitProvider.ROLE); 063 } 064 065 /** 066 * Get the label associated with the degree key 067 * @param cdmValue The code of degree 068 * @return The label of degree or code if not found 069 */ 070 public static String degreeLabel (String cdmValue) 071 { 072 return degreeLabel(cdmValue, Config.getInstance().getValue("odf.programs.lang")); 073 } 074 075 /** 076 * Get the code associated with the given reference table's entry 077 * @param tableRefEntryId The id of entry 078 * @return the code or <code>null</code> if not found 079 */ 080 public static String getCode (String tableRefEntryId) 081 { 082 try 083 { 084 Content content = _ametysObjectResolver.resolveById(tableRefEntryId); 085 return content.getValue(OdfReferenceTableEntry.CODE); 086 } 087 catch (AmetysRepositoryException e) 088 { 089 return null; 090 } 091 } 092 093 /** 094 * Get the id of reference table's entry 095 * @param tableRefId The id of content type 096 * @param code The code 097 * @return the id or <code>null</code> if not found 098 */ 099 public static String getEntryId (String tableRefId, String code) 100 { 101 OdfReferenceTableEntry entry = _odfRefTableHelper.getItemFromCode(tableRefId, code); 102 if (entry != null) 103 { 104 return entry.getId(); 105 } 106 return null; 107 } 108 109 /** 110 * Get the label associated with the degree key 111 * @param cdmValue The cdm value of degree 112 * @param lang The language 113 * @return The label of degree or empty string if not found 114 */ 115 public static String degreeLabel (String cdmValue, String lang) 116 { 117 return Optional 118 .ofNullable(_odfRefTableHelper.getItemFromCDM(OdfReferenceTableHelper.DEGREE, cdmValue)) 119 .map(degree -> degree.getLabel(lang)) 120 .orElse(StringUtils.EMPTY); 121 } 122 123 /** 124 * Get the whole structure of a subprogram, including the structure of child subprograms 125 * @param subprogramId The id of subprogram 126 * @return Node with the subprogram structure 127 */ 128 public static Node getSubProgramStructure (String subprogramId) 129 { 130 SubProgram subProgram = _ametysObjectResolver.resolveById(subprogramId); 131 return new SubProgramElement(subProgram, _ametysObjectResolver); 132 } 133 134 /** 135 * Get the structure of a subprogram, including the structure of child subprograms until the given depth 136 * @param subprogramId The id of subprogram 137 * @param depth Set a positive number to get structure of child subprograms until given depth. Set a negative number to get the whole structure recursively, including the structure of child subprograms. This parameter concerns only subprograms. 138 * @return Node with the subprogram structure 139 */ 140 public static Node getSubProgramStructure (String subprogramId, int depth) 141 { 142 SubProgram subProgram = _ametysObjectResolver.resolveById(subprogramId); 143 return new SubProgramElement(subProgram, depth, null, _ametysObjectResolver); 144 } 145 146 /** 147 * Get the parent program information 148 * @param subprogramId The id of subprogram 149 * @return a node for each program's information 150 */ 151 public static NodeList getParentProgram (String subprogramId) 152 { 153 return getParentProgramStructure(subprogramId, 0); 154 } 155 156 /** 157 * Get the certification label of a {@link AbstractProgram}. 158 * Returns null if the program is not certified. 159 * @param abstractProgramId the id of program or subprogram 160 * @return the certification label 161 */ 162 public static String getCertificationLabel(String abstractProgramId) 163 { 164 AbstractProgram abstractProgram = _ametysObjectResolver.resolveById(abstractProgramId); 165 if (abstractProgram.isCertified()) 166 { 167 String degreeId = null; 168 if (abstractProgram instanceof Program) 169 { 170 degreeId = abstractProgram.getDegree(); 171 } 172 else if (abstractProgram instanceof SubProgram) 173 { 174 // Get degree from parent 175 Set<Program> rootPrograms = abstractProgram.getRootPrograms(); 176 if (rootPrograms.size() > 0) 177 { 178 degreeId = rootPrograms.iterator().next().getDegree(); 179 } 180 } 181 182 if (StringUtils.isNotEmpty(degreeId)) 183 { 184 Content degree = _ametysObjectResolver.resolveById(degreeId); 185 return degree.getValue("certificationLabel"); 186 } 187 } 188 189 return null; 190 } 191 192 /** 193 * Get the program information 194 * @param programId The id of program 195 * @return Node with the program's information 196 */ 197 public static Node getProgram (String programId) 198 { 199 return getProgramStructure(programId, 0); 200 } 201 202 /** 203 * Get the structure of a parent programs, including the structure of child subprograms until the given depth. 204 * @param subprogramId The id of subprogram 205 * @param depth Set a positive number to get structure of child subprograms until given depth. Set a negative number to get the whole structure recursively, including the structure of child subprograms. This parameter concerns only subprograms. 206 * @return a node for each program's structure 207 */ 208 public static NodeList getParentProgramStructure (String subprogramId, int depth) 209 { 210 List<ProgramElement> programs = new ArrayList<>(); 211 212 SubProgram subProgram = _ametysObjectResolver.resolveById(subprogramId); 213 214 Set<Program> rootPrograms = subProgram.getRootPrograms(); 215 if (rootPrograms.size() > 0) 216 { 217 programs.add(new ProgramElement(rootPrograms.iterator().next(), depth, null, _ametysObjectResolver)); 218 } 219 220 return new AmetysNodeList(programs); 221 } 222 223 /** 224 * Get the structure of a program until the given depth. 225 * @param programId The id of program 226 * @param depth Set a positive number to get structure of child subprograms until given depth. Set a negative number to get the whole structure recursively, including the structure of child subprograms. This parameter concerns only subprograms. 227 * @return Node with the program structure 228 */ 229 public static Node getProgramStructure (String programId, int depth) 230 { 231 Program program = _ametysObjectResolver.resolveById(programId); 232 return new ProgramElement(program, depth, null, _ametysObjectResolver); 233 } 234 235 /** 236 * Get the items of a reference table 237 * @param tableRefId the id of reference table 238 * @param lang the language to use for labels 239 * @return the items 240 */ 241 public static Node getTableRefItems(String tableRefId, String lang) 242 { 243 return getTableRefItems(tableRefId, lang, false); 244 } 245 246 /** 247 * Get the items of a reference table 248 * @param tableRefId the id of reference table 249 * @param lang the language to use for labels 250 * @param ordered true to sort items by 'order' attribute 251 * @return the items 252 */ 253 public static Node getTableRefItems(String tableRefId, String lang, boolean ordered) 254 { 255 return new OdfReferenceTableElement(tableRefId, _odfRefTableHelper, lang, ordered); 256 } 257 258 /** 259 * Get the id of root orgunit 260 * @return The id of root 261 */ 262 public static String getRootOrgUnitId() 263 { 264 return _rootOrgUnitProvider.getRootId(); 265 } 266}