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}