001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.base;
029:
030: import java.io.Serializable;
031: import java.util.StringTokenizer;
032:
033: import net.sf.jasperreports.engine.JRConstants;
034: import net.sf.jasperreports.engine.JRExpression;
035: import net.sf.jasperreports.engine.JRExpressionChunk;
036: import net.sf.jasperreports.engine.JRRuntimeException;
037: import net.sf.jasperreports.engine.util.JRClassLoader;
038:
039: /**
040: * @author Teodor Danciu (teodord@users.sourceforge.net)
041: * @version $Id: JRBaseExpression.java 1712 2007-04-30 18:04:51Z teodord $
042: */
043: public class JRBaseExpression implements JRExpression, Serializable {
044:
045: /**
046: *
047: */
048: private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID;
049:
050: /**
051: *
052: */
053: protected String valueClassName = null;
054: protected String valueClassRealName = null;
055: protected int id = 0;
056:
057: protected transient Class valueClass = null;
058:
059: /**
060: *
061: */
062: private JRExpressionChunk[] chunks = null;
063:
064: /**
065: *
066: */
067: private static int lastId = 0;
068:
069: /**
070: *
071: */
072: protected JRBaseExpression() {
073: }
074:
075: /**
076: * Creates a copy of an expression.
077: *
078: * @param expression the original expression
079: * @param factory the base object factory
080: * @param expressionId if not null, the created expression will use it as ID
081: * instead of the original expressions's ID
082: */
083: protected JRBaseExpression(JRExpression expression,
084: JRBaseObjectFactory factory, Integer expressionId) {
085: factory.put(expression, this );
086:
087: valueClassName = expression.getValueClassName();
088: if (expressionId == null) {
089: id = expression.getId();
090: } else {
091: id = expressionId.intValue();
092: }
093:
094: /* */
095: JRExpressionChunk[] jrChunks = expression.getChunks();
096: if (jrChunks != null && jrChunks.length > 0) {
097: chunks = new JRExpressionChunk[jrChunks.length];
098: for (int i = 0; i < chunks.length; i++) {
099: chunks[i] = factory.getExpressionChunk(jrChunks[i]);
100: }
101: }
102: }
103:
104: /**
105: * Creates a copy of an expression.
106: *
107: * @param expression the original expression
108: * @param factory the base object factory
109: */
110: protected JRBaseExpression(JRExpression expression,
111: JRBaseObjectFactory factory) {
112: this (expression, factory, null);
113: }
114:
115: /**
116: *
117: */
118: private static synchronized int getNextId() {
119: return lastId++;
120: }
121:
122: /**
123: *
124: */
125: public void regenerateId() {
126: id = getNextId();
127: }
128:
129: /**
130: *
131: */
132: public Class getValueClass() {
133: if (valueClass == null) {
134: String className = getValueClassRealName();
135: if (className != null) {
136: try {
137: valueClass = JRClassLoader
138: .loadClassForName(className);
139: } catch (ClassNotFoundException e) {
140: throw new JRRuntimeException(e);
141: }
142: }
143: }
144:
145: return valueClass;
146: }
147:
148: /**
149: *
150: */
151: public String getValueClassName() {
152: return valueClassName;
153: }
154:
155: /**
156: *
157: */
158: private String getValueClassRealName() {
159: if (valueClassRealName == null) {
160: valueClassRealName = JRClassLoader
161: .getClassRealName(valueClassName);
162: }
163:
164: return valueClassRealName;
165: }
166:
167: /**
168: *
169: */
170: public int getId() {
171: return id;
172: }
173:
174: /**
175: *
176: */
177: public JRExpressionChunk[] getChunks() {
178: return chunks;
179: }
180:
181: /**
182: *
183: */
184: public String getText() {
185: String text = "";
186:
187: chunks = getChunks();
188: if (chunks != null && chunks.length > 0) {
189: StringBuffer sbuffer = new StringBuffer();
190:
191: for (int i = 0; i < chunks.length; i++) {
192: switch (chunks[i].getType()) {
193: case JRExpressionChunk.TYPE_PARAMETER: {
194: sbuffer.append("$P{");
195: sbuffer.append(chunks[i].getText());
196: sbuffer.append("}");
197: break;
198: }
199: case JRExpressionChunk.TYPE_FIELD: {
200: sbuffer.append("$F{");
201: sbuffer.append(chunks[i].getText());
202: sbuffer.append("}");
203: break;
204: }
205: case JRExpressionChunk.TYPE_VARIABLE: {
206: sbuffer.append("$V{");
207: sbuffer.append(chunks[i].getText());
208: sbuffer.append("}");
209: break;
210: }
211: case JRExpressionChunk.TYPE_RESOURCE: {
212: sbuffer.append("$R{");
213: sbuffer.append(chunks[i].getText());
214: sbuffer.append("}");
215: break;
216: }
217: case JRExpressionChunk.TYPE_TEXT:
218: default: {
219: String textChunk = chunks[i].getText();
220: String escapedText = escapeTextChunk(textChunk);
221: sbuffer.append(escapedText);
222: break;
223: }
224: }
225: }
226:
227: text = sbuffer.toString();
228: }
229:
230: return text;
231: }
232:
233: protected String escapeTextChunk(String text) {
234: if (text == null || text.indexOf('$') < 0) {
235: return text;
236: }
237:
238: StringBuffer sb = new StringBuffer(text.length() + 4);
239: StringTokenizer tkzer = new StringTokenizer(text, "$", true);
240: boolean wasDelim = false;
241: while (tkzer.hasMoreElements()) {
242: String token = tkzer.nextToken();
243: if (wasDelim
244: && (token.startsWith("P{")
245: || token.startsWith("F{")
246: || token.startsWith("V{") || token
247: .startsWith("R{"))
248: && token.indexOf('}') > 0) {
249: sb.append('$');
250: }
251: sb.append(token);
252: wasDelim = token.equals("$");
253: }
254:
255: return sb.toString();
256: }
257:
258: }
|