001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2013, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ---------------------- 028 * ImageMapUtilities.java 029 * ---------------------- 030 * (C) Copyright 2004-2013, 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 * 02-Jul-2013 : Use ParamChecks (DG); 049 * 050 */ 051 052package org.jfree.chart.imagemap; 053 054import java.io.IOException; 055import java.io.PrintWriter; 056 057import org.jfree.chart.ChartRenderingInfo; 058import org.jfree.chart.entity.ChartEntity; 059import org.jfree.chart.entity.EntityCollection; 060import org.jfree.chart.util.ParamChecks; 061import org.jfree.util.StringUtils; 062 063/** 064 * Collection of utility methods related to producing image maps. 065 * Functionality was originally in {@link org.jfree.chart.ChartUtilities}. 066 */ 067public class ImageMapUtilities { 068 069 /** 070 * Writes an image map to an output stream. 071 * 072 * @param writer the writer (<code>null</code> not permitted). 073 * @param name the map name (<code>null</code> not permitted). 074 * @param info the chart rendering info (<code>null</code> not permitted). 075 * 076 * @throws java.io.IOException if there are any I/O errors. 077 */ 078 public static void writeImageMap(PrintWriter writer, String name, 079 ChartRenderingInfo info) throws IOException { 080 081 // defer argument checking... 082 ImageMapUtilities.writeImageMap(writer, name, info, 083 new StandardToolTipTagFragmentGenerator(), 084 new StandardURLTagFragmentGenerator()); 085 086 } 087 088 /** 089 * Writes an image map to an output stream. 090 * 091 * @param writer the writer (<code>null</code> not permitted). 092 * @param name the map name (<code>null</code> not permitted). 093 * @param info the chart rendering info (<code>null</code> not permitted). 094 * @param useOverLibForToolTips whether to use OverLIB for tooltips 095 * (http://www.bosrup.com/web/overlib/). 096 * 097 * @throws java.io.IOException if there are any I/O errors. 098 */ 099 public static void writeImageMap(PrintWriter writer, 100 String name, ChartRenderingInfo info, 101 boolean useOverLibForToolTips) throws IOException { 102 103 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator; 104 if (useOverLibForToolTips) { 105 toolTipTagFragmentGenerator 106 = new OverLIBToolTipTagFragmentGenerator(); 107 } 108 else { 109 toolTipTagFragmentGenerator 110 = new StandardToolTipTagFragmentGenerator(); 111 } 112 ImageMapUtilities.writeImageMap(writer, name, info, 113 toolTipTagFragmentGenerator, 114 new StandardURLTagFragmentGenerator()); 115 116 } 117 118 /** 119 * Writes an image map to an output stream. 120 * 121 * @param writer the writer (<code>null</code> not permitted). 122 * @param name the map name (<code>null</code> not permitted). 123 * @param info the chart rendering info (<code>null</code> not permitted). 124 * @param toolTipTagFragmentGenerator a generator for the HTML fragment 125 * that will contain the tooltip text (<code>null</code> not permitted 126 * if <code>info</code> contains tooltip information). 127 * @param urlTagFragmentGenerator a generator for the HTML fragment that 128 * will contain the URL reference (<code>null</code> not permitted if 129 * <code>info</code> contains URLs). 130 * 131 * @throws java.io.IOException if there are any I/O errors. 132 */ 133 public static void writeImageMap(PrintWriter writer, String name, 134 ChartRenderingInfo info, 135 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, 136 URLTagFragmentGenerator urlTagFragmentGenerator) 137 throws IOException { 138 139 writer.println(ImageMapUtilities.getImageMap(name, info, 140 toolTipTagFragmentGenerator, urlTagFragmentGenerator)); 141 } 142 143 /** 144 * Creates an image map element that complies with the XHTML 1.0 145 * specification. 146 * 147 * @param name the map name (<code>null</code> not permitted). 148 * @param info the chart rendering info (<code>null</code> not permitted). 149 * 150 * @return The map element. 151 */ 152 public static String getImageMap(String name, ChartRenderingInfo info) { 153 return ImageMapUtilities.getImageMap(name, info, 154 new StandardToolTipTagFragmentGenerator(), 155 new StandardURLTagFragmentGenerator()); 156 } 157 158 /** 159 * Creates an image map element that complies with the XHTML 1.0 160 * specification. 161 * 162 * @param name the map name (<code>null</code> not permitted). 163 * @param info the chart rendering info (<code>null</code> not permitted). 164 * @param toolTipTagFragmentGenerator a generator for the HTML fragment 165 * that will contain the tooltip text (<code>null</code> not permitted 166 * if <code>info</code> contains tooltip information). 167 * @param urlTagFragmentGenerator a generator for the HTML fragment that 168 * will contain the URL reference (<code>null</code> not permitted if 169 * <code>info</code> contains URLs). 170 * 171 * @return The map tag. 172 */ 173 public static String getImageMap(String name, ChartRenderingInfo info, 174 ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, 175 URLTagFragmentGenerator urlTagFragmentGenerator) { 176 177 StringBuilder sb = new StringBuilder(); 178 sb.append("<map id=\"").append(htmlEscape(name)); 179 sb.append("\" name=\"").append(htmlEscape(name)).append("\">"); 180 sb.append(StringUtils.getLineSeparator()); 181 EntityCollection entities = info.getEntityCollection(); 182 if (entities != null) { 183 int count = entities.getEntityCount(); 184 for (int i = count - 1; i >= 0; i--) { 185 ChartEntity entity = entities.getEntity(i); 186 if (entity.getToolTipText() != null 187 || entity.getURLText() != null) { 188 String area = entity.getImageMapAreaTag( 189 toolTipTagFragmentGenerator, 190 urlTagFragmentGenerator); 191 if (area.length() > 0) { 192 sb.append(area); 193 sb.append(StringUtils.getLineSeparator()); 194 } 195 } 196 } 197 } 198 sb.append("</map>"); 199 return sb.toString(); 200 201 } 202 203 /** 204 * Returns a string that is equivalent to the input string, but with 205 * special characters converted to HTML escape sequences. 206 * 207 * @param input the string to escape (<code>null</code> not permitted). 208 * 209 * @return A string with characters escaped. 210 * 211 * @since 1.0.9 212 */ 213 public static String htmlEscape(String input) { 214 ParamChecks.nullNotPermitted(input, "input"); 215 StringBuilder result = new StringBuilder(); 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 ParamChecks.nullNotPermitted(input, "input"); 256 StringBuilder result = new StringBuilder(); 257 int length = input.length(); 258 for (int i = 0; i < length; i++) { 259 char c = input.charAt(i); 260 if (c == '\"') { 261 result.append("\\\""); 262 } 263 else if (c == '\'') { 264 result.append("\\'"); 265 } 266 else if (c == '\\') { 267 result.append("\\\\"); 268 } 269 else { 270 result.append(c); 271 } 272 } 273 return result.toString(); 274 } 275}