001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * ---------------------- 028 * ImageMapUtilities.java 029 * ---------------------- 030 * (C) Copyright 2004-2009, by Richard Atkinson and Contributors. 031 * 032 * Original Author: Richard Atkinson; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * Fawad Halim - bug 2690293; 035 * 036 * Changes 037 * ------- 038 * 02-Aug-2004 : Initial version (RA); 039 * 13-Jan-2005 : Renamed ImageMapUtilities (DG); 040 * 19-Jan-2005 : Reversed order of tags for chart entities to get correct 041 * layering (DG); 042 * ------------- JFREECHART 1.0.x --------------------------------------------- 043 * 06-Feb-2006 : API doc updates (DG); 044 * 04-Dec-2007 : Added htmlEscape() method, and escape 'name' in 045 * getImageMap() (DG); 046 * 19-Mar-2009 : Added javascriptEscape() method - see bug 2690293 by FH (DG); 047 * 25-Mar-2009 : Reimplemented javascriptEscape() (DG); 048 * 049 */ 050 051 package org.jfree.chart.imagemap; 052 053 import java.io.IOException; 054 import java.io.PrintWriter; 055 056 import org.jfree.chart.ChartRenderingInfo; 057 import org.jfree.chart.entity.ChartEntity; 058 import org.jfree.chart.entity.EntityCollection; 059 import org.jfree.util.StringUtils; 060 061 /** 062 * Collection of utility methods related to producing image maps. 063 * Functionality was originally in {@link org.jfree.chart.ChartUtilities}. 064 */ 065 public class ImageMapUtilities { 066 067 /** 068 * Writes an image map to an output stream. 069 * 070 * @param writer the writer (<code>null</code> not permitted). 071 * @param name the map name (<code>null</code> not permitted). 072 * @param info the chart rendering info (<code>null</code> not permitted). 073 * 074 * @throws java.io.IOException if there are any I/O errors. 075 */ 076 public static void writeImageMap(PrintWriter writer, String name, 077 ChartRenderingInfo info) throws IOException { 078 079 // defer argument checking... 080 ImageMapUtilities.writeImageMap(writer, name, info, 081 new StandardToolTipTagFragmentGenerator(), 082 new StandardURLTagFragmentGenerator()); 083 084 } 085 086 /** 087 * Writes an image map to an output stream. 088 * 089 * @param writer the writer (<code>null</code> not permitted). 090 * @param name the map name (<code>null</code> not permitted). 091 * @param info the chart rendering info (<code>null</code> not permitted). 092 * @param useOverLibForToolTips whether to use OverLIB for tooltips 093 * (http://www.bosrup.com/web/overlib/). 094 * 095 * @throws java.io.IOException if there are any I/O errors. 096 */ 097 public static void writeImageMap(PrintWriter writer, 098 String name, ChartRenderingInfo info, 099 boolean useOverLibForToolTips) throws IOException { 100 101 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator = null; 102 if (useOverLibForToolTips) { 103 toolTipTagFragmentGenerator 104 = new OverLIBToolTipTagFragmentGenerator(); 105 } 106 else { 107 toolTipTagFragmentGenerator 108 = new StandardToolTipTagFragmentGenerator(); 109 } 110 ImageMapUtilities.writeImageMap(writer, name, info, 111 toolTipTagFragmentGenerator, 112 new StandardURLTagFragmentGenerator()); 113 114 } 115 116 /** 117 * Writes an image map to an output stream. 118 * 119 * @param writer the writer (<code>null</code> not permitted). 120 * @param name the map name (<code>null</code> not permitted). 121 * @param info the chart rendering info (<code>null</code> not permitted). 122 * @param toolTipTagFragmentGenerator a generator for the HTML fragment 123 * that will contain the tooltip text (<code>null</code> not permitted 124 * if <code>info</code> contains tooltip information). 125 * @param urlTagFragmentGenerator a generator for the HTML fragment that 126 * will contain the URL reference (<code>null</code> not permitted if 127 * <code>info</code> contains URLs). 128 * 129 * @throws java.io.IOException if there are any I/O errors. 130 */ 131 public static void writeImageMap(PrintWriter writer, String name, 132 ChartRenderingInfo info, 133 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, 134 URLTagFragmentGenerator urlTagFragmentGenerator) 135 throws IOException { 136 137 writer.println(ImageMapUtilities.getImageMap(name, info, 138 toolTipTagFragmentGenerator, urlTagFragmentGenerator)); 139 } 140 141 /** 142 * Creates an image map element that complies with the XHTML 1.0 143 * specification. 144 * 145 * @param name the map name (<code>null</code> not permitted). 146 * @param info the chart rendering info (<code>null</code> not permitted). 147 * 148 * @return The map element. 149 */ 150 public static String getImageMap(String name, ChartRenderingInfo info) { 151 return ImageMapUtilities.getImageMap(name, info, 152 new StandardToolTipTagFragmentGenerator(), 153 new StandardURLTagFragmentGenerator()); 154 } 155 156 /** 157 * Creates an image map element that complies with the XHTML 1.0 158 * specification. 159 * 160 * @param name the map name (<code>null</code> not permitted). 161 * @param info the chart rendering info (<code>null</code> not permitted). 162 * @param toolTipTagFragmentGenerator a generator for the HTML fragment 163 * that will contain the tooltip text (<code>null</code> not permitted 164 * if <code>info</code> contains tooltip information). 165 * @param urlTagFragmentGenerator a generator for the HTML fragment that 166 * will contain the URL reference (<code>null</code> not permitted if 167 * <code>info</code> contains URLs). 168 * 169 * @return The map tag. 170 */ 171 public static String getImageMap(String name, ChartRenderingInfo info, 172 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, 173 URLTagFragmentGenerator urlTagFragmentGenerator) { 174 175 StringBuffer sb = new StringBuffer(); 176 sb.append("<map id=\"" + htmlEscape(name) + "\" name=\"" 177 + htmlEscape(name) + "\">"); 178 sb.append(StringUtils.getLineSeparator()); 179 EntityCollection entities = info.getEntityCollection(); 180 if (entities != null) { 181 int count = entities.getEntityCount(); 182 for (int i = count - 1; i >= 0; i--) { 183 ChartEntity entity = entities.getEntity(i); 184 if (entity.getToolTipText() != null 185 || entity.getURLText() != null) { 186 String area = entity.getImageMapAreaTag( 187 toolTipTagFragmentGenerator, 188 urlTagFragmentGenerator); 189 if (area.length() > 0) { 190 sb.append(area); 191 sb.append(StringUtils.getLineSeparator()); 192 } 193 } 194 } 195 } 196 sb.append("</map>"); 197 return sb.toString(); 198 199 } 200 201 /** 202 * Returns a string that is equivalent to the input string, but with 203 * special characters converted to HTML escape sequences. 204 * 205 * @param input the string to escape (<code>null</code> not permitted). 206 * 207 * @return A string with characters escaped. 208 * 209 * @since 1.0.9 210 */ 211 public static String htmlEscape(String input) { 212 if (input == null) { 213 throw new IllegalArgumentException("Null 'input' argument."); 214 } 215 StringBuffer result = new StringBuffer(); 216 int length = input.length(); 217 for (int i = 0; i < length; i++) { 218 char c = input.charAt(i); 219 if (c == '&') { 220 result.append("&"); 221 } 222 else if (c == '\"') { 223 result.append("""); 224 } 225 else if (c == '<') { 226 result.append("<"); 227 } 228 else if (c == '>') { 229 result.append(">"); 230 } 231 else if (c == '\'') { 232 result.append("'"); 233 } 234 else if (c == '\\') { 235 result.append("\"); 236 } 237 else { 238 result.append(c); 239 } 240 } 241 return result.toString(); 242 } 243 244 /** 245 * Returns a string that is equivalent to the input string, but with 246 * special characters converted to JavaScript escape sequences. 247 * 248 * @param input the string to escape (<code>null</code> not permitted). 249 * 250 * @return A string with characters escaped. 251 * 252 * @since 1.0.13 253 */ 254 public static String javascriptEscape(String input) { 255 if (input == null) { 256 throw new IllegalArgumentException("Null 'input' argument."); 257 } 258 StringBuffer result = new StringBuffer(); 259 int length = input.length(); 260 for (int i = 0; i < length; i++) { 261 char c = input.charAt(i); 262 if (c == '\"') { 263 result.append("\\\""); 264 } 265 else if (c == '\'') { 266 result.append("\\'"); 267 } 268 else if (c == '\\') { 269 result.append("\\\\"); 270 } 271 else { 272 result.append(c); 273 } 274 } 275 return result.toString(); 276 } 277 }