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 }