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