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.net.URI;
019import java.net.URISyntaxException;
020
021import org.apache.avalon.framework.context.Context;
022import org.apache.avalon.framework.context.ContextException;
023import org.apache.avalon.framework.context.Contextualizable;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027import org.apache.cocoon.components.ContextHelper;
028import org.apache.cocoon.environment.Request;
029
030import org.ametys.cms.transformation.xslt.ResolveURIComponent;
031import org.ametys.core.util.URLEncoder;
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            
083            result.append(Config.getInstance().getValueAsString("cms.url"))
084                    .append("/_odf/")
085                    .append("_resources")
086                    .append(URLEncoder.encodePath(fullPath).replaceAll(":", "%3A"));
087            
088            return result.toString();
089        }
090        else if ("page".equals(type))
091        {
092            // Force absolute
093            return ResolveURIComponent.resolve(type, uri, download, true, false);
094        }
095        else
096        {
097            // Resolve URI forcing not abosolute nor internal
098            String resolvedUri = ResolveURIComponent.resolve(type, uri, download, false, false);
099            return _resolve(resolvedUri);
100        }
101    }
102    
103    /**
104     * Resolve the URI of a resource image
105     * @param type Type name (defined by the extension to use)
106     * @param uri URI depending on the type
107     * @param height the height
108     * @param width the width
109     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
110     */
111    public static String resolveImage(String type, String uri, int height, int width)
112    {
113        return resolveImage(type, uri, height, width, false);
114    }
115    
116    /**
117     * Resolve the absolute URI of a resource image
118     * @param type Type name (defined by the extension to use)
119     * @param uri URI depending on the type
120     * @param height the height
121     * @param width the width
122     * @param download Is this uri for download purposes.
123     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
124     */
125    public static String resolveImage(String type, String uri, int height, int width, boolean download)
126    {
127        if ("explorer".equals(type))
128        {
129            if (height == 0 && width == 0)
130            {
131                return _resolveResource(uri, download, "_resources", null);
132            }
133            
134            return _resolveResource(uri, download, "_resources-images", "_" + height + "x" + width);
135        }
136        else
137        {
138            // Resolve URI forcing not absolute nor internal
139            String resolvedUri = ResolveURIComponent.resolveImage(type, uri, height, width, download, false, false);
140            return _resolve(resolvedUri);
141        }
142    }
143    
144    /**
145     * Resolve the URI of a resource image
146     * @param type Type name (defined by the extension to use)
147     * @param uri URI depending on the type
148     * @param maxHeight the max height
149     * @param maxWidth the max width
150     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
151     */
152    public String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth)
153    {
154        return resolveBoundedImage(type, uri, maxHeight, maxWidth, false);
155    }
156    
157    /**
158     * Resolve the asbsolute URI of a resource image
159     * @param type Type name (defined by the extension to use)
160     * @param uri URI depending on the type
161     * @param maxHeight the max height
162     * @param maxWidth the max width
163     * @param download Is this uri for download purposes.
164     * @return The uri resolved, the empty string if the uri could not be resolved, or the uri itself if there is no resolver adapted
165     */
166    public String resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth, boolean download)
167    {
168        if ("explorer".equals(type))
169        {
170            if (maxHeight == 0 && maxWidth == 0)
171            {
172                return _resolveResource(uri, download, "_resources", null);
173            }
174            
175            return _resolveResource(uri, download, "_resources-images", "_max" + maxHeight + "x" + maxWidth);
176        }
177        else
178        {
179            // Resolve URI forcing not absolute nor internal
180            String resolvedUri = ResolveURIComponent.resolveBoundedImage(type, uri, maxHeight, maxWidth, 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(Config.getInstance().getValueAsString("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 prefix, String suffix)
200    {
201        Resource resource = (Resource) _ametysObjectResolver.resolveById(uri);
202        String fullPath = resource.getPath();
203        
204        int i = fullPath.lastIndexOf(".");
205        String extension = i != -1 ? fullPath.substring(i) : null;
206        fullPath = i != -1 ? fullPath.substring(0, i) : fullPath; 
207        
208        StringBuilder result = new StringBuilder();
209        
210        // Always use absolute url
211        result.append(Config.getInstance().getValueAsString("cms.url"))
212                .append("/_odf/")
213                .append(prefix)
214                .append(URLEncoder.encodePath(fullPath).replaceAll(":", "%3A"));
215        
216        if (suffix != null)
217        {
218            result.append(suffix);
219        }
220        
221        if (extension != null)
222        {
223            result.append(extension);
224        }
225        
226        try
227        {
228            return new URI(null, null, result.toString(), download ? "download=true" : null, null).toASCIIString();
229        }
230        catch (URISyntaxException e)
231        {
232            throw new RuntimeException(e);
233        }
234    }
235}