001/*
002 *  Copyright 2014 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.plugins.flipbook;
017
018import org.apache.avalon.framework.logger.Logger;
019import org.apache.avalon.framework.service.ServiceException;
020import org.apache.avalon.framework.service.ServiceManager;
021import org.apache.cocoon.components.ContextHelper;
022import org.apache.cocoon.environment.Request;
023
024import org.ametys.cms.data.Binary;
025import org.ametys.cms.repository.Content;
026import org.ametys.cms.transformation.URIResolver;
027import org.ametys.core.util.FilenameUtils;
028import org.ametys.core.util.URIUtils;
029import org.ametys.plugins.repository.AmetysObjectResolver;
030import org.ametys.plugins.repository.UnknownAmetysObjectException;
031import org.ametys.runtime.plugin.component.PluginAware;
032import org.ametys.web.editor.AttributeURIResolver;
033
034/**
035 * {@link URIResolver} for type "attribute-flipbook".<br>
036 * These links point to a document file from the resource explorer converted to flash. 
037 */
038public class Attribute2FlipbookUriResolver extends AttributeURIResolver implements PluginAware
039{
040    /** The plugin name. */
041    protected String _pluginName;
042    
043    /** The logger . */
044    protected Logger _logger;
045    
046    /** Metadata to images convertor. */
047    protected ConvertMetadata2ImagesComponent _metadataComponent;
048    
049    @Override
050    public void service(ServiceManager serviceManager) throws ServiceException
051    {
052        super.service(serviceManager);
053        _metadataComponent = (ConvertMetadata2ImagesComponent) serviceManager.lookup(ConvertMetadata2ImagesComponent.ROLE);
054    }
055    
056    @Override
057    public void setPluginInfo(String pluginName, String featureName, String id)
058    {
059        _pluginName = pluginName;
060    }
061    
062    @Override
063    public void enableLogging(Logger logger)
064    {
065        _logger = logger;
066    }
067    
068    @Override
069    public String getType()
070    {
071        return "attribute-flipbook";
072    }
073    
074    @Override
075    public String resolve(String uri, boolean download, boolean absolute, boolean internal)
076    {
077        Request request = ContextHelper.getRequest(_context);
078        
079        String path;
080        String fileName;
081        String siteName = (String) request.getAttribute("site");
082        Content content;
083        try
084        {
085            AttributeInfo info = _getAttributeInfo(uri, request);
086            
087            path = info.getPath();
088            content = info.getContent();
089
090            fileName = content.getName();
091        }
092        catch (UnknownAmetysObjectException e)
093        {
094            return "";
095        }
096
097        Binary binary = content.getValue(path);
098        
099        if (!_metadataComponent.isMimeTypeSupported(binary.getMimeType()))
100        {
101            return super.resolve(uri, download, absolute, internal);
102        }
103        
104        String resultPath = (absolute ? _prefixHandler.getAbsoluteUriPrefix(siteName) : _prefixHandler.getUriPrefix(siteName))
105                + "/_plugins/" + _pluginName + "/" + siteName
106                + "/_metadata-flipbook/"
107                + fileName
108                + "/" 
109                + path
110                + "/_contents"
111                + FilenameUtils.encodePath(content.getPath())
112                + "/book.html";
113        
114        new CacheThread(content.getId(), path, siteName, _resolver, _logger).start();
115        
116        // Encode twice
117        return URIUtils.encodePath(resultPath.toString());
118    }
119    
120    private String _resolveImage(String uri, String uriArgument, boolean absolute)
121    {
122        Request request = ContextHelper.getRequest(_context);
123        
124        String path;
125        String siteName = (String) request.getAttribute("site");
126        Content content;
127        try
128        {
129            AttributeInfo info = _getAttributeInfo(uri, request);
130            
131            path = info.getPath();
132            content = info.getContent();
133        }
134        catch (UnknownAmetysObjectException e)
135        {
136            return "";
137        }
138
139        Binary binary = content.getValue(path);
140        
141        if (!_metadataComponent.isMimeTypeSupported(binary.getMimeType()))
142        { 
143            String defaultPath = (absolute ? _prefixHandler.getAbsoluteUriPrefix(siteName) : _prefixHandler.getUriPrefix(siteName))
144                    + "/_plugins/" + _pluginName + "/" + siteName
145                    + "/pages" 
146                    + "/error"
147                    + "/thumbnail_"
148                    + uriArgument
149                    + ".png";
150            
151            return URIUtils.encodePath(defaultPath);
152        }
153
154        String result = (absolute ? _prefixHandler.getAbsoluteUriPrefix(siteName) : _prefixHandler.getUriPrefix(siteName))
155                + "/_plugins/" + _pluginName + "/" + siteName
156                + "/contents/"
157                + content.getName()
158                + "/metadatas/"
159                + path
160                + "/"
161                + FilenameUtils.encodeName(binary.getFilename())
162                + "/pages" 
163                + "/thumbnail_"
164                + uriArgument
165                + ".png";
166        
167        // Encode twice
168        return URIUtils.encodePath(result);
169    }
170    
171    @Override
172    public String resolveImage(String uri, int height, int width, boolean download, boolean absolute, boolean internal)
173    {
174        if (height == 0 && width == 0)
175        {
176            return resolve(uri, download, absolute, internal);
177        }
178        
179        return _resolveImage(uri, height + "x" + width, absolute);
180    }
181    
182    @Override
183    public String resolveBoundedImage(String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal)
184    {
185        if (maxHeight == 0 && maxWidth == 0)
186        {
187            return resolve(uri, download, absolute, internal);
188        }
189        
190        return _resolveImage(uri, maxHeight + "x" + maxWidth, absolute);
191    }
192    
193    @Override
194    public String resolveCroppedImage(String uri, int cropHeight, int cropWidth, boolean download, boolean absolute, boolean internal)
195    {
196        throw new UnsupportedOperationException("#resolveCroppedImage is nos supported for Attribute2FlipbookUriResolver");
197    }
198    
199    @Override
200    public String resolveImageAsBase64(String uri, int height, int width)
201    {
202        throw new UnsupportedOperationException("#resolveImageAsBase64 is nos supported for Attribute2FlipbookUriResolver");
203    }
204    
205    @Override
206    public String resolveBoundedImageAsBase64(String uri, int maxHeight, int maxWidth)
207    {
208        throw new UnsupportedOperationException("#resolveBoundedImageAsBase64 is nos supported for Attribute2FlipbookUriResolver");
209    }
210    
211    @Override
212    public String resolveCroppedImageAsBase64(String uri, int cropHeight, int cropWidth)
213    {
214        throw new UnsupportedOperationException("#resolveCroppedImageAsBase64 is nos supported for Attribute2FlipbookUriResolver");
215    }
216
217    private class CacheThread extends Thread 
218    {
219        private String _contentId;
220        private String _path;
221        private String _siteName;
222        private Logger _cacheLogger;
223        private AmetysObjectResolver _cacheResolver;
224        
225        public CacheThread(String contentId, String path, String siteName, AmetysObjectResolver cacheResolver, Logger cacheLogger) 
226        {
227            _contentId = contentId;
228            _path = path;
229            _siteName = siteName;
230            _cacheLogger = cacheLogger;
231            _cacheResolver = cacheResolver;
232            setDaemon(true);
233            setName("FlipbookCacheMetadataCreator");
234        }
235        
236        @Override
237        public void run() 
238        {
239            try
240            {
241                Content content = _cacheResolver.resolveById(_contentId);
242                _metadataComponent.doCache(content, _path, _siteName);
243            }
244            catch (Exception e)
245            {
246                _cacheLogger.error("An error occurred during creating cache for content : " + _contentId);
247            }
248        }
249    }
250}