001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.plugin; 020 021import java.util.Map; 022 023import org.apache.wiki.WikiContext; 024import org.apache.wiki.WikiEngine; 025import org.apache.wiki.api.exceptions.PluginException; 026import org.apache.wiki.api.exceptions.ProviderException; 027import org.apache.wiki.api.plugin.WikiPlugin; 028import org.apache.wiki.attachment.Attachment; 029import org.apache.wiki.attachment.AttachmentManager; 030import org.apache.wiki.util.TextUtil; 031 032/** 033 * Provides an image plugin for better control than is possible with a simple image inclusion. 034 * <br> Most parameters are equivalents of the html image attributes. 035 * 036 * <p>Parameters : </p> 037 * <ul> 038 * <li><b>src</b> - the source (a URL) of the image (required parameter)</li> 039 * <li><b>align</b> - the alignment of the image</li> 040 * <li><b>height</b> - the height of the image</li> 041 * <li><b>width</b> - the width of the image</li> 042 * <li><b>alt</b> - alternate text</li> 043 * <li><b>caption</b> - the caption for the image</li> 044 * <li><b>link</b> - the hyperlink for the image</li> 045 * <li><b>target</b> - the target (frame) to be used for opening the image</li> 046 * <li><b>style</b> - the style attribute of the image</li> 047 * <li><b>class</b> - the associated class for the image</li> 048 * <li><b>border</b> - the border for the image</li> 049 * <li><b>title</b> - the title for the image, can be presented as a tooltip to the user</li> 050 * </ul> 051 * 052 * @since 2.1.4. 053 */ 054// FIXME: It is not yet possible to do wiki internal links. In order to 055// do this cleanly, a TranslatorReader revamp is needed. 056 057public class Image 058 implements WikiPlugin 059{ 060 /** The parameter name for setting the src. Value is <tt>{@value}</tt>. */ 061 public static final String PARAM_SRC = "src"; 062 /** The parameter name for setting the align. Value is <tt>{@value}</tt>. */ 063 public static final String PARAM_ALIGN = "align"; 064 /** The parameter name for setting the height. Value is <tt>{@value}</tt>. */ 065 public static final String PARAM_HEIGHT = "height"; 066 /** The parameter name for setting the width. Value is <tt>{@value}</tt>. */ 067 public static final String PARAM_WIDTH = "width"; 068 /** The parameter name for setting the alt. Value is <tt>{@value}</tt>. */ 069 public static final String PARAM_ALT = "alt"; 070 /** The parameter name for setting the caption. Value is <tt>{@value}</tt>. */ 071 public static final String PARAM_CAPTION = "caption"; 072 /** The parameter name for setting the link. Value is <tt>{@value}</tt>. */ 073 public static final String PARAM_LINK = "link"; 074 /** The parameter name for setting the target. Value is <tt>{@value}</tt>. */ 075 public static final String PARAM_TARGET = "target"; 076 /** The parameter name for setting the style. Value is <tt>{@value}</tt>. */ 077 public static final String PARAM_STYLE = "style"; 078 /** The parameter name for setting the class. Value is <tt>{@value}</tt>. */ 079 public static final String PARAM_CLASS = "class"; 080 // public static final String PARAM_MAP = "map"; 081 /** The parameter name for setting the border. Value is <tt>{@value}</tt>. */ 082 public static final String PARAM_BORDER = "border"; 083 /** The parameter name for setting the title. Value is <tt>{@value}</tt>. */ 084 public static final String PARAM_TITLE = "title"; 085 086 /** 087 * This method is used to clean away things like quotation marks which 088 * a malicious user could use to stop processing and insert javascript. 089 */ 090 private static String getCleanParameter( Map<String, String> params, String paramId ) 091 { 092 return TextUtil.replaceEntities( params.get( paramId ) ); 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 public String execute( WikiContext context, Map<String, String> params ) 099 throws PluginException 100 { 101 WikiEngine engine = context.getEngine(); 102 String src = getCleanParameter( params, PARAM_SRC ); 103 String align = getCleanParameter( params, PARAM_ALIGN ); 104 String ht = getCleanParameter( params, PARAM_HEIGHT ); 105 String wt = getCleanParameter( params, PARAM_WIDTH ); 106 String alt = getCleanParameter( params, PARAM_ALT ); 107 String caption = getCleanParameter( params, PARAM_CAPTION ); 108 String link = getCleanParameter( params, PARAM_LINK ); 109 String target = getCleanParameter( params, PARAM_TARGET ); 110 String style = getCleanParameter( params, PARAM_STYLE ); 111 String cssclass= getCleanParameter( params, PARAM_CLASS ); 112 // String map = getCleanParameter( params, PARAM_MAP ); 113 String border = getCleanParameter( params, PARAM_BORDER ); 114 String title = getCleanParameter( params, PARAM_TITLE ); 115 116 if( src == null ) 117 { 118 throw new PluginException("Parameter 'src' is required for Image plugin"); 119 } 120 121 //if( cssclass == null ) cssclass = "imageplugin"; 122 123 if( target != null && !validTargetValue(target) ) 124 { 125 target = null; // not a valid value so ignore 126 } 127 128 try 129 { 130 AttachmentManager mgr = engine.getAttachmentManager(); 131 Attachment att = mgr.getAttachmentInfo( context, src ); 132 133 if( att != null ) 134 { 135 src = context.getURL( WikiContext.ATTACH, att.getName() ); 136 } 137 } 138 catch( ProviderException e ) 139 { 140 throw new PluginException( "Attachment info failed: "+e.getMessage() ); 141 } 142 143 StringBuilder result = new StringBuilder(); 144 145 result.append( "<table border=\"0\" class=\"imageplugin\"" ); 146 147 if( title != null ) 148 { 149 result.append(" title=\""+title+"\""); 150 } 151 152 if( align != null ) 153 { 154 if( align.equals("center") ) 155 { 156 result.append(" style=\"margin-left: auto; margin-right: auto; text-align:center; vertical-align:middle;\""); 157 } 158 else 159 { 160 result.append(" style=\"float:" + align + ";\""); 161 } 162 } 163 164 result.append( ">\n" ); 165 166 if( caption != null ) 167 { 168 result.append("<caption>"+caption+"</caption>\n"); 169 } 170 171 //move css class and style to the container of the image, 172 //so it doesn't affect the caption 173 result.append( "<tr><td" ); 174 175 if( cssclass != null ) 176 { 177 result.append(" class=\""+cssclass+"\""); 178 } 179 180 if( style != null ) 181 { 182 result.append(" style=\""+style); 183 184 // Make sure that we add a ";" to the end of the style string 185 if( result.charAt( result.length()-1 ) != ';' ) result.append(";"); 186 187 result.append("\""); 188 } 189 190 result.append( ">" ); 191 192 if( link != null ) 193 { 194 result.append("<a href=\""+link+"\""); 195 if( target != null ) 196 { 197 result.append(" target=\""+target+"\""); 198 } 199 result.append(">"); 200 } 201 202 result.append( "<img src=\""+src+"\"" ); 203 204 if( ht != null ) result.append(" height=\""+ht+"\""); 205 if( wt != null ) result.append(" width=\""+wt+"\""); 206 if( alt != null ) result.append(" alt=\""+alt+"\""); 207 if( border != null ) result.append(" border=\""+border+"\""); 208 // if( map != null ) result.append(" map=\""+map+"\""); 209 210 result.append(" />"); 211 if( link != null ) result.append("</a>"); 212 result.append("</td></tr>\n"); 213 214 result.append("</table>\n"); 215 216 return result.toString(); 217 } 218 219 private boolean validTargetValue( String s ) 220 { 221 if( s.equals("_blank") 222 || s.equals("_self") 223 || s.equals("_parent") 224 || s.equals("_top") ) 225 { 226 return true; 227 } 228 else if( s.length() > 0 ) // check [a-zA-z] 229 { 230 char c = s.charAt(0); 231 return Character.isLowerCase(c) || Character.isUpperCase(c); 232 } 233 return false; 234 } 235 236}