001/* 002 * Copyright 2010 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.cms.transformation; 017 018import java.io.InputStream; 019import java.util.Collections; 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022 023import org.apache.avalon.framework.context.Context; 024import org.apache.avalon.framework.context.ContextException; 025import org.apache.avalon.framework.context.Contextualizable; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029 030import org.ametys.cms.URIPrefixHandler; 031import org.ametys.cms.repository.Content; 032import org.ametys.cms.transformation.ConsistencyChecker.CHECK; 033import org.ametys.core.util.FilenameUtils; 034import org.ametys.core.util.URIUtils; 035import org.ametys.plugins.explorer.resources.Resource; 036import org.ametys.plugins.repository.AmetysObject; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.repository.UnknownAmetysObjectException; 039import org.ametys.runtime.i18n.I18nizableText; 040 041/** 042 * {@link URIResolver} for type "attachment".<br> 043 * These links point to a file from the attachments of the current Content. 044 */ 045public class AttachmentURIResolver extends AbstractURIResolver implements Serviceable, Contextualizable 046{ 047 /** Regular expression for contents stored under plugins */ 048 protected static final Pattern __PLUGIN_CONTENT_PATTERN = Pattern.compile("^/ametys:plugins/([^/]+)/ametys:contents/(.*)$"); 049 /** The ametys resolver */ 050 protected AmetysObjectResolver _resolver; 051 /** The avalon context */ 052 protected Context _context; 053 /** The URI prefix handler */ 054 protected URIPrefixHandler _prefixHandler; 055 056 @Override 057 public void contextualize(Context context) throws ContextException 058 { 059 _context = context; 060 } 061 062 @Override 063 public void service(ServiceManager manager) throws ServiceException 064 { 065 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 066 _prefixHandler = (URIPrefixHandler) manager.lookup(URIPrefixHandler.ROLE); 067 } 068 069 @Override 070 public String getType() 071 { 072 return "attachment-content"; 073 } 074 075 @Override 076 public String _resolve(String uri, String uriArgument, boolean download, boolean absolute, boolean internal) 077 { 078 String path; 079 Content content = null; 080 String contentName = null; 081 082 try 083 { 084 Resource resource = (Resource) _resolver.resolveById(uri); 085 path = resource.getResourcePath(); 086 087 AmetysObject ao = resource; 088 do 089 { 090 ao = ao.getParent(); 091 } 092 while (ao != null && !(ao instanceof Content)); 093 094 if (ao == null) 095 { 096 throw new IllegalArgumentException("The given attachment URI should be a content attachment."); 097 } 098 099 content = (Content) ao; 100 contentName = content.getName(); 101 } 102 catch (UnknownAmetysObjectException e) 103 { 104 getLogger().warn("Link to unexisting resource " + uri); 105 return ""; 106 } 107 catch (Exception e) 108 { 109 throw new IllegalStateException(e); 110 } 111 112 String filename = FilenameUtils.encodePath(path); 113 String basePath = org.apache.commons.io.FilenameUtils.removeExtension(filename); 114 String extension = org.apache.commons.io.FilenameUtils.getExtension(filename); 115 116 StringBuilder resultPath = new StringBuilder(); 117 resultPath.append(getUriPrefix(content, download, absolute, internal)); 118 119 Matcher m = __PLUGIN_CONTENT_PATTERN.matcher(content.getPath()); 120 if (m.matches()) 121 { 122 String pluginName = m.group(1); 123 resultPath.append("/") 124 .append(pluginName) 125 .append("/_plugin-attachment/"); 126 } 127 else 128 { 129 resultPath.append("/_attachment/"); 130 } 131 132 resultPath.append(contentName) 133 .append(basePath) 134 .append(uriArgument) 135 .append(extension.isEmpty() ? "" : "." + extension); 136 137 return URIUtils.encodeURI(resultPath.toString(), download ? Collections.singletonMap("download", "true") : null); 138 } 139 140 /** 141 * Get the URI prefix 142 * @param object The object 143 * @param download true if the pointed resource is to be downloaded. 144 * @param absolute true if the url must be absolute 145 * @param internal true to get an internal URI. 146 * @return the URI prefix 147 */ 148 protected String getUriPrefix (AmetysObject object, boolean download, boolean internal, boolean absolute) 149 { 150 return _prefixHandler.computeUriPrefix(absolute, internal); 151 } 152 153 154 @Override 155 protected String resolveImageAsBase64(String uri, int height, int width, int maxHeight, int maxWidth, int cropHeight, int cropWidth) 156 { 157 try 158 { 159 Resource resource = (Resource) _resolver.resolveById(uri); 160 161 try (InputStream dataIs = resource.getInputStream()) 162 { 163 return ImageResolverHelper.resolveImageAsBase64(dataIs, resource.getMimeType(), height, width, maxHeight, maxWidth, cropHeight, cropWidth); 164 } 165 } 166 catch (UnknownAmetysObjectException e) 167 { 168 getLogger().warn("Link to unexisting resource " + uri); 169 return ""; 170 } 171 catch (Exception e) 172 { 173 throw new IllegalStateException(e); 174 } 175 } 176 177 @Override 178 public CHECK checkLink(String uri, boolean shortTest) 179 { 180 try 181 { 182 _resolver.resolveById(uri); 183 return CHECK.SUCCESS; 184 } 185 catch (UnknownAmetysObjectException e) 186 { 187 return CHECK.NOT_FOUND; 188 } 189 } 190 191 @Override 192 public I18nizableText getLabel(String uri) 193 { 194 try 195 { 196 Resource resource = (Resource) _resolver.resolveById(uri); 197 return new I18nizableText("plugin.cms", "PLUGINS_CMS_LINK_ATTACHMENT_LABEL", Collections.singletonList(resource.getResourcePath())); 198 } 199 catch (UnknownAmetysObjectException e) 200 { 201 return new I18nizableText("plugin.cms", "PLUGINS_CMS_LINK_ATTACHMENT_UNKNOWN"); 202 } 203 } 204}