Frames | No Frames |
1: /** 2: * ======================================== 3: * JFreeReport : a free Java report library 4: * ======================================== 5: * 6: * Project Info: http://reporting.pentaho.org/ 7: * 8: * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors. 9: * 10: * This library is free software; you can redistribute it and/or modify it under the terms 11: * of the GNU Lesser General Public License as published by the Free Software Foundation; 12: * either version 2.1 of the License, or (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 15: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16: * See the GNU Lesser General Public License for more details. 17: * 18: * You should have received a copy of the GNU Lesser General Public License along with this 19: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20: * Boston, MA 02111-1307, USA. 21: * 22: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 23: * in the United States and other countries.] 24: * 25: * ------------ 26: * $Id: PropertyLookupParser.java 2725 2007-04-01 18:49:29Z taqua $ 27: * ------------ 28: * (C) Copyright 2000-2005, by Object Refinery Limited. 29: * (C) Copyright 2005-2007, by Pentaho Corporation. 30: */ 31: 32: package org.jfree.report.util; 33: 34: import java.io.Serializable; 35: 36: /** 37: * The property lookup parser is used to resolve embedded references to 38: * properties within strings. 39: * <p> 40: * The default format of the property specification is: 41: * <code>${property-name}</code> where 'property-name is the name of the 42: * property. If this construct is found within the text, it is replaced with 43: * the value returned from a call to "lookupVariable". 44: * 45: * @author Thomas Morgner 46: */ 47: public abstract class PropertyLookupParser implements Serializable 48: { 49: /** A parse state indicator signaling that the parser is outside a property. */ 50: private static final int EXPECT_DOLLAR = 0; 51: /** A parse state indicator signaling that an open brace is expected. */ 52: private static final int EXPECT_OPEN_BRACE = 1; 53: 54: /** 55: * A parse state indicator signaling that a closed brace is expected. All chars 56: * received, which are not equal to the closed brace, count as property name. 57: */ 58: private static final int EXPECT_CLOSE_BRACE = 2; 59: /** The initial marker char, a $ by default. */ 60: private char markerChar; 61: /** The closing brace char. */ 62: private char closingBraceChar; 63: /** The opening brace char. */ 64: private char openingBraceChar; 65: /** The escape char. */ 66: private char escapeChar; 67: 68: /** 69: * Initializes the parser to the default format of "${..}". The 70: * escape char will be a backslash. 71: */ 72: protected PropertyLookupParser () 73: { 74: markerChar = '$'; 75: closingBraceChar = '}'; 76: openingBraceChar = '{'; 77: escapeChar = '\\'; 78: } 79: 80: /** 81: * Returns the currently defined closed-brace char. 82: * 83: * @return the closed-brace char. 84: */ 85: public char getClosingBraceChar () 86: { 87: return closingBraceChar; 88: } 89: 90: /** 91: * Defines the closing brace character. 92: * @param closingBraceChar the closed-brace character. 93: */ 94: public void setClosingBraceChar (final char closingBraceChar) 95: { 96: this.closingBraceChar = closingBraceChar; 97: } 98: 99: /** 100: * Returns the escape char. 101: * @return the escape char. 102: */ 103: public char getEscapeChar () 104: { 105: return escapeChar; 106: } 107: 108: /** 109: * Defines the escape char. 110: * 111: * @param escapeChar the escape char 112: */ 113: public void setEscapeChar (final char escapeChar) 114: { 115: this.escapeChar = escapeChar; 116: } 117: 118: /** 119: * Returns the currently defined opening-brace char. 120: * 121: * @return the opening-brace char. 122: */ 123: public char getOpeningBraceChar () 124: { 125: return openingBraceChar; 126: } 127: 128: /** 129: * Defines the opening brace character. 130: * @param openingBraceChar the opening-brace character. 131: */ 132: public void setOpeningBraceChar (final char openingBraceChar) 133: { 134: this.openingBraceChar = openingBraceChar; 135: } 136: 137: /** 138: * Returns initial property marker char. 139: * @return the initial property marker character. 140: */ 141: public char getMarkerChar () 142: { 143: return markerChar; 144: } 145: 146: /** 147: * Defines initial property marker char. 148: * @param markerChar the initial property marker character. 149: */ 150: public void setMarkerChar (final char markerChar) 151: { 152: this.markerChar = markerChar; 153: } 154: 155: /** 156: * Translates the given string and resolves the embedded property references. 157: * 158: * @param value the raw value, 159: * @return the fully translated string. 160: */ 161: public String translateAndLookup (final String value) 162: { 163: if (value == null) 164: { 165: return null; 166: } 167: 168: final char[] chars = value.toCharArray(); 169: final StringBuffer result = new StringBuffer(chars.length); 170: boolean haveEscape = false; 171: int state = EXPECT_DOLLAR; 172: final StringBuffer propertyName = new StringBuffer(); 173: 174: for (int i = 0; i < chars.length; i++) 175: { 176: final char c = chars[i]; 177: 178: if (haveEscape) 179: { 180: haveEscape = false; 181: if (state == EXPECT_CLOSE_BRACE) 182: { 183: propertyName.append(c); 184: } 185: else 186: { 187: result.append(c); 188: } 189: continue; 190: } 191: 192: if (state == EXPECT_DOLLAR && c == markerChar) 193: { 194: state = EXPECT_OPEN_BRACE; 195: continue; 196: } 197: if (state == EXPECT_OPEN_BRACE) 198: { 199: if (c == openingBraceChar) 200: { 201: state = EXPECT_CLOSE_BRACE; 202: continue; 203: } 204: else 205: { 206: result.append(markerChar); 207: state = 0; 208: } 209: } 210: if (state == EXPECT_CLOSE_BRACE && c == closingBraceChar) 211: { 212: final String s = lookupVariable(propertyName.toString()); 213: if (s == null) 214: { 215: result.append(markerChar); 216: result.append(openingBraceChar); 217: result.append(propertyName); 218: result.append(closingBraceChar); 219: } 220: else 221: { 222: result.append(s); 223: } 224: propertyName.delete(0, propertyName.length()); 225: state = 0; 226: continue; 227: } 228: 229: if (c == escapeChar) 230: { 231: haveEscape = true; 232: continue; 233: } 234: 235: if (state == EXPECT_CLOSE_BRACE) 236: { 237: propertyName.append(c); 238: } 239: else 240: { 241: result.append(c); 242: } 243: } 244: 245: if (state >= EXPECT_OPEN_BRACE) 246: { 247: result.append(markerChar); 248: if (state >= EXPECT_CLOSE_BRACE) 249: { 250: result.append(openingBraceChar); 251: result.append(propertyName); 252: } 253: } 254: return result.toString(); 255: } 256: 257: /** 258: * Looks up the property with the given name. 259: * 260: * @param property the name of the property to look up. 261: * @return the translated value. 262: */ 263: protected abstract String lookupVariable (String property); 264: }