    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2007, 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-2007, by Richard Atkinson and Contributors.
    031     *
    032     * Original Author:  Richard Atkinson;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * Changes
    036     * -------
    037     * 02-Aug-2004 : Initial version (RA);
    038     * 13-Jan-2005 : Renamed ImageMapUtilities (DG);
    039     * 19-Jan-2005 : Reversed order of tags for chart entities to get correct
    040     *               layering (DG);
    041     * ------------- JFREECHART 1.0.x ---------------------------------------------
    042     * 06-Feb-2006 : API doc updates (DG);
    043     * 04-Dec-2007 : Added htmlEscape() method, and escape 'name' in
    044     *               getImageMap() (DG);
    045     *
    046     */
    047
    048    package org.jfree.chart.imagemap;
    049
    050    import java.io.IOException;
    051    import java.io.PrintWriter;
    052
    053    import org.jfree.chart.ChartRenderingInfo;
    054    import org.jfree.chart.entity.ChartEntity;
    055    import org.jfree.chart.entity.EntityCollection;
    056    import org.jfree.util.StringUtils;
    057
    058    /**
    059     * Collection of utility methods related to producing image maps.
    060     * Functionality was originally in {@link org.jfree.chart.ChartUtilities}.
    061     */
    062    public class ImageMapUtilities {
    063
    064        /**
    065         * Writes an image map to an output stream.
    066         *
    067         * @param writer  the writer (<code>null</code> not permitted).
    068         * @param name  the map name (<code>null</code> not permitted).
    069         * @param info  the chart rendering info (<code>null</code> not permitted).
    070         *
    071         * @throws java.io.IOException if there are any I/O errors.
    072         */
    073        public static void writeImageMap(PrintWriter writer, String name,
    074                                         ChartRenderingInfo info)
    075            throws IOException {
    076
    077            // defer argument checking...
    078            ImageMapUtilities.writeImageMap(writer, name, info,
    079                    new StandardToolTipTagFragmentGenerator(),
    080                    new StandardURLTagFragmentGenerator());
    081
    082        }
    083
    084        /**
    085         * Writes an image map to an output stream.
    086         *
    087         * @param writer  the writer (<code>null</code> not permitted).
    088         * @param name  the map name (<code>null</code> not permitted).
    089         * @param info  the chart rendering info (<code>null</code> not permitted).
    090         * @param useOverLibForToolTips  whether to use OverLIB for tooltips
    091         *                               (http://www.bosrup.com/web/overlib/).
    092         *
    093         * @throws java.io.IOException if there are any I/O errors.
    094         */
    095        public static void writeImageMap(PrintWriter writer,
    096                                         String name,
    097                                         ChartRenderingInfo info,
    098                                         boolean useOverLibForToolTips)
    099            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    }