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.URLEncoder;
030import org.ametys.plugins.explorer.resources.Resource;
031import org.ametys.plugins.repository.AmetysObject;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.plugins.repository.UnknownAmetysObjectException;
034import org.ametys.runtime.plugin.component.PluginAware;
035import org.ametys.web.editor.AttachmentURIResolver;
036import org.ametys.web.repository.SiteAwareAmetysObject;
037import org.ametys.web.repository.content.WebContent;
038
039/**
040 * {@link URIResolver} for type "attachment-content-pdf2flash".<br> TODO
041 * These links point to a document file from the attachments of the current Content converted it to flash. 
042 */
043public class Attachment2FlipbookUriResolver extends AttachmentURIResolver implements PluginAware, Configurable
044{
045    /** The plugin name. */
046    protected String _pluginName;
047    
048    /** The type. */
049    protected String _type;
050    
051    /** The ametys object resolver. */
052    protected ConvertContentAttachment2ImagesComponent _attachmentComponent;
053    
054    @Override
055    public void service(ServiceManager serviceManager) throws ServiceException
056    {
057        super.service(serviceManager);
058        _attachmentComponent = (ConvertContentAttachment2ImagesComponent) serviceManager.lookup(ConvertContentAttachment2ImagesComponent.ROLE);
059    }
060    
061    @Override
062    public void setPluginInfo(String pluginName, String featureName, String id)
063    {
064        _pluginName = pluginName;
065    }
066
067    public void configure(Configuration configuration) throws ConfigurationException
068    {
069        _type = configuration.getChild("type").getValue("attachment-content-flipbook");
070    }
071    
072    @Override
073    public String getType()
074    {
075        return _type;
076    }
077    
078    @Override
079    public String resolve(String uri, boolean download, boolean absolute, boolean internal)
080    {
081        Request request = ContextHelper.getRequest(_context);
082
083        String path;
084        Content content = null;
085        String contentName = null;
086        String siteName = null;
087        Resource resource = null;
088        try
089        {
090            resource = (Resource) _resolver.resolveById(uri);
091            path = resource.getResourcePath();
092            
093            content = (Content) request.getAttribute(Content.class.getName());
094            contentName = content.getName();
095            
096            if (content instanceof WebContent)
097            {
098                siteName = ((WebContent) content).getSiteName();
099            }
100            else
101            {
102                siteName = (String) request.getAttribute("siteName");
103                if (siteName == null)
104                {
105                    siteName = (String) request.getAttribute("site");
106                }
107            }
108           
109        }
110        catch (UnknownAmetysObjectException e)
111        {
112            getLogger().warn("Link to unexisting resource " + uri);
113            return "";
114        }
115        catch (Exception e)
116        {
117            throw new IllegalStateException(e);
118        }
119        
120        
121        // plugins/flipbook/<siteName>/_attachments-flipbook/<contentName>/<fileName>/book.html
122        String resultPath = getUriPrefix(content, download, absolute, internal)
123                + "/_attachments-flipbook/"
124                + contentName 
125                + URLEncoder.encodePath(path)
126                + "/_contents"
127                + URLEncoder.encodePath(resource.getPath()).replaceAll(":", "%3A")
128                + "/book.html";
129        
130        if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType()))
131        {
132            return super.resolve(uri, download, absolute, internal);
133        }
134        
135        new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start();
136        
137        // Encode twice
138        return URLEncoder.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 URLEncoder.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                + resource.getResourcePath()
191                + "/pages" 
192                + "/thumbnail_"
193                + height + "x" + width
194                + ".png";
195        
196        return URLEncoder.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 URLEncoder.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                + resource.getResourcePath()
255                + "/pages" 
256                + "/thumbnail_max"
257                + maxHeight + "x" + maxWidth
258                + ".png";
259        
260        return URLEncoder.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}