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 org.apache.wiki.api.core.Attachment; 022import org.apache.wiki.api.core.Context; 023import org.apache.wiki.api.core.ContextEnum; 024import org.apache.wiki.api.core.Engine; 025import org.apache.wiki.api.exceptions.PluginException; 026import org.apache.wiki.api.exceptions.ProviderException; 027import org.apache.wiki.api.plugin.Plugin; 028import org.apache.wiki.attachment.AttachmentManager; 029import org.apache.wiki.util.TextUtil; 030 031import java.util.Map; 032 033/** 034 * Provides an image plugin for better control than is possible with a simple image inclusion. 035 * <br> Most parameters are equivalents of the html image attributes. 036 * 037 * <p>Parameters : </p> 038 * <ul> 039 * <li><b>src</b> - the source (a URL) of the image (required parameter)</li> 040 * <li><b>align</b> - the alignment of the image</li> 041 * <li><b>height</b> - the height of the image</li> 042 * <li><b>width</b> - the width of the image</li> 043 * <li><b>alt</b> - alternate text</li> 044 * <li><b>caption</b> - the caption for the image</li> 045 * <li><b>link</b> - the hyperlink for the image</li> 046 * <li><b>target</b> - the target (frame) to be used for opening the image</li> 047 * <li><b>style</b> - the style attribute of the image</li> 048 * <li><b>class</b> - the associated class for the image</li> 049 * <li><b>border</b> - the border for the image</li> 050 * <li><b>title</b> - the title for the image, can be presented as a tooltip to the user</li> 051 * </ul> 052 * 053 * @since 2.1.4. 054 */ 055// FIXME: It is not yet possible to do wiki internal links. In order to do this cleanly, a TranslatorReader revamp is needed. 056 057public class Image implements Plugin { 058 059 /** The parameter name for setting the src. Value is <tt>{@value}</tt>. */ 060 public static final String PARAM_SRC = "src"; 061 /** The parameter name for setting the align. Value is <tt>{@value}</tt>. */ 062 public static final String PARAM_ALIGN = "align"; 063 /** The parameter name for setting the height. Value is <tt>{@value}</tt>. */ 064 public static final String PARAM_HEIGHT = "height"; 065 /** The parameter name for setting the width. Value is <tt>{@value}</tt>. */ 066 public static final String PARAM_WIDTH = "width"; 067 /** The parameter name for setting the alt. Value is <tt>{@value}</tt>. */ 068 public static final String PARAM_ALT = "alt"; 069 /** The parameter name for setting the caption. Value is <tt>{@value}</tt>. */ 070 public static final String PARAM_CAPTION = "caption"; 071 /** The parameter name for setting the link. Value is <tt>{@value}</tt>. */ 072 public static final String PARAM_LINK = "link"; 073 /** The parameter name for setting the target. Value is <tt>{@value}</tt>. */ 074 public static final String PARAM_TARGET = "target"; 075 /** The parameter name for setting the style. Value is <tt>{@value}</tt>. */ 076 public static final String PARAM_STYLE = "style"; 077 /** The parameter name for setting the class. Value is <tt>{@value}</tt>. */ 078 public static final String PARAM_CLASS = "class"; 079 // public static final String PARAM_MAP = "map"; 080 /** The parameter name for setting the border. Value is <tt>{@value}</tt>. */ 081 public static final String PARAM_BORDER = "border"; 082 /** The parameter name for setting the title. Value is <tt>{@value}</tt>. */ 083 public static final String PARAM_TITLE = "title"; 084 085 /** 086 * This method is used to clean away things like quotation marks which 087 * a malicious user could use to stop processing and insert javascript. 088 */ 089 private static String getCleanParameter( final Map< String, String > params, final String paramId ) { 090 return TextUtil.replaceEntities( params.get( paramId ) ); 091 } 092 093 /** 094 * {@inheritDoc} 095 */ 096 @Override 097 public String execute( final Context context, final Map<String, String> params ) throws PluginException { 098 final Engine engine = context.getEngine(); 099 String src = getCleanParameter( params, PARAM_SRC ); 100 final String align = getCleanParameter( params, PARAM_ALIGN ); 101 final String ht = getCleanParameter( params, PARAM_HEIGHT ); 102 final String wt = getCleanParameter( params, PARAM_WIDTH ); 103 final String alt = getCleanParameter( params, PARAM_ALT ); 104 final String caption = getCleanParameter( params, PARAM_CAPTION ); 105 final String link = getCleanParameter( params, PARAM_LINK ); 106 String target = getCleanParameter( params, PARAM_TARGET ); 107 final String style = getCleanParameter( params, PARAM_STYLE ); 108 final String cssclass= getCleanParameter( params, PARAM_CLASS ); 109 // String map = getCleanParameter( params, PARAM_MAP ); 110 final String border = getCleanParameter( params, PARAM_BORDER ); 111 final String title = getCleanParameter( params, PARAM_TITLE ); 112 113 if( src == null ) { 114 throw new PluginException("Parameter 'src' is required for Image plugin"); 115 } 116 117 //if( cssclass == null ) cssclass = "imageplugin"; 118 119 if( target != null && !validTargetValue(target) ) { 120 target = null; // not a valid value so ignore 121 } 122 123 try { 124 final AttachmentManager mgr = engine.getManager( AttachmentManager.class ); 125 final Attachment att = mgr.getAttachmentInfo( context, src ); 126 127 if( att != null ) { 128 src = context.getURL( ContextEnum.PAGE_ATTACH.getRequestContext(), att.getName() ); 129 } 130 } catch( final ProviderException e ) { 131 throw new PluginException( "Attachment info failed: " + e.getMessage() ); 132 } 133 134 final StringBuilder result = new StringBuilder(); 135 136 result.append( "<table border=\"0\" class=\"imageplugin\"" ); 137 138 if( title != null ) { 139 result.append( " title=\"" ).append( title ).append( "\"" ); 140 } 141 142 if( align != null ) { 143 if( align.equals( "center" ) ) { 144 result.append( " style=\"margin-left: auto; margin-right: auto; text-align:center; vertical-align:middle;\"" ); 145 } else { 146 result.append( " style=\"float:" ).append( align ).append( ";\"" ); 147 } 148 } 149 150 result.append( ">\n" ); 151 152 if( caption != null ) { 153 result.append( "<caption>" ).append( caption ).append( "</caption>\n" ); 154 } 155 156 // move css class and style to the container of the image, so it doesn't affect the caption 157 result.append( "<tr><td" ); 158 159 if( cssclass != null ) { 160 result.append( " class=\"" ).append( cssclass ).append( "\"" ); 161 } 162 163 if( style != null ) { 164 result.append( " style=\"" ).append( style ); 165 166 // Make sure that we add a ";" to the end of the style string 167 if( result.charAt( result.length()-1 ) != ';' ) result.append(";"); 168 169 result.append("\""); 170 } 171 172 result.append( ">" ); 173 174 if( link != null ) { 175 result.append( "<a href=\"" ).append( link ).append( "\"" ); 176 if( target != null ) { 177 result.append( " target=\"" ).append( target ).append( "\"" ); 178 } 179 result.append(">"); 180 } 181 182 result.append( "<img src=\"" ).append( src ).append( "\"" ); 183 184 if( ht != null ) { 185 result.append( " height=\"" ).append( ht ).append( "\"" ); 186 } 187 if( wt != null ) { 188 result.append( " width=\"" ).append( wt ).append( "\"" ); 189 } 190 if( alt != null ) { 191 result.append( " alt=\"" ).append( alt ).append( "\"" ); 192 } 193 if( border != null ) { 194 result.append( " border=\"" ).append( border ).append( "\"" ); 195 } 196 // if( map != null ) result.append(" map=\""+map+"\""); 197 198 result.append(" />"); 199 if( link != null ) { 200 result.append("</a>"); 201 } 202 result.append("</td></tr>\n"); 203 result.append("</table>\n"); 204 205 return result.toString(); 206 } 207 208 private boolean validTargetValue( final String s ) 209 { 210 if( s.equals("_blank") 211 || s.equals("_self") 212 || s.equals("_parent") 213 || s.equals("_top") ) 214 { 215 return true; 216 } 217 else if( !s.isEmpty() ) // check [a-zA-z] 218 { 219 final char c = s.charAt(0); 220 return Character.isLowerCase(c) || Character.isUpperCase(c); 221 } 222 return false; 223 } 224 225}