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;
017
018import java.io.InputStream;
019import java.util.Collections;
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.commons.lang.StringUtils;
028
029import org.ametys.cms.URIPrefixHandler;
030import org.ametys.cms.transformation.ConsistencyChecker.CHECK;
031import org.ametys.core.util.FilenameUtils;
032import org.ametys.core.util.URIUtils;
033import org.ametys.plugins.explorer.resources.Resource;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.AmetysObjectResolver;
036import org.ametys.plugins.repository.UnknownAmetysObjectException;
037import org.ametys.plugins.repository.version.VersionableAmetysObject;
038import org.ametys.runtime.i18n.I18nizableText;
039
040/**
041 * {@link URIResolver} for type "explorer". <br>
042 * These links point to a file from the resources explorer.
043 */
044public class ResourceURIResolver extends AbstractURIResolver implements Serviceable, Contextualizable
045{
046    /** The ametys object resolver. */
047    protected AmetysObjectResolver _resolver;
048    /** The avalon context. */
049    protected Context _context;
050    /** The URI prefix handler */
051    protected URIPrefixHandler _prefixHandler;
052    
053    @Override
054    public void contextualize(Context context) throws ContextException
055    {
056        _context = context;
057    }
058
059    @Override
060    public void service(ServiceManager manager) throws ServiceException
061    {
062        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
063        _prefixHandler = (URIPrefixHandler) manager.lookup(URIPrefixHandler.ROLE);
064    }
065    
066    @Override
067    public String getType()
068    {
069        return "explorer";
070    }
071    
072    /**
073     * Get the URI prefix
074     * @param object The object
075     * @param download true if the pointed resource is to be downloaded.
076     * @param absolute true if the url must be absolute
077     * @param internal true to get an internal URI.
078     * @return the URI prefix
079     */
080    protected String getUriPrefix (AmetysObject object, boolean download, boolean internal, boolean absolute)
081    {
082        return _prefixHandler.computeUriPrefix(absolute, internal);
083    }
084    
085    @Override
086    protected String _resolve(String uri, String uriArgument, boolean download, boolean absolute, boolean internal)
087    {
088        String version = null;
089        String path;
090        Resource resource = null;
091        try
092        {
093            String resourceId = uri;
094            int i = uri.indexOf(";");
095            if (i != -1)
096            {
097                resourceId = uri.substring(0, i);
098                version = uri.substring(i + 1);
099            }
100            
101            resource = (Resource) _resolver.resolveById(resourceId);
102            path = getResourcePath(resource);
103        }
104        catch (UnknownAmetysObjectException e)
105        {
106            getLogger().warn("Link to unexisting resource " + uri);
107            return "";
108        }
109        
110        String filename = FilenameUtils.encodePath(path);
111        String baseName = org.apache.commons.io.FilenameUtils.removeExtension(filename);
112        String extension = org.apache.commons.io.FilenameUtils.getExtension(filename);
113        
114        StringBuilder result = new StringBuilder();
115        
116        result.append(getUriPrefix(resource, download, absolute, internal));
117        
118        String realPrefix = getRealPrefix(resource, "resource");
119        if (StringUtils.isNotEmpty(realPrefix))
120        {
121            result.append("/_").append(realPrefix);
122        }
123        
124        if (StringUtils.isNotEmpty(version) && resource instanceof VersionableAmetysObject)
125        {
126            result.append("/__v_").append(version);
127        }
128        
129        result.append(baseName)
130              .append(uriArgument)
131              .append(extension.isEmpty() ? "" : "." + extension);
132        
133        return URIUtils.encodeURI(result.toString(), download ? Collections.singletonMap("download", "true") : null);
134    }
135    
136    /**
137     * Get the resource path 
138     * @param resource the resource
139     * @return the path
140     */
141    protected String getResourcePath (Resource resource)
142    {
143        return resource.getResourcePath();
144    }
145    
146    /**
147     * Get the real prefix
148     * @param resource the resource
149     * @param prefix the initial prefix
150     * @return the real prefix
151     */
152    protected String getRealPrefix (Resource resource, String prefix)
153    {
154        return prefix;
155    }
156    
157    @Override
158    protected String resolveImageAsBase64(String uri, int height, int width, int maxHeight, int maxWidth, int cropHeight, int cropWidth)
159    {
160        try
161        {
162            Resource resource = (Resource) _resolver.resolveById(uri);
163            try (InputStream dataIs = resource.getInputStream())
164            {
165                return ImageResolverHelper.resolveImageAsBase64(dataIs, resource.getMimeType(), height, width, maxHeight, maxWidth, cropHeight, cropWidth);
166            }
167        }
168        catch (UnknownAmetysObjectException e)
169        {
170            getLogger().warn("Link to unexisting resource " + uri);
171            return "";
172        }
173        catch (Exception e)
174        {
175            throw new IllegalStateException(e);
176        }
177    }
178
179    @Override
180    public CHECK checkLink(String uri, boolean shortTest)
181    {
182        try
183        {
184            _resolver.resolveById(uri);
185            return CHECK.SUCCESS;
186        }
187        catch (UnknownAmetysObjectException e)
188        {
189            return CHECK.NOT_FOUND;
190        }
191    }
192    
193    @Override
194    public I18nizableText getLabel(String uri)
195    {
196        try
197        {
198            Resource resource = (Resource) _resolver.resolveById(uri);
199            return new I18nizableText("plugin.cms", "PLUGINS_CMS_LINK_RESOURCE_LABEL", Collections.singletonList(resource.getResourcePath()));
200        }
201        catch (UnknownAmetysObjectException e)
202        {
203            return new I18nizableText("plugin.cms", "PLUGINS_CMS_LINK_RESOURCE_UNKNOWN");
204        }
205    }
206}