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