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; 024 025import org.ametys.cms.transformation.URIResolver; 026import org.ametys.core.util.FilenameUtils; 027import org.ametys.core.util.URIUtils; 028import org.ametys.plugins.explorer.resources.Resource; 029import org.ametys.plugins.repository.AmetysObject; 030import org.ametys.plugins.repository.AmetysObjectResolver; 031import org.ametys.plugins.repository.UnknownAmetysObjectException; 032import org.ametys.runtime.plugin.component.PluginAware; 033import org.ametys.web.editor.ResourceURIResolver; 034import org.ametys.web.explorer.ResourceHelper; 035 036/** 037 * {@link URIResolver} for type "explorer-flipbook".<br> 038 * These links point to a document file from the resource explorer converted to flash. 039 */ 040public class Resource2FlipbookUriResolver extends ResourceURIResolver implements PluginAware, Configurable 041{ 042 /** The plugin name. */ 043 protected String _pluginName; 044 045 /** The type. */ 046 protected String _type; 047 048 /** The cache resource component. */ 049 protected ConvertResource2ImagesComponent _resourceComponent; 050 051 @Override 052 public void service(ServiceManager serviceManager) throws ServiceException 053 { 054 super.service(serviceManager); 055 _resourceComponent = (ConvertResource2ImagesComponent) serviceManager.lookup(ConvertResource2ImagesComponent.ROLE); 056 } 057 058 @Override 059 public void setPluginInfo(String pluginName, String featureName, String id) 060 { 061 _pluginName = pluginName; 062 } 063 064 public void configure(Configuration configuration) throws ConfigurationException 065 { 066 _type = configuration.getChild("type").getValue("explorer-flipbook"); 067 } 068 069 @Override 070 public String getType() 071 { 072 return _type; 073 } 074 075 @Override 076 protected String getResourcePath(Resource resource) 077 { 078 String fullPath = resource.getPath(); 079 080 if (fullPath.startsWith(ResourceHelper.SHARED_RESOURCE_PATH)) 081 { 082 return fullPath.substring(ResourceHelper.SHARED_RESOURCE_PATH.length()); 083 } 084 else 085 { 086 return super.getResourcePath(resource); 087 } 088 } 089 090 @Override 091 public String resolve(String uri, boolean download, boolean absolute, boolean internal) 092 { 093 String path; 094 Resource resource = null; 095 String siteName = null; 096 try 097 { 098 resource = (Resource) _resolver.resolveById(uri); 099 path = getResourcePath(resource); 100 siteName = _getSiteName(resource); 101 } 102 catch (UnknownAmetysObjectException e) 103 { 104 getLogger().warn("Link to unexisting resource " + uri); 105 return ""; 106 } 107 108 if (!_resourceComponent.isMimeTypeSupported(resource.getMimeType())) 109 { 110 return super.resolve(uri, download, absolute, internal); 111 } 112 113 StringBuilder result = new StringBuilder(); 114 115 // _plugins/flipbook/<site>/_[shared-]resource-flipbook/<path>/<to>/<resource>/<fileName>/book.html 116 result.append(_getUriPrefix(resource, download, internal, absolute, true)) 117 .append("/_") 118 .append(getRealPrefix(resource, "resource-flipbook")) 119 .append(FilenameUtils.encodePath(path)) 120 .append("/book.html"); 121 122 new CacheThread(resource.getId(), siteName, _resolver, getLogger()).start(); 123 124 // Encode twice 125 return URIUtils.encodePath(result.toString()); 126 } 127 128 @Override 129 public String resolveImage(String uri, int height, int width, boolean download, boolean absolute, boolean internal) 130 { 131 Resource resource = null; 132 String path; 133 try 134 { 135 resource = (Resource) _resolver.resolveById(uri); 136 String fullPath = resource.getPath(); 137 138 if (fullPath.startsWith(ResourceHelper.SHARED_RESOURCE_PATH)) 139 { 140 path = fullPath.substring(ResourceHelper.SHARED_RESOURCE_PATH.length()); 141 } 142 else 143 { 144 path = resource.getResourcePath(); 145 } 146 } 147 catch (UnknownAmetysObjectException e) 148 { 149 getLogger().warn("Link to unexisting resource " + uri); 150 return ""; 151 } 152 153 if (!_resourceComponent.isMimeTypeSupported(resource.getMimeType())) 154 { 155 String defaultPath = _getUriPrefix(resource, download, absolute, internal, true) 156 + "/pages" 157 + "/error" 158 + "/thumbnail_" 159 + height + "x" + width 160 + ".png"; 161 162 return URIUtils.encodePath(defaultPath); 163 } 164 165 new CacheThread(resource.getId(), _getSiteName(resource), _resolver, getLogger()).start(); 166 167 String result = _getUriPrefix(resource, download, absolute, internal, false) 168 + "/" + getRealPrefix(resource, "resources") 169 + FilenameUtils.encodePath(path) 170 + "/pages" 171 + "/thumbnail_" 172 + height + "x" + width 173 + ".png"; 174 175 return URIUtils.encodePath(result); 176 } 177 178 @Override 179 public String resolveBoundedImage(String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal) 180 { 181 if (maxHeight == 0 && maxWidth == 0) 182 { 183 return resolve(uri, download, absolute, internal); 184 } 185 186 Resource resource = null; 187 String path; 188 try 189 { 190 resource = (Resource) _resolver.resolveById(uri); 191 String fullPath = resource.getPath(); 192 193 if (fullPath.startsWith(ResourceHelper.SHARED_RESOURCE_PATH)) 194 { 195 path = fullPath.substring(ResourceHelper.SHARED_RESOURCE_PATH.length()); 196 } 197 else 198 { 199 path = resource.getResourcePath(); 200 } 201 } 202 catch (UnknownAmetysObjectException e) 203 { 204 getLogger().warn("Link to unexisting resource " + uri); 205 return ""; 206 } 207 208 if (!_resourceComponent.isMimeTypeSupported(resource.getMimeType())) 209 { 210 String defaultPath = _getUriPrefix(resource, download, absolute, internal, true) 211 + "/pages" 212 + "/error" 213 + "/thumbnail_max" 214 + maxHeight + "x" + maxWidth 215 + ".png"; 216 217 return URIUtils.encodePath(defaultPath); 218 } 219 220 new CacheThread(resource.getId(), _getSiteName(resource), _resolver, getLogger()).start(); 221 222 String result = _getUriPrefix(resource, download, absolute, internal, false) 223 + "/" + getRealPrefix(resource, "resources") 224 + FilenameUtils.encodePath(path) 225 + "/pages" 226 + "/thumbnail_max" 227 + maxHeight + "x" + maxWidth 228 + ".png"; 229 230 return URIUtils.encodePath(result); 231 } 232 233 private String _getUriPrefix(AmetysObject object, boolean download, boolean absolute, boolean internal, boolean addSiteNameForSharedResources) 234 { 235 Resource resource = (Resource) object; 236 String siteName = _getSiteName(resource); 237 238 String uriPrefix = super.getUriPrefix(object, download, absolute, internal); 239 240 uriPrefix += "/_plugins/" + _pluginName; 241 242 if (addSiteNameForSharedResources || !resource.getPath().startsWith(ResourceHelper.SHARED_RESOURCE_PATH)) 243 { 244 uriPrefix += "/" + siteName; 245 } 246 247 return uriPrefix; 248 } 249 250 private class CacheThread extends Thread 251 { 252 private String _resourceId; 253 private String _siteName; 254 private Logger _cacheLogger; 255 private AmetysObjectResolver _cacheResolver; 256 257 public CacheThread(String resourceId, String siteName, AmetysObjectResolver cacheResolver, Logger cacheLogger) 258 { 259 _resourceId = resourceId; 260 _siteName = siteName; 261 _cacheLogger = cacheLogger; 262 _cacheResolver = cacheResolver; 263 setDaemon(true); 264 setName("FlipbookCacheResourceCreator"); 265 } 266 267 @Override 268 public void run() 269 { 270 try 271 { 272 Resource resource = _cacheResolver.resolveById(_resourceId); 273 _resourceComponent.doCache(resource, _siteName); 274 } 275 catch (Exception e) 276 { 277 _cacheLogger.error("An error occurred during creating cache for resource : " + _resourceId); 278 } 279 } 280 } 281}