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.xslt; 017 018import java.util.Collections; 019 020import org.apache.avalon.framework.context.Context; 021import org.apache.avalon.framework.context.ContextException; 022import org.apache.avalon.framework.context.Contextualizable; 023import org.apache.avalon.framework.logger.LogEnabled; 024import org.apache.avalon.framework.logger.Logger; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.avalon.framework.service.Serviceable; 028import org.apache.cocoon.components.ContextHelper; 029import org.apache.cocoon.environment.Request; 030 031import org.ametys.cms.transformation.xslt.ResolveURIComponent; 032import org.ametys.core.util.FilenameUtils; 033import org.ametys.core.util.URIUtils; 034import org.ametys.plugins.explorer.resources.Resource; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.runtime.config.Config; 037 038/** 039 * Helper component to be used from XSL stylesheets for CDM-fr export 040 */ 041public class CDMFrXSLTHelper implements Serviceable, Contextualizable, LogEnabled 042{ 043 private static AmetysObjectResolver _ametysObjectResolver; 044 private static Context _context; 045 private static Logger _logger; 046 047 @Override 048 public void contextualize(Context context) throws ContextException 049 { 050 _context = context; 051 } 052 053 @Override 054 public void enableLogging(Logger logger) 055 { 056 _logger = logger; 057 } 058 059 @Override 060 public void service(ServiceManager smanager) throws ServiceException 061 { 062 _ametysObjectResolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 063 } 064 065 /** 066 * Resolve the URI of a resource 067 * @param type Type name (defined by the extension to use) 068 * @param uri URI depending on the type 069 * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted 070 */ 071 public static String resolve(String type, String uri) 072 { 073 return resolve(type, uri, false); 074 } 075 076 /** 077 * Resolve the URI of a resource 078 * @param type Type name (defined by the extension to use) 079 * @param uri URI depending on the type 080 * @param download Is this uri for download purposes. 081 * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted 082 */ 083 public static String resolve(String type, String uri, boolean download) 084 { 085 if ("explorer".equals(type)) 086 { 087 try 088 { 089 Resource resource = (Resource) _ametysObjectResolver.resolveById(uri); 090 String fullPath = resource.getPath(); 091 092 StringBuilder result = new StringBuilder(); 093 result.append((String) Config.getInstance().getValue("cms.url")) 094 .append("/_odf/_resource") 095 .append(FilenameUtils.encodePath(fullPath)); 096 097 return URIUtils.encodePath(result.toString()); 098 } 099 catch (Exception e) 100 { 101 _logger.warn("Error resolving the uri '" + uri + "' with type " + type, e); 102 return ""; 103 } 104 } 105 else if ("page".equals(type)) 106 { 107 // Force absolute 108 return ResolveURIComponent.resolve(type, uri, download, true, false); 109 } 110 else if ("mail".equals(type) || "phone".equals(type)) 111 { 112 // special handlig for mailto: and tel: links, as they won't be correctly handled by _resolve 113 return uri; 114 } 115 else 116 { 117 // Resolve URI forcing not absolute nor internal 118 String resolvedUri = ResolveURIComponent.resolve(type, uri, download, false, false); 119 return _resolve(resolvedUri); 120 } 121 } 122 123 /** 124 * Resolve the URI of a resource image 125 * @param type Type name (defined by the extension to use) 126 * @param uri URI depending on the type 127 * @param height the height 128 * @param width the width 129 * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted 130 */ 131 public static String resolveImage(String type, String uri, int height, int width) 132 { 133 return resolveImage(type, uri, height, width, false); 134 } 135 136 /** 137 * Resolve the absolute URI of a resource image 138 * @param type Type name (defined by the extension to use) 139 * @param uri URI depending on the type 140 * @param height the height 141 * @param width the width 142 * @param download Is this uri for download purposes. 143 * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted 144 */ 145 public static String resolveImage(String type, String uri, int height, int width, boolean download) 146 { 147 if ("explorer".equals(type)) 148 { 149 if (height == 0 && width == 0) 150 { 151 return _resolveResource(uri, download, null); 152 } 153 154 return _resolveResource(uri, download, "_" + height + "x" + width); 155 } 156 else 157 { 158 // Resolve URI forcing not absolute nor internal 159 String resolvedUri = ResolveURIComponent.resolveImage(type, uri, height, width, download, false, false); 160 return _resolve(resolvedUri); 161 } 162 } 163 164 /** 165 * Resolve the absolute URI of a resource video 166 * @param type Type name (defined by the extension to use) 167 * @param uri URI depending on the type 168 * @param download Is this uri for download purposes. 169 * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted 170 */ 171 public static String resolveVideo(String type, String uri, boolean download) 172 { 173 if ("explorer".equals(type)) 174 { 175 return _resolveResource(uri, download, null); 176 } 177 else 178 { 179 // Resolve URI forcing not absolute nor internal 180 String resolvedUri = ResolveURIComponent.resolve(type, uri, download, false, false); 181 return _resolve(resolvedUri); 182 } 183 } 184 185 private static String _resolve (String resolvedUri) 186 { 187 // Redirect to "odf" workspace 188 Request request = ContextHelper.getRequest(_context); 189 String contextPath = request.getContextPath(); 190 191 StringBuilder result = new StringBuilder(); 192 result.append((String) Config.getInstance().getValue("cms.url")) 193 .append("/_odf") 194 .append(org.apache.commons.lang.StringUtils.substringAfter(resolvedUri, contextPath)); 195 196 return result.toString(); 197 } 198 199 private static String _resolveResource (String uri, boolean download, String suffix) 200 { 201 try 202 { 203 Resource resource = (Resource) _ametysObjectResolver.resolveById(uri); 204 String fullPath = resource.getPath(); 205 206 int i = fullPath.lastIndexOf("."); 207 String extension = i != -1 ? fullPath.substring(i) : null; 208 fullPath = i != -1 ? fullPath.substring(0, i) : fullPath; 209 210 StringBuilder result = new StringBuilder(); 211 212 // Always use absolute url 213 result.append((String) Config.getInstance().getValue("cms.url")) 214 .append("/_odf/_resource") 215 .append(FilenameUtils.encodePath(fullPath)); 216 217 if (suffix != null) 218 { 219 result.append(suffix); 220 } 221 222 if (extension != null) 223 { 224 result.append(extension); 225 } 226 227 return URIUtils.encodeURI(result.toString(), download ? Collections.singletonMap("download", "true") : null); 228 } 229 catch (Exception e) 230 { 231 _logger.warn("Error resolving the uri '" + uri + "'", e); 232 return ""; 233 } 234 } 235}