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.transformation.ConsistencyChecker.CHECK; 027import org.ametys.cms.transformation.ImageResolverHelper; 028import org.ametys.cms.transformation.URIResolver; 029import org.ametys.core.util.URLEncoder; 030import org.ametys.plugins.repository.UnknownAmetysObjectException; 031import org.ametys.plugins.repository.metadata.BinaryMetadata; 032import org.ametys.plugins.workspaces.project.objects.Project; 033import org.ametys.runtime.i18n.I18nizableText; 034import org.ametys.web.URIPrefixHandler; 035 036/** 037 * {@link URIResolver} for type "project-metadata".<br> 038 * These links point to a file of a project 039 */ 040public class ProjectMetadataUriResolver extends AbstractLogEnabled implements URIResolver, Serviceable 041{ 042 private ProjectManager _projectManager; 043 private URIPrefixHandler _webPrefixHandler; 044 045 @Override 046 public void service(ServiceManager manager) throws ServiceException 047 { 048 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 049 _webPrefixHandler = (URIPrefixHandler) manager.lookup(URIPrefixHandler.ROLE); 050 } 051 052 @Override 053 public String getType() 054 { 055 return "project-metadata"; 056 } 057 058 public String resolve(String uri, boolean download, boolean absolute, boolean internal) 059 { 060 Project project = null; 061 String projectName = null; 062 String metadataName = null; 063 BinaryMetadata metadata = null; 064 065 try 066 { 067 String[] path = uri.split(";"); 068 projectName = path[0]; 069 metadataName = path[1]; 070 071 project = _projectManager.getProject(projectName); 072 073 metadata = project.getMetadataHolder().getBinaryMetadata(metadataName); 074 } 075 catch (UnknownAmetysObjectException e) 076 { 077 getLogger().warn("No metadata " + metadataName + " for project " + projectName); 078 return ""; 079 } 080 catch (Exception e) 081 { 082 throw new IllegalStateException(e); 083 } 084 085 StringBuilder resultPath = new StringBuilder(); 086 resultPath.append(getUriPrefix(projectName, download, absolute, false)); 087 088 resultPath.append(project.getName()) 089 .append("/_project-attachments/") 090 .append(metadataName) 091 .append("/") 092 .append(metadata.getFilename()); 093 094 String encodePath = URLEncoder.encodePath(resultPath.toString()); 095 return URLEncoder.encodeURI(encodePath, 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 BinaryMetadata 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.getMetadataHolder().getBinaryMetadata(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 // TODO Auto-generated method stub 200 return null; 201 } 202 203 @Override 204 public I18nizableText getLabel(String uri) 205 { 206 // TODO Auto-generated method stub 207 return null; 208 } 209 210 211 /** 212 * Resolves the URI for project's illustration.<br> 213 * @param uri the uri 214 * @param sizeArguments The size arguments 215 * @param download true if the pointed resource is to be downloaded. 216 * @param absolute true if the url must be absolute 217 * @return the path to the image. 218 */ 219 protected String _resolveImage(String uri, String sizeArguments, boolean download, boolean absolute) 220 { 221 Project project = null; 222 String projectName = null; 223 String metadataName = null; 224 BinaryMetadata metadata = null; 225 226 try 227 { 228 String[] path = uri.split(";"); 229 projectName = path[0]; 230 metadataName = path[1]; 231 232 project = _projectManager.getProject(projectName); 233 234 metadata = project.getMetadataHolder().getBinaryMetadata(metadataName); 235 } 236 catch (UnknownAmetysObjectException e) 237 { 238 getLogger().warn("No metadata " + metadataName + " for project " + projectName); 239 return ""; 240 } 241 catch (Exception e) 242 { 243 throw new IllegalStateException(e); 244 } 245 246 StringBuilder resultPath = new StringBuilder(); 247 resultPath.append(getUriPrefix(projectName, download, absolute, false)); 248 249 String filename = metadata.getFilename(); 250 int i = filename.lastIndexOf("."); 251 String extension = filename.substring(i); 252 filename = filename.substring(0, i); 253 254 resultPath.append("/_project-images/") 255 .append(metadataName) 256 .append("/") 257 .append(filename) 258 .append(sizeArguments) 259 .append(extension); 260 261 String encodePath = URLEncoder.encodePath(resultPath.toString()); 262 return URLEncoder.encodeURI(encodePath, download ? Collections.singletonMap("download", "true") : null); 263 } 264 265 /** 266 * Get the URI prefix 267 * @param projectName The project name 268 * @param download true if the pointed resource is to be downloaded. 269 * @param absolute true if the url must be absolute 270 * @param internal true to get an internal URI. 271 * @return the URI prefix 272 */ 273 protected String getUriPrefix (String projectName, boolean download, boolean absolute, boolean internal) 274 { 275 if (internal) 276 { 277 return "cocoon://_workspaces/" + projectName; 278 } 279 else if (absolute) 280 { 281 return _webPrefixHandler.getAbsoluteUriPrefix(projectName) + "/_workspaces/" + projectName; 282 } 283 else 284 { 285 return _webPrefixHandler.getUriPrefix(projectName) + "/_workspaces/" + projectName; 286 } 287 } 288 289}