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.plugins.odfweb.xslt; 017 018import org.apache.avalon.framework.service.ServiceException; 019import org.apache.avalon.framework.service.ServiceManager; 020import org.apache.commons.lang.StringUtils; 021 022import org.ametys.cms.repository.Content; 023import org.ametys.odf.ProgramItem; 024import org.ametys.odf.program.AbstractProgram; 025import org.ametys.odf.program.Program; 026import org.ametys.odf.program.SubProgram; 027import org.ametys.odf.skill.ODFSkillsHelper; 028import org.ametys.plugins.odfweb.repository.OdfPageHandler; 029import org.ametys.plugins.odfweb.repository.ProgramPage; 030import org.ametys.plugins.repository.AmetysObject; 031import org.ametys.web.repository.page.Page; 032import org.ametys.web.repository.sitemap.Sitemap; 033import org.ametys.web.transformation.xslt.AmetysXSLTHelper; 034 035/** 036 * Helper component to be used from XSL stylesheets. 037 */ 038public class OdfXSLTHelper extends org.ametys.odf.OdfXSLTHelper 039{ 040 /** The ODF page handler */ 041 protected static OdfPageHandler _odfPageHandler; 042 043 /** The ODF skills helper */ 044 protected static ODFSkillsHelper _odfSkillsHelper; 045 046 @Override 047 public void service(ServiceManager smanager) throws ServiceException 048 { 049 super.service(smanager); 050 _odfPageHandler = (OdfPageHandler) smanager.lookup(OdfPageHandler.ROLE); 051 _odfSkillsHelper = (ODFSkillsHelper) smanager.lookup(ODFSkillsHelper.ROLE); 052 } 053 054 /** 055 * Get the ODF root page, for a specific site, language. 056 * If there is many ODF root pages, the first page of the list is returned. 057 * @param siteName the desired site name. 058 * @param language the sitemap language to search in. 059 * @return the first ODF root page, or null if not found 060 */ 061 public static String odfRootPage(String siteName, String language) 062 { 063 Page odfRootPage = _odfPageHandler.getOdfRootPage(siteName, language); 064 if (odfRootPage != null) 065 { 066 return odfRootPage.getId(); 067 } 068 return null; 069 } 070 071 /** 072 * Get the ODF root page, for a specific site, language and catalog. 073 * @param siteName the desired site name. 074 * @param language the sitemap language to search in. 075 * @param catalog The ODF catalog 076 * @return the ODF root page, or null if not found 077 */ 078 public static String odfRootPage(String siteName, String language, String catalog) 079 { 080 Page odfRootPage = _odfPageHandler.getOdfRootPage(siteName, language, catalog); 081 if (odfRootPage != null) 082 { 083 return odfRootPage.getId(); 084 } 085 return null; 086 } 087 088 /** 089 * Get the PDF url of a program or a subprogram 090 * @param contentId The content id 091 * @param siteName The site name 092 * @return the PDF url or empty string if the content is not a {@link Program} or {@link SubProgram} 093 */ 094 public static String odfPDFUrl (String contentId, String siteName) 095 { 096 StringBuilder sb = new StringBuilder(); 097 098 Content content = _ametysObjectResolver.resolveById(contentId); 099 if (content instanceof AbstractProgram) 100 { 101 sb.append(AmetysXSLTHelper.uriPrefix()) 102 .append("/plugins/odf-web/") 103 .append(siteName) 104 .append("/_content/") 105 .append(content.getName()) 106 .append(".pdf"); 107 } 108 109 return sb.toString(); 110 } 111 112 /** 113 * Get the id of parent program from the current page 114 * @return the id of parent program or null if not found 115 */ 116 public static String parentProgramId() 117 { 118 String pageId = AmetysXSLTHelper.pageId(); 119 120 if (StringUtils.isNotEmpty(pageId)) 121 { 122 Page page = _ametysObjectResolver.resolveById(pageId); 123 124 AmetysObject parent = page.getParent(); 125 while (!(parent instanceof Sitemap)) 126 { 127 if (parent instanceof ProgramPage) 128 { 129 return ((ProgramPage) parent).getProgram().getId(); 130 } 131 132 parent = parent.getParent(); 133 } 134 } 135 136 return null; 137 } 138 139 /** 140 * <code>true</code> if the program item is part of an program item (program, subprogram or container) that is excluded from skills 141 * @param programItemId the program item id 142 * @param programPageItemId the program item page id. If null or empty, program item is display with no context, consider that skills are available 143 * @return <code>true</code> if the program item has an excluded parent in it path from the page context 144 */ 145 public static boolean areSkillsUnavailable(String programItemId, String programPageItemId) 146 { 147 if (StringUtils.isBlank(programItemId) || StringUtils.isBlank(programPageItemId)) 148 { 149 // program part is displayed outside a page context, assuming that skills should be displayed 150 return false; 151 } 152 153 ProgramItem programItem = _ametysObjectResolver.resolveById(programItemId); 154 if (programItem instanceof Program) 155 { 156 return _odfSkillsHelper.isExcluded(programItem); 157 } 158 159 Page programItemPage = _ametysObjectResolver.resolveById(programPageItemId); 160 161 ProgramPage closestProgramPage = _getClosestProgramPage(programItemPage); 162 AbstractProgram closestProgramOrSubprogram = closestProgramPage.getProgram(); 163 164 ProgramItem parent = _odfHelper.getParentProgramItem(programItem, closestProgramOrSubprogram); 165 while (parent != null && !(parent instanceof Program)) 166 { 167 if (_odfSkillsHelper.isExcluded(parent)) 168 { 169 // If the parent is excluded, the skills are unavailable 170 return true; 171 } 172 173 // If the closest program parent is a subprogram, continue to its program parent 174 if (closestProgramOrSubprogram instanceof SubProgram && closestProgramOrSubprogram.equals(parent)) 175 { 176 closestProgramOrSubprogram = ((ProgramPage) closestProgramPage.getParent()).getProgram(); 177 } 178 parent = _odfHelper.getParentProgramItem(parent, closestProgramOrSubprogram); 179 } 180 181 return parent != null ? _odfSkillsHelper.isExcluded(parent) : false; 182 } 183 184 private static ProgramPage _getClosestProgramPage(Page page) 185 { 186 Page parentPage = page.getParent(); 187 while (!(parentPage instanceof ProgramPage)) 188 { 189 parentPage = parentPage.getParent(); 190 } 191 192 return (ProgramPage) parentPage; 193 } 194}