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-flipbook".<br> 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 AmetysObject ao = resource; 095 do 096 { 097 ao = ao.getParent(); 098 } 099 while (ao != null && !(ao instanceof Content)); 100 101 if (ao == null) 102 { 103 throw new IllegalArgumentException("The given attachment URI should be a content attachment."); 104 } 105 106 content = (Content) ao; 107 contentName = content.getName(); 108 109 if (content instanceof WebContent) 110 { 111 siteName = ((WebContent) content).getSiteName(); 112 } 113 else 114 { 115 siteName = (String) request.getAttribute("siteName"); 116 if (siteName == null) 117 { 118 siteName = (String) request.getAttribute("site"); 119 } 120 } 121 122 } 123 catch (UnknownAmetysObjectException e) 124 { 125 getLogger().warn("Link to unexisting resource " + uri); 126 return ""; 127 } 128 catch (Exception e) 129 { 130 throw new IllegalStateException(e); 131 } 132 133 134 // plugins/flipbook/<siteName>/_attachments-flipbook/<contentName>/<fileName>/book.html 135 String resultPath = getUriPrefix(content, download, absolute, internal) 136 + "/_attachments-flipbook/" 137 + contentName 138 + FilenameUtils.encodePath(path) 139 + "/_contents" 140 + FilenameUtils.encodePath(resource.getPath()) 141 + "/book.html"; 142 143 if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType())) 144 { 145 return super.resolve(uri, download, absolute, internal); 146 } 147 148 new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start(); 149 150 return URIUtils.encodePath(resultPath.toString()); 151 } 152 153 @Override 154 public String resolveImage(String uri, int height, int width, boolean download, boolean absolute, boolean internal) 155 { 156 return _resolveImage(uri, "", height, width, download, absolute, internal); 157 } 158 159 @Override 160 public String resolveBoundedImage(String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal) 161 { 162 return _resolveImage(uri, "max", maxHeight, maxWidth, download, absolute, internal); 163 } 164 165 private String _resolveImage(String uri, String uriArgument, int height, int width, boolean download, boolean absolute, boolean internal) 166 { 167 if (height == 0 && width == 0) 168 { 169 return resolve(uri, download, absolute, internal); 170 } 171 172 Content content = null; 173 String contentName = null; 174 String siteName = null; 175 Resource resource = null; 176 try 177 { 178 resource = (Resource) _resolver.resolveById(uri); 179 180 AmetysObject ao = resource; 181 do 182 { 183 ao = ao.getParent(); 184 } 185 while (ao != null && !(ao instanceof Content)); 186 187 if (ao == null) 188 { 189 throw new IllegalArgumentException("The given attachment URI should be a content attachment."); 190 } 191 192 content = (Content) ao; 193 contentName = content.getName(); 194 195 if (content instanceof WebContent) 196 { 197 siteName = ((WebContent) content).getSiteName(); 198 } 199 } 200 catch (UnknownAmetysObjectException e) 201 { 202 getLogger().warn("Link to unexisting resource " + uri); 203 return ""; 204 } 205 catch (Exception e) 206 { 207 throw new IllegalStateException(e); 208 } 209 210 if (!_attachmentComponent.isMimeTypeSupported(resource.getMimeType())) 211 { 212 String defaultPath = getUriPrefix(content, download, absolute, internal) 213 + "/pages" 214 + "/error" 215 + "/thumbnail_" 216 + uriArgument 217 + height + "x" + width 218 + ".png"; 219 220 return URIUtils.encodePath(defaultPath); 221 } 222 223 new CacheThread(resource.getId(), contentName, siteName, _resolver, getLogger()).start(); 224 225 String result = getUriPrefix(content, download, absolute, internal) 226 + "/contents/" 227 + contentName 228 + "/attachments" 229 + FilenameUtils.encodePath(resource.getResourcePath()) 230 + "/pages" 231 + "/thumbnail_" 232 + uriArgument 233 + height + "x" + width 234 + ".png"; 235 236 return URIUtils.encodePath(result); 237 } 238 239 @Override 240 protected String getUriPrefix(AmetysObject object, boolean download, boolean absolute, boolean internal) 241 { 242 Request request = ContextHelper.getRequest(_context); 243 244 String siteName = null; 245 if (object instanceof SiteAwareAmetysObject) 246 { 247 siteName = ((SiteAwareAmetysObject) object).getSiteName(); 248 } 249 else 250 { 251 siteName = (String) request.getAttribute("siteName"); 252 253 if (siteName == null) 254 { 255 siteName = (String) request.getAttribute("site"); 256 } 257 } 258 259 String initialSiteName = (String) ContextHelper.getRequest(_context).getAttribute("initialSiteName"); 260 boolean isInitialSite = initialSiteName == null || initialSiteName.equals(siteName); 261 262 String uriPrefix; 263 if (internal) 264 { 265 uriPrefix = "cocoon://" + siteName; 266 } 267 else if (absolute || !isInitialSite) 268 { 269 uriPrefix = _webPrefixHandler.getAbsoluteUriPrefix(siteName); 270 } 271 else 272 { 273 uriPrefix = _webPrefixHandler.getUriPrefix(siteName); 274 } 275 276 uriPrefix += "/_plugins/" + _pluginName + "/" + siteName; 277 return uriPrefix; 278 } 279 280 private class CacheThread extends Thread 281 { 282 private String _resourceId; 283 private String _siteName; 284 private String _contentName; 285 private Logger _cacheLogger; 286 private AmetysObjectResolver _cacheResolver; 287 288 /** 289 * Constructor 290 * @param resourceId The id of resource 291 * @param contentName The content's name 292 * @param siteName The site name 293 * @param cacheResolver The ametys object resolver 294 * @param cacheLogger The logger 295 */ 296 public CacheThread(String resourceId, String contentName, String siteName, AmetysObjectResolver cacheResolver, Logger cacheLogger) 297 { 298 _resourceId = resourceId; 299 _siteName = siteName; 300 _cacheLogger = cacheLogger; 301 _cacheResolver = cacheResolver; 302 _contentName = contentName; 303 setDaemon(true); 304 setName("FlipbookCacheAttachmentCreator"); 305 } 306 307 @Override 308 public void run() 309 { 310 try 311 { 312 Resource resource = _cacheResolver.resolveById(_resourceId); 313 _attachmentComponent.doCache(resource, _contentName, _siteName); 314 } 315 catch (Exception e) 316 { 317 _cacheLogger.error("An error occurred during creating cache for resource : " + _resourceId); 318 } 319 } 320 } 321}