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