    001    /* ========================================================================
    002     * JCommon : a free general purpose class library for the Java(tm) platform
    003     * ========================================================================
    004     *
    005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jcommon/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     * ParserUtil.java
    029     * ---------------
    030     * (C)opyright 2002-2005, by Thomas Morgner and Contributors.
    031     *
    032     * Original Author:  Thomas Morgner (taquera@sherito.org);
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * $Id: ParserUtil.java,v 1.3 2005/10/18 13:25:44 mungady Exp $
    036     *
    037     * Changes
    038     * -------
    039     * 21-May-2002 : Contains utility functions to make parsing easier.
    040     * 10-Dec-2002 : Fixed issues reported by Checkstyle (DG);
    041     * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon;
    042     * 23-Sep-2003 : Minor Javadoc updates (DG);
    043     *
    044     */
    045    package org.jfree.xml;
    046
    047    import java.awt.BasicStroke;
    048    import java.awt.Color;
    049    import java.awt.Stroke;
    050    import java.awt.geom.Rectangle2D;
    051    import java.lang.reflect.Field;
    052
    053    import org.xml.sax.Attributes;
    054    import org.xml.sax.SAXException;
    055
    056    /**
    057     * Basic helper functions to ease up the process of parsing.
    058     *
    059     * @author Thomas Morgner
    060     */
    061    public class ParserUtil {
    062
    063        /**
    064         * Parses the string <code>text</code> into an int. If text is null or does not
    065         * contain a parsable value, the message given in <code>message</code> is used to
    066         * throw a SAXException.
    067         *
    068         * @param text  the text to parse.
    069         * @param message  the error message if parsing fails.
    070         *
    071         * @return the int value.
    072         *
    073         * @throws SAXException if there is a problem with the parsing.
    074         */
    075        public static int parseInt(final String text, final String message) throws SAXException {
    076            if (text == null) {
    077                throw new SAXException(message);
    078            }
    079
    080            try {
    081                return Integer.parseInt(text);
    082            }
    083            catch (NumberFormatException nfe) {
    084                throw new SAXException("NumberFormatError: " + message);
    085            }
    086        }
    087
    088        /**
    089         * Parses an integer.
    090         *
    091         * @param text  the text to parse.
    092         * @param defaultVal  the default value.
    093         *
    094         * @return the integer.
    095         */
    096        public static int parseInt(final String text, final int defaultVal) {
    097            if (text == null) {
    098                return defaultVal;
    099            }
    100
    101            try {
    102                return Integer.parseInt(text);
    103            }
    104            catch (NumberFormatException nfe) {
    105                return defaultVal;
    106            }
    107        }
    108
    109        /**
    110         * Parses the string <code>text</code> into an float. If text is null or does not
    111         * contain a parsable value, the message given in <code>message</code> is used to
    112         * throw a SAXException.
    113         *
    114         * @param text  the text to parse.
    115         * @param message  the error message if parsing fails.
    116         *
    117         * @return the float value.
    118         *
    119         * @throws SAXException if there is a problem with the parsing.
    120         */
    121        public static float parseFloat(final String text, final String message) throws SAXException {
    122            if (text == null) {
    123                throw new SAXException(message);
    124            }
    125            try {
    126                return Float.parseFloat(text);
    127            }
    128            catch (NumberFormatException nfe) {
    129                throw new SAXException("NumberFormatError: " + message);
    130            }
    131        }
    132
    133        /**
    134         * Parses the string <code>text</code> into an float. If text is null or does not
    135         * contain a parsable value, the message given in <code>message</code> is used to
    136         * throw a SAXException.
    137         *
    138         * @param text  the text to parse.
    139         * @param defaultVal the defaultValue returned if parsing fails.
    140         *
    141         * @return the float value.
    142         */
    143        public static float parseFloat(final String text, final float defaultVal) {
    144            if (text == null) {
    145                return defaultVal;
    146            }
    147            try {
    148                return Float.parseFloat(text);
    149            }
    150            catch (NumberFormatException nfe) {
    151                return defaultVal;
    152            }
    153        }
    154
    155        /**
    156         * Parses a boolean. If the string <code>text</code> contains the value of "true", the
    157         * true value is returned, else false is returned.
    158         *
    159         * @param text  the text to parse.
    160         * @param defaultVal  the default value.
    161         *
    162         * @return a boolean.
    163         */
    164        public static boolean parseBoolean(final String text, final boolean defaultVal) {
    165            if (text == null) {
    166                return defaultVal;
    167            }
    168            return text.equalsIgnoreCase("true");
    169        }
    170
    171        /**
    172         * Parses a string. If the <code>text</code> is null, defaultval is returned.
    173         *
    174         * @param text  the text to parse.
    175         * @param defaultVal  the default value.
    176         *
    177         * @return a string.
    178         */
    179        public static String parseString(final String text, final String defaultVal) {
    180            if (text == null) {
    181                return defaultVal;
    182            }
    183            return text;
    184        }
    185
    186        /**
    187         * Creates a basic stroke given the width contained as float in the given string.
    188         * If the string could not be parsed into a float, a basic stroke with the width of
    189         * 1 is returned.
    190         *
    191         * @param weight  a string containing a number (the stroke weight).
    192         *
    193         * @return the stroke.
    194         */
    195        public static Stroke parseStroke(final String weight) {
    196            try {
    197                if (weight != null) {
    198                    final Float w = new Float(weight);
    199                    return new BasicStroke(w.floatValue());
    200                }
    201            }
    202            catch (NumberFormatException nfe) {
    203                //Log.warn("Invalid weight for stroke", nfe);
    204            }
    205            return new BasicStroke(1);
    206        }
    207
    208        /**
    209         * Parses a color entry. If the entry is in hexadecimal or ocal notation, the color is
    210         * created using Color.decode(). If the string denotes a constant name of on of the color
    211         * constants defined in java.awt.Color, this constant is used.
    212         * <p>
    213         * As fallback the color black is returned if no color can be parsed.
    214         *
    215         * @param color  the color (as a string).
    216         *
    217         * @return the paint.
    218         */
    219        public static Color parseColor(final String color) {
    220            return parseColor(color, Color.black);
    221        }
    222
    223        /**
    224         * Parses a color entry. If the entry is in hexadecimal or octal notation, the color is
    225         * created using Color.decode(). If the string denotes a constant name of one of the color
    226         * constants defined in java.awt.Color, this constant is used.
    227         * <p>
    228         * As fallback the supplied default value is returned if no color can be parsed.
    229         *
    230         * @param color  the color (as a string).
    231         * @param defaultValue  the default value (returned if no color can be parsed).
    232         *
    233         * @return the paint.
    234         */
    235        public static Color parseColor(final String color, final Color defaultValue) {
    236            if (color == null) {
    237                return defaultValue;
    238            }
    239            try {
    240                // get color by hex or octal value
    241                return Color.decode(color);
    242            }
    243            catch (NumberFormatException nfe) {
    244                // if we can't decode lets try to get it by name
    245                try {
    246                    // try to get a color by name using reflection
    247                    // black is used for an instance and not for the color itselfs
    248                    final Field f = Color.class.getField(color);
    249
    250                    return (Color) f.get(null);
    251                }
    252                catch (Exception ce) {
    253                    //Log.warn("No such Color : " + color);
    254                    // if we can't get any color return black
    255                    return defaultValue;
    256                }
    257            }
    258        }
    259
    260
    261        /**
    262         * Parses a position of an element. If a relative postion is given, the returnvalue
    263         * is a negative number between 0 and -100.
    264         *
    265         * @param value  the value.
    266         * @param exceptionMessage  the exception message.
    267         *
    268         * @return the float value.
    269         *
    270         * @throws SAXException if there is a problem parsing the string.
    271         */
    272        public static float parseRelativeFloat(final String value, final String exceptionMessage)
    273            throws SAXException {
    274            if (value == null) {
    275                throw new SAXException(exceptionMessage);
    276            }
    277            final String tvalue = value.trim();
    278            if (tvalue.endsWith("%")) {
    279                final String number = tvalue.substring(0, tvalue.indexOf("%"));
    280                final float f = parseFloat(number, exceptionMessage) * -1.0f;
    281                return f;
    282            }
    283            else {
    284                return parseFloat(tvalue, exceptionMessage);
    285            }
    286        }
    287
    288        /**
    289         * Parses an element position. The position is stored in the attributes "x", "y", "width" and
    290         * "height". The attributes are allowed to have relative notion.
    291         *
    292         * @param atts  the attributes.
    293         *
    294         * @return the element position.
    295         *
    296         * @throws SAXException if there is a problem getting the element position.
    297         */
    298        public static Rectangle2D getElementPosition(final Attributes atts) throws SAXException {
    299            final float x = ParserUtil.parseRelativeFloat(atts.getValue("x"),
    300                "Element x not specified");
    301            final float y = ParserUtil.parseRelativeFloat(atts.getValue("y"),
    302                "Element y not specified");
    303            final float w = ParserUtil.parseRelativeFloat(atts.getValue("width"),
    304                "Element width not specified");
    305            final float h = ParserUtil.parseRelativeFloat(atts.getValue("height"),
    306                "Element height not specified");
    307            final Rectangle2D.Float retval = new Rectangle2D.Float(x, y, w, h);
    308            return retval;
    309        }
    310
    311    }