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.cms.transformation.xslt;
017
018import org.apache.avalon.framework.activity.Initializable;
019import org.apache.avalon.framework.context.Context;
020import org.apache.avalon.framework.context.ContextException;
021import org.apache.avalon.framework.context.Contextualizable;
022import org.apache.avalon.framework.logger.AbstractLogEnabled;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028
029import org.ametys.cms.transformation.URIResolver;
030import org.ametys.cms.transformation.URIResolverExtensionPoint;
031
032/**
033 * This component resolve links and give a static hack access for xslt calls
034 */
035public class ResolveURIComponent extends AbstractLogEnabled implements Serviceable, Initializable, Contextualizable
036{
037    private static ResolveURIComponent _instance;
038    
039    private static Context _context;
040    
041    private URIResolverExtensionPoint _linkResolverExtensionPoint;
042    
043    @Override
044    public void contextualize(Context context) throws ContextException
045    {
046        _context = context;
047    }
048    
049    @Override
050    public void service(ServiceManager manager) throws ServiceException
051    {
052        _linkResolverExtensionPoint = (URIResolverExtensionPoint) manager.lookup(URIResolverExtensionPoint.ROLE);
053    }
054    
055    @Override
056    public void initialize() throws Exception
057    {
058        _instance = this;
059    }
060    
061    /**
062     * Resolve an uri upon the LinkResolverExtensionPoint
063     * @param type Type name (defined by the extension to use)
064     * @param uri URI depending on the type
065     * @return The uri resolved, or the uri if there is no resolver adapted
066     */
067    public static String resolve(String type, String uri)
068    {
069        return resolve(type, uri, false);
070    }
071
072    /**
073     * Resolve an uri upon the LinkResolverExtensionPoint
074     * @param type Type name (defined by the extension to use)
075     * @param uri URI depending on the type
076     * @param download Is this uri for download purposes.
077     * @return The uri resolved, or the uri if there is no resolver adapted
078     */
079    public static String resolve(String type, String uri, boolean download)
080    {
081        // FIXME CMS-2611 Force absolute 
082        Request request = ContextHelper.getRequest(_context);
083        boolean absolute = request.getAttribute("forceAbsoluteUrl") != null ? (Boolean) request.getAttribute("forceAbsoluteUrl") : false;
084        
085        return resolve(type, uri, download, absolute);
086    }
087    
088    /**
089     * Resolve an uri upon the LinkResolverExtensionPoint
090     * @param type Type name (defined by the extension to use)
091     * @param uri URI depending on the type
092     * @param download Is this uri for download purposes.
093     * @param absolute true to generate absolute url
094     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
095     */
096    public static String resolve(String type, String uri, boolean download, boolean absolute)
097    {
098        return resolve(type, uri, download, absolute, false);
099    }
100    
101    /**
102     * Resolve an uri upon the LinkResolverExtensionPoint
103     * @param type Type name (defined by the extension to use)
104     * @param uri URI depending on the type
105     * @param download Is this uri for download purposes.
106     * @param absolute true to generate absolute url
107     * @param internal true to get an internal URI.
108     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
109     */
110    public static String resolve(String type, String uri, boolean download, boolean absolute, boolean internal)
111    {
112        Request request = ContextHelper.getRequest(_context);
113        Object forceRemoteUrl = request.getAttribute("forceRemoteUrl");
114        
115        boolean remote = forceRemoteUrl != null && ((forceRemoteUrl instanceof Boolean && (Boolean) forceRemoteUrl) || Boolean.valueOf((String) forceRemoteUrl));
116        
117        String proxiedUri = remote ? type + ";" + uri : uri;
118        URIResolver uriResolver = _instance._linkResolverExtensionPoint.getResolverForType(remote ? "remote" : type);
119        if (uriResolver != null)
120        {
121            try
122            {
123                request.removeAttribute("forceRemoteUrl");
124                return uriResolver.resolve(proxiedUri, download, absolute, internal);
125            }
126            catch (Exception e)
127            {
128                _instance.getLogger().warn("Error resolving the uri '" + uri + "' with type " + type, e);
129                return "";
130            }
131            finally
132            {
133                request.setAttribute("forceRemoteUrl", forceRemoteUrl);
134            }
135        }
136        else
137        {
138            return uri;
139        }
140    }
141    
142    /**
143     * Resolve an uri upon the LinkResolverExtensionPoint
144     * @param type Type name (defined by the extension to use)
145     * @param uri URI depending on the type
146     * @param height the height
147     * @param width the width
148     * @return The uri resolved, or the uri if there is no resolver adapted
149     */
150    public static String resolveImage(String type, String uri, int height, int width)
151    {
152        return resolveImage (type, uri, height, width, false);
153    }
154    
155    /**
156     * Resolve an uri upon the LinkResolverExtensionPoint
157     * @param type Type name (defined by the extension to use)
158     * @param uri URI depending on the type
159     * @param height the height
160     * @param width the width
161     * @param download Is this uri for download purposes.
162     * @return The uri resolved, or the uri if there is no resolver adapted
163     */
164    public static String resolveImage(String type, String uri, int height, int width, boolean download)
165    {
166        // FIXME CMS-2611 Force absolute 
167        Request request = ContextHelper.getRequest(_context);
168        boolean absolute = request.getAttribute("forceAbsoluteUrl") != null ? (Boolean) request.getAttribute("forceAbsoluteUrl") : false;
169        
170        return resolveImage(type, uri, height, width, download, absolute);
171    }
172    
173    /**
174     * Resolve an uri upon the LinkResolverExtensionPoint
175     * @param type Type name (defined by the extension to use)
176     * @param uri URI depending on the type
177     * @param height the height
178     * @param width the width
179     * @param download Is this uri for download purposes.
180     * @param absolute true to generate absolute url
181     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
182     */
183    public static String resolveImage(String type, String uri, int height, int width, boolean download, boolean absolute)
184    {
185        return resolveImage(type, uri, height, width, download, absolute, false);
186    }
187    
188    /**
189     * Resolve an uri upon the LinkResolverExtensionPoint
190     * @param type Type name (defined by the extension to use)
191     * @param uri URI depending on the type
192     * @param height the height
193     * @param width the width
194     * @param download Is this uri for download purposes.
195     * @param absolute true to generate absolute url
196     * @param internal true to get an internal URI.
197     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
198     */
199    public static String resolveImage(String type, String uri, int height, int width, boolean download, boolean absolute, boolean internal)
200    {
201        // FIXME CMS-4059 Force base64 encoding. 
202        Request request = ContextHelper.getRequest(_context);
203        boolean encodeBase64 = request.getAttribute("forceBase64Encoding") != null ? (Boolean) request.getAttribute("forceBase64Encoding") : false;
204        
205        Object forceRemoteUrl = request.getAttribute("forceRemoteUrl");
206        boolean remote = forceRemoteUrl != null && ((forceRemoteUrl instanceof Boolean && (Boolean) forceRemoteUrl) || Boolean.valueOf((String) forceRemoteUrl));
207        
208        String proxiedUri = remote ? type + ";" + uri : uri;
209        URIResolver uriResolver = _instance._linkResolverExtensionPoint.getResolverForType(remote ? "remote" : type);
210        if (uriResolver != null)
211        {
212            try
213            {
214                request.removeAttribute("forceRemoteUrl");
215                if (encodeBase64)
216                {
217                    return uriResolver.resolveImageAsBase64(proxiedUri, height, width);
218                }
219                else
220                {
221                    return uriResolver.resolveImage(proxiedUri, height, width, download, absolute, internal);
222                }
223            }
224            catch (Exception e)
225            {
226                _instance.getLogger().warn("Error resolving the image of uri '" + uri + "' with type " + type, e);
227                return "";
228            }
229            finally
230            {
231                request.setAttribute("forceRemoteUrl", forceRemoteUrl);
232            }
233        }
234        else
235        {
236            return uri;
237        }
238    }
239    
240    /**
241     * Resolve an uri upon the LinkResolverExtensionPoint
242     * @param type Type name (defined by the extension to use)
243     * @param uri URI depending on the type
244     * @param maxHeight the max height
245     * @param maxWidth the max width
246     * @return The uri resolved, or the uri if there is no resolver adapted
247     */
248    public static String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth)
249    {
250        return resolveBoundedImage (type, uri, maxHeight, maxWidth, false);
251    }
252    
253    /**
254     * Resolve an uri upon the LinkResolverExtensionPoint
255     * @param type Type name (defined by the extension to use)
256     * @param uri URI depending on the type
257     * @param maxHeight the max height
258     * @param maxWidth the max width
259     * @param download Is this uri for download purposes.
260     * @return The uri resolved, or the uri if there is no resolver adapted
261     */
262    public static String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth, boolean download)
263    {
264        // FIXME CMS-2611 Force absolute 
265        Request request = ContextHelper.getRequest(_context);
266        boolean absolute = request.getAttribute("forceAbsoluteUrl") != null ? (Boolean) request.getAttribute("forceAbsoluteUrl") : false;
267        
268        return resolveBoundedImage(type, uri, maxHeight, maxWidth, download, absolute);
269    }
270    
271    /**
272     * Resolve an uri upon the LinkResolverExtensionPoint
273     * @param type Type name (defined by the extension to use)
274     * @param uri URI depending on the type
275     * @param maxHeight the max height
276     * @param maxWidth the max width
277     * @param download Is this uri for download purposes.
278     * @param absolute true to generate absolute url
279     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
280     */
281    public static String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth, boolean download, boolean absolute)
282    {
283        return resolveBoundedImage(type, uri, maxHeight, maxWidth, download, absolute, false);
284    }
285    
286    /**
287     * Resolve an uri upon the LinkResolverExtensionPoint
288     * @param type Type name (defined by the extension to use)
289     * @param uri URI depending on the type
290     * @param maxHeight the max height
291     * @param maxWidth the max width
292     * @param download Is this uri for download purposes.
293     * @param absolute true to generate absolute url
294     * @param internal true to get an internal URI.
295     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
296     */
297    public static String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal)
298    {
299        // FIXME CMS-4059 Force base64 encoding. 
300        Request request = ContextHelper.getRequest(_context);
301        boolean encodeBase64 = request.getAttribute("forceBase64Encoding") != null ? (Boolean) request.getAttribute("forceBase64Encoding") : false;
302        
303        Object forceRemoteUrl = request.getAttribute("forceRemoteUrl");
304        boolean remote = forceRemoteUrl != null && ((forceRemoteUrl instanceof Boolean && (Boolean) forceRemoteUrl) || Boolean.valueOf((String) forceRemoteUrl));
305        
306        String proxiedUri = remote ? type + ";" + uri : uri;
307        URIResolver uriResolver = _instance._linkResolverExtensionPoint.getResolverForType(remote ? "remote" : type);
308        if (uriResolver != null)
309        {
310            try
311            {
312                request.removeAttribute("forceRemoteUrl");
313                if (encodeBase64)
314                {
315                    return uriResolver.resolveBoundedImageAsBase64(proxiedUri, maxHeight, maxWidth);
316                }
317                else
318                {
319                    return uriResolver.resolveBoundedImage(proxiedUri, maxHeight, maxWidth, download, absolute, internal);
320                }
321            }
322            catch (Exception e)
323            {
324                _instance.getLogger().warn("Error resolving the image of uri '" + uri + "' with type " + type, e);
325                return "";
326            }
327            finally
328            {
329                request.setAttribute("forceRemoteUrl", forceRemoteUrl);
330            }
331        }
332        else
333        {
334            return uri;
335        }
336    }
337
338    /**
339     * Resolve an uri upon the LinkResolverExtensionPoint
340     * @param type Type name (defined by the extension to use)
341     * @param uri URI depending on the type
342     * @param cropHeight the crop height
343     * @param cropWidth the crop width
344     * @return The uri resolved, or the uri if there is no resolver adapted
345     */
346    public static String resolveCroppedImage(String type, String uri, int cropHeight, int cropWidth)
347    {
348        return resolveCroppedImage (type, uri, cropHeight, cropWidth, false);
349    }
350    
351    /**
352     * Resolve an uri upon the LinkResolverExtensionPoint
353     * @param type Type name (defined by the extension to use)
354     * @param uri URI depending on the type
355     * @param cropHeight the crop height
356     * @param cropWidth the crop width
357     * @param download Is this uri for download purposes.
358     * @return The uri resolved, or the uri if there is no resolver adapted
359     */
360    public static String resolveCroppedImage(String type, String uri, int cropHeight, int cropWidth, boolean download)
361    {
362        // FIXME CMS-2611 Force absolute 
363        Request request = ContextHelper.getRequest(_context);
364        boolean absolute = request.getAttribute("forceAbsoluteUrl") != null ? (Boolean) request.getAttribute("forceAbsoluteUrl") : false;
365        
366        return resolveCroppedImage(type, uri, cropHeight, cropWidth, download, absolute);
367    }
368    
369    /**
370     * Resolve an uri upon the LinkResolverExtensionPoint
371     * @param type Type name (defined by the extension to use)
372     * @param uri URI depending on the type
373     * @param cropHeight the crop height
374     * @param cropWidth the crop width
375     * @param download Is this uri for download purposes.
376     * @param absolute true to generate absolute url
377     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
378     */
379    public static String resolveCroppedImage(String type, String uri, int cropHeight, int cropWidth, boolean download, boolean absolute)
380    {
381        return resolveCroppedImage(type, uri, cropHeight, cropWidth, download, absolute, false);
382    }
383    
384    /**
385     * Resolve an uri upon the LinkResolverExtensionPoint
386     * @param type Type name (defined by the extension to use)
387     * @param uri URI depending on the type
388     * @param cropHeight the crop height
389     * @param cropWidth the crop width
390     * @param download Is this uri for download purposes.
391     * @param absolute true to generate absolute url
392     * @param internal true to get an internal URI.
393     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
394     */
395    public static String resolveCroppedImage(String type, String uri, int cropHeight, int cropWidth, boolean download, boolean absolute, boolean internal)
396    {
397        // FIXME CMS-4059 Force base64 encoding. 
398        Request request = ContextHelper.getRequest(_context);
399        boolean encodeBase64 = request.getAttribute("forceBase64Encoding") != null ? (Boolean) request.getAttribute("forceBase64Encoding") : false;
400        
401        URIResolver uriResolver = _instance._linkResolverExtensionPoint.getResolverForType(type);
402        if (uriResolver != null)
403        {
404            try
405            {
406                if (encodeBase64)
407                {
408                    return uriResolver.resolveCroppedImageAsBase64(uri, cropHeight, cropWidth);
409                }
410                else
411                {
412                    return uriResolver.resolveCroppedImage(uri, cropHeight, cropWidth, download, absolute, internal);
413                }
414            }
415            catch (Exception e)
416            {
417                _instance.getLogger().warn("Error resolving the image of uri '" + uri + "' with type " + type, e);
418                return "";
419            }
420        }
421        else
422        {
423            return uri;
424        }
425    }
426}