001/* 002 * Copyright 2017 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.workspaces.project; 017 018import java.io.InputStream; 019import java.util.Collections; 020 021import org.apache.avalon.framework.logger.AbstractLogEnabled; 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.avalon.framework.service.Serviceable; 025 026import org.ametys.cms.data.Binary; 027import org.ametys.cms.transformation.ConsistencyChecker.CHECK; 028import org.ametys.cms.transformation.ImageResolverHelper; 029import org.ametys.cms.transformation.URIResolver; 030import org.ametys.core.util.FilenameUtils; 031import org.ametys.core.util.URIUtils; 032import org.ametys.plugins.repository.UnknownAmetysObjectException; 033import org.ametys.plugins.workspaces.project.objects.Project; 034import org.ametys.runtime.i18n.I18nizableText; 035import org.ametys.web.URIPrefixHandler; 036 037/** 038 * {@link URIResolver} for type "project-metadata".<br> 039 * These links point to a file of a project 040 */ 041public class ProjectMetadataUriResolver extends AbstractLogEnabled implements URIResolver, Serviceable 042{ 043 private ProjectManager _projectManager; 044 private URIPrefixHandler _webPrefixHandler; 045 046 @Override 047 public void service(ServiceManager manager) throws ServiceException 048 { 049 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 050 _webPrefixHandler = (URIPrefixHandler) manager.lookup(URIPrefixHandler.ROLE); 051 } 052 053 @Override 054 public String getType() 055 { 056 return "project-metadata"; 057 } 058 059 public String resolve(String uri, boolean download, boolean absolute, boolean internal) 060 { 061 Project project = null; 062 String projectName = null; 063 String metadataName = null; 064 Binary metadata = null; 065 066 try 067 { 068 String[] path = uri.split(";"); 069 projectName = path[0]; 070 metadataName = path[1]; 071 072 project = _projectManager.getProject(projectName); 073 074 metadata = project.getValue(metadataName); 075 } 076 catch (UnknownAmetysObjectException e) 077 { 078 getLogger().warn("No metadata " + metadataName + " for project " + projectName); 079 return ""; 080 } 081 catch (Exception e) 082 { 083 throw new IllegalStateException(e); 084 } 085 086 StringBuilder resultPath = new StringBuilder(); 087 resultPath.append(getUriPrefix(projectName, download, absolute, false)); 088 089 resultPath.append(project.getName()) 090 .append("/_project-attachments/") 091 .append(metadataName) 092 .append("/") 093 .append(FilenameUtils.encodeName(metadata.getFilename())); 094 095 return URIUtils.encodeURI(resultPath.toString(), download ? Collections.singletonMap("download", "true") : null); 096 } 097 098 @Override 099 public String resolveImage(String uri, int height, int width, boolean download, boolean absolute, boolean internal) 100 { 101 StringBuilder sizeSb = new StringBuilder(); 102 if (width != 0 && height != 0) 103 { 104 sizeSb.append(height).append("x").append(width); 105 } 106 107 return _resolveImage(uri, sizeSb.toString(), download, absolute); 108 } 109 110 @Override 111 public String resolveImageAsBase64(String uri, int height, int width) 112 { 113 return resolveImageAsBase64(uri, height, width, 0, 0, 0, 0); 114 } 115 116 /** 117 * Get an image's bytes encoded as base64, optionally resized. 118 * @param uri the image URI. 119 * @param height the specified height. Ignored if negative. 120 * @param width the specified width. Ignored if negative. 121 * @param maxHeight the maximum image height. Ignored if height or width is specified. 122 * @param maxWidth the maximum image width. Ignored if height or width is specified. 123 * @param cropHeight The cropping height. Ignored if negative. 124 * @param cropWidth The cropping width. Ignored if negative. 125 * @return the image bytes encoded as base64. 126 */ 127 protected String resolveImageAsBase64(String uri, int height, int width, int maxHeight, int maxWidth, int cropHeight, int cropWidth) 128 { 129 Project project = null; 130 String projectName = null; 131 String metadataName = null; 132 Binary metadata = null; 133 134 try 135 { 136 String[] path = uri.split(";"); 137 projectName = path[0]; 138 metadataName = path[1]; 139 140 project = _projectManager.getProject(projectName); 141 142 metadata = project.getValue(metadataName); 143 144 try (InputStream dataIs = metadata.getInputStream()) 145 { 146 return ImageResolverHelper.resolveImageAsBase64(dataIs, metadata.getMimeType(), height, width, maxHeight, maxWidth, cropHeight, cropWidth); 147 } 148 } 149 catch (UnknownAmetysObjectException e) 150 { 151 getLogger().warn("No metadata " + metadataName + " for project " + projectName); 152 return ""; 153 } 154 catch (Exception e) 155 { 156 throw new IllegalStateException(e); 157 } 158 } 159 160 @Override 161 public String resolveBoundedImage(String uri, int maxHeight, int maxWidth, boolean download, boolean absolute, boolean internal) 162 { 163 StringBuilder sizeSb = new StringBuilder(); 164 if (maxHeight != 0 && maxWidth != 0) 165 { 166 sizeSb.append("_max").append(maxHeight).append("x").append(maxWidth); 167 } 168 169 return _resolveImage(uri, sizeSb.toString(), download, absolute); 170 } 171 172 @Override 173 public String resolveBoundedImageAsBase64(String uri, int maxHeight, int maxWidth) 174 { 175 return resolveImageAsBase64(uri, 0, 0, maxHeight, maxWidth, 0, 0); 176 } 177 178 @Override 179 public String resolveCroppedImage(String uri, int cropHeight, int cropWidth, boolean download, boolean absolute, boolean internal) 180 { 181 StringBuilder sizeSb = new StringBuilder(); 182 if (cropHeight != 0 && cropWidth != 0) 183 { 184 sizeSb.append("_crop").append(cropHeight).append("x").append(cropWidth); 185 } 186 187 return _resolveImage(uri, sizeSb.toString(), download, absolute); 188 } 189 190 @Override 191 public String resolveCroppedImageAsBase64(String uri, int cropHeight, int cropWidth) 192 { 193 return resolveImageAsBase64(uri, 0, 0, 0, 0, cropHeight, cropWidth); 194 } 195 196 @Override 197 public CHECK checkLink(String uri, boolean shortTest) 198 { 199 return null; 200 } 201 202 @Override 203 public I18nizableText getLabel(String uri) 204 { 205 return null; 206 } 207 208 /** 209 * Resolves the URI for project's illustration.<br> 210 * @param uri the uri 211 * @param sizeArguments The size arguments 212 * @param download true if the pointed resource is to be downloaded. 213 * @param absolute true if the url must be absolute 214 * @return the path to the image. 215 */ 216 protected String _resolveImage(String uri, String sizeArguments, boolean download, boolean absolute) 217 { 218 Project project = null; 219 String projectName = null; 220 String metadataName = null; 221 Binary metadata = null; 222 223 try 224 { 225 String[] path = uri.split(";"); 226 projectName = path[0]; 227 metadataName = path[1]; 228 229 project = _projectManager.getProject(projectName); 230 231 metadata = project.getValue(metadataName); 232 } 233 catch (UnknownAmetysObjectException e) 234 { 235 getLogger().warn("No metadata " + metadataName + " for project " + projectName); 236 return ""; 237 } 238 catch (Exception e) 239 { 240 throw new IllegalStateException(e); 241 } 242 243 StringBuilder resultPath = new StringBuilder(); 244 resultPath.append(getUriPrefix(projectName, download, absolute, false)); 245 246 String filename = metadata.getFilename(); 247 int i = filename.lastIndexOf("."); 248 String extension = filename.substring(i); 249 filename = filename.substring(0, i); 250 251 resultPath.append("/_project-images/") 252 .append(metadataName) 253 .append("/") 254 .append(FilenameUtils.encodeName(filename)) 255 .append(sizeArguments) 256 .append(extension); 257 258 return URIUtils.encodeURI(resultPath.toString(), download ? Collections.singletonMap("download", "true") : null); 259 } 260 261 /** 262 * Get the URI prefix 263 * @param projectName The project name 264 * @param download true if the pointed resource is to be downloaded. 265 * @param absolute true if the url must be absolute 266 * @param internal true to get an internal URI. 267 * @return the URI prefix 268 */ 269 protected String getUriPrefix (String projectName, boolean download, boolean absolute, boolean internal) 270 { 271 if (internal) 272 { 273 return "cocoon://_workspaces/" + projectName; 274 } 275 else if (absolute) 276 { 277 return _webPrefixHandler.getAbsoluteUriPrefix(projectName) + "/_workspaces/" + projectName; 278 } 279 else 280 { 281 return _webPrefixHandler.getUriPrefix(projectName) + "/_workspaces/" + projectName; 282 } 283 } 284 285}