    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("&amp;");
    221                }
    222                else if (c == '\"') {
    223                    result.append("&quot;");
    224                }
    225                else if (c == '<') {
    226                    result.append("&lt;");
    227                }
    228                else if (c == '>') {
    229                    result.append("&gt;");
    230                }
    231                else if (c == '\'') {
    232                    result.append("&#39;");
    233                }
    234                else if (c == '\\') {
    235                    result.append("&#092;");
    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    }