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.configuration.Configurable;
019import org.apache.avalon.framework.configuration.Configuration;
020import org.apache.avalon.framework.configuration.ConfigurationException;
021import org.apache.avalon.framework.logger.Logger;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.components.ContextHelper;
025import org.apache.cocoon.environment.Request;
026
027import org.ametys.cms.repository.Content;
028import org.ametys.cms.transformation.URIResolver;
029import org.ametys.core.util.FilenameUtils;
030import org.ametys.core.util.URIUtils;
031import org.ametys.plugins.explorer.resources.Resource;
032import org.ametys.plugins.repository.AmetysObject;
033import org.ametys.plugins.repository.AmetysObjectResolver;
034import org.ametys.plugins.repository.UnknownAmetysObjectException;
035import org.ametys.runtime.plugin.component.PluginAware;
036import org.ametys.web.editor.AttachmentURIResolver;
037import org.ametys.web.repository.SiteAwareAmetysObject;
038import org.ametys.web.repository.content.WebContent;
039
040/**
041 * {@link URIResolver} for type "attachment-content-pdf2flash".<br> TODO
042 * These links point to a document file from the attachments of the current Content converted it to flash. 
043 */
044public class Attachment2FlipbookUriResolver extends AttachmentURIResolver implements PluginAware, Configurable
045{
046    /** The plugin name. */
047    protected String _pluginName;
048    
049    /** The type. */
050    protected String _type;
051    
052    /** The ametys object resolver. */
053    protected ConvertContentAttachment2ImagesComponent _attachmentComponent;
054    
055    @Override
056    public void service(ServiceManager serviceManager) throws ServiceException
057    {
058        super.service(serviceManager);
059        _attachmentComponent = (ConvertContentAttachment2ImagesComponent) serviceManager.lookup(ConvertContentAttachment2ImagesComponent.ROLE);
060    }
061    
062    @Override
063    public void setPluginInfo(String pluginName, String featureName, String id)
064    {
065        _pluginName = pluginName;
066    }
067
068    public void configure(Configuration configuration) throws ConfigurationException
069    {
070        _type = configuration.getChild("type").getValue("attachment-content-flipbook");
071    }
072    
073    @Override
074    public String getType()
075    {
076        return _type;
077    }
078    
079    @Override
080    public String resolve(String uri, boolean download, boolean absolute, boolean internal)
081    {
082        Request request = ContextHelper.getRequest(_context);
083
084        String path;
085        Content content = null;
086        String contentName = null;
087        String siteName = null;
088        Resource resource = null;
089        try
090        {
091            resource = (Resource) _resolver.resolveById(uri);
092            path = resource.getResourcePath();
093            
094            content = (Content) request.getAttribute(Content.class.getName());
095            contentName = content.getName();
096            
097            if (content instanceof WebContent)
098            {
099                siteName = ((WebContent) content).getSiteName();
100            }
101            else
102            {
103                siteName = (String) request.getAttribute("siteName");
104                if (siteName == null)
105                {
106                    siteName = (String) request.getAttribute("site");
107                }
108            }
109           
110        }
111        catch (UnknownAmetysObjectException e)
112        {
113            getLogger().warn("Link to unexisting resource " + uri);
114            return "";
115        }
116        catch (Exception e)
117        {
118            throw new IllegalStateException(e);
119        }
120        
121        
122        // plugins/flipbook/<siteName>/_attachments-flipbook/<contentName>/<fileName>/book.html
123        String resultPath = getUriPrefix(content, download, absolute, internal)
124                + "/_attachments-flipbook/"
125                + contentName 
126                + FilenameUtils.encodePath(path)
127                + "/_contents"
128                + FilenameUtils.encodePath(resource.getPath())
129                + "/book.html";
130        
131        if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType()))
132        {
133            return super.resolve(uri, download, absolute, internal);
134        }
135        
136        new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start();
137        
138        return URIUtils.encodePath(resultPath.toString());
139    }
140    
141    @Override
142    public String resolveImage(String uri, int height, int width, boolean download, boolean absolute, boolean internal)
143    {
144        Request request = ContextHelper.getRequest(_context);
145
146        Content content = null;
147        String contentName = null;
148        String siteName = null;
149        Resource resource = null;
150        try
151        {
152            resource = (Resource) _resolver.resolveById(uri);
153            
154            content = (Content) request.getAttribute(Content.class.getName());
155            contentName = content.getName();
156            
157            if (content instanceof WebContent)
158            {
159                siteName = ((WebContent) content).getSiteName();
160            }
161        }
162        catch (UnknownAmetysObjectException e)
163        {
164            getLogger().warn("Link to unexisting resource " + uri);
165            return "";
166        }
167        catch (Exception e)
168        {
169            throw new IllegalStateException(e);
170        }
171        
172        if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType()))
173        { 
174            String defaultPath = getUriPrefix(content, download, absolute, internal)
175                    + "/pages" 
176                    + "/error"
177                    + "/thumbnail_"
178                    + height + "x" + width
179                    + ".png";
180            
181            return URIUtils.encodePath(defaultPath);
182        }
183        
184        new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start();
185
186        String result = getUriPrefix(content, download, absolute, internal)
187                + "/contents/"
188                + contentName
189                + "/attachments"
190                + FilenameUtils.encodePath(resource.getResourcePath())
191                + "/pages" 
192                + "/thumbnail_"
193                + height + "x" + width
194                + ".png";
195        
196        return URIUtils.encodePath(result);
197    }
198    
199    @Override
200    public String resolveBoundedImage(String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal)
201    {
202        if (maxHeight == 0 && maxWidth == 0)
203        {
204            return resolve(uri, download, absolute, internal);
205        }
206        
207        Request request = ContextHelper.getRequest(_context);
208
209        Content content = null;
210        String contentName = null;
211        String siteName = null;
212        Resource resource = null;
213        try
214        {
215            resource = (Resource) _resolver.resolveById(uri);
216            
217            content = (Content) request.getAttribute(Content.class.getName());
218            contentName = content.getName();
219            
220            if (content instanceof WebContent)
221            {
222                siteName = ((WebContent) content).getSiteName();
223            }
224            
225        }
226        catch (UnknownAmetysObjectException e)
227        {
228            getLogger().warn("Link to unexisting resource " + uri);
229            return "";
230        }
231        catch (Exception e)
232        {
233            throw new IllegalStateException(e);
234        }
235        
236        if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType()))
237        { 
238            String defaultPath = getUriPrefix(content, download, absolute, internal)
239                    + "/pages" 
240                    + "/error"
241                    + "/thumbnail_max"
242                    + maxHeight + "x" + maxWidth
243                    + ".png";
244            
245            return URIUtils.encodePath(defaultPath);
246        }
247
248        new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start();
249        
250        String result = getUriPrefix(content, download, absolute, internal)
251                + "/contents/"
252                + contentName
253                + "/attachments"
254                + FilenameUtils.encodePath(resource.getResourcePath())
255                + "/pages" 
256                + "/thumbnail_max"
257                + maxHeight + "x" + maxWidth
258                + ".png";
259        
260        return URIUtils.encodePath(result);
261    }
262    
263    @Override
264    protected String getUriPrefix(AmetysObject object, boolean download, boolean absolute, boolean internal)
265    {
266        Request request = ContextHelper.getRequest(_context);
267        
268        String siteName = null;
269        if (object instanceof SiteAwareAmetysObject)
270        {
271            siteName = ((SiteAwareAmetysObject) object).getSiteName();
272        }
273        else
274        {
275            siteName = (String) request.getAttribute("siteName");
276            
277            if (siteName == null)
278            {
279                siteName = (String) request.getAttribute("site");
280            }
281        }
282        
283        String initialSiteName = (String) ContextHelper.getRequest(_context).getAttribute("initialSiteName");
284        boolean isInitialSite = initialSiteName == null || initialSiteName.equals(siteName);
285        
286        String uriPrefix;
287        if (internal)
288        {
289            uriPrefix = "cocoon://" + siteName;
290        }
291        else if (absolute || !isInitialSite)
292        {
293            uriPrefix = _webPrefixHandler.getAbsoluteUriPrefix(siteName);
294        }
295        else
296        {
297            uriPrefix = _webPrefixHandler.getUriPrefix(siteName);
298        }
299        
300        uriPrefix +=  "/_plugins/" + _pluginName + "/" + siteName;
301        return uriPrefix;
302    }
303    
304    private class CacheThread extends Thread 
305    {
306        private String _resourceId;
307        private String _siteName;
308        private String _contentName;
309        private Logger _cacheLogger;
310        private AmetysObjectResolver _cacheResolver;
311        
312        /**
313         * Constructor
314         * @param resourceId The id of resource
315         * @param contentName The content's name
316         * @param siteName The site name
317         * @param cacheResolver The ametys object resolver
318         * @param cacheLogger The logger
319         */
320        public CacheThread(String resourceId, String contentName, String siteName, AmetysObjectResolver cacheResolver, Logger cacheLogger) 
321        {
322            _resourceId = resourceId;
323            _siteName = siteName;
324            _cacheLogger = cacheLogger;
325            _cacheResolver = cacheResolver;
326            _contentName = contentName;
327            setDaemon(true);
328            setName("FlipbookCacheAttachmentCreator");
329        }
330        
331        @Override
332        public void run() 
333        {
334            try
335            {
336                Resource resource = _cacheResolver.resolveById(_resourceId);
337                _attachmentComponent.doCache(resource, _contentName, _siteName);
338            }
339            catch (Exception e)
340            {
341                _cacheLogger.error("An error occurred during creating cache for resource : " + _resourceId);
342            }
343        }
344    }
345}