1:
31: package ;
32:
33: import ;
34: import ;
35: import ;
36: import ;
37: import ;
38: import ;
39:
40:
45: public class FormulaFunction extends AbstractExpression implements Function
46: {
47: private String formulaNamespace;
48: private String formulaExpression;
49: private String formula;
50:
51: private String initialNamespace;
52: private String initialExpression;
53: private String initial;
54: private transient Formula compiledFormula;
55: private boolean initialized;
56:
57: public FormulaFunction()
58: {
59: }
60:
61: private synchronized FormulaContext getFormulaContext()
62: {
63: final ReportContext globalContext = getRuntime().getReportContext();
64: return globalContext.getFormulaContext();
65: }
66:
67: public String getInitial()
68: {
69: return initial;
70: }
71:
72: public String getInitialExpression()
73: {
74: return initialExpression;
75: }
76:
77: public String getInitialNamespace()
78: {
79: return initialNamespace;
80: }
81:
82: public void setInitial(final String initial)
83: {
84: this.initial = initial;
85: if (initial == null)
86: {
87: initialNamespace = null;
88: initialExpression = null;
89: }
90: else
91: {
92: final int separator = initial.indexOf(':');
93: if (separator <= 0 || ((separator + 1) == initial.length()))
94: {
95: if (formula.startsWith("="))
96: {
97: initialNamespace = "report";
98: initialExpression = initial.substring(1);
99: }
100: else
101: {
102:
103: initialNamespace = null;
104: initialExpression = null;
105: }
106: }
107: else
108: {
109: initialNamespace = initial.substring(0, separator);
110: initialExpression = initial.substring(separator + 1);
111: }
112: }
113: }
114:
115:
116: public String getFormula()
117: {
118: return formula;
119: }
120:
121: public String getFormulaNamespace()
122: {
123: return formulaNamespace;
124: }
125:
126: public String getFormulaExpression()
127: {
128: return formulaExpression;
129: }
130:
131: public void setFormula(final String formula)
132: {
133: this.formula = formula;
134: if (formula == null)
135: {
136: formulaNamespace = null;
137: formulaExpression = null;
138: }
139: else
140: {
141: final int separator = formula.indexOf(':');
142: if (separator <= 0 || ((separator + 1) == formula.length()))
143: {
144: if (formula.startsWith("="))
145: {
146: formulaNamespace = "report";
147: formulaExpression = formula.substring(1);
148: }
149: else
150: {
151:
152: formulaNamespace = null;
153: formulaExpression = null;
154: }
155: }
156: else
157: {
158: formulaNamespace = formula.substring(0, separator);
159: formulaExpression = formula.substring(separator + 1);
160: }
161: }
162: this.compiledFormula = null;
163: }
164:
165:
175: public Function advance() throws DataSourceException
176: {
177: try
178: {
179: return (Function) clone();
180: }
181: catch (CloneNotSupportedException e)
182: {
183: throw new DataSourceException("Unable to derive a new instance");
184: }
185: }
186:
187: private Object computeInitialValue()
188: {
189: try
190: {
191: if (initial != null)
192: {
193: final Formula initFormula = new Formula(initialExpression);
194: final ReportFormulaContext context =
195: new ReportFormulaContext(getFormulaContext(), getDataRow());
196: context.setDeclaringElement(getRuntime().getDeclaringParent());
197: try
198: {
199: initFormula.initialize(context);
200: return initFormula.evaluate();
201: }
202: finally
203: {
204: context.setDeclaringElement(null);
205: context.setDataRow(null);
206: }
207: }
208:
209:
210: return computeRegularValue();
211: }
212: catch (Exception e)
213: {
214: Log.debug ("Failed to compute the initial value.");
215: return null;
216: }
217: }
218:
219: private Object computeRegularValue()
220: {
221: try
222: {
223: if (compiledFormula == null)
224: {
225: compiledFormula = new Formula(formulaExpression);
226: }
227:
228: final ReportFormulaContext context =
229: new ReportFormulaContext(getFormulaContext(), getDataRow());
230: context.setDeclaringElement(getRuntime().getDeclaringParent());
231: try
232: {
233: compiledFormula.initialize(context);
234: return compiledFormula.evaluate();
235: }
236: finally
237: {
238: context.setDeclaringElement(null);
239: context.setDataRow(null);
240: }
241: }
242: catch (Exception e)
243: {
244: Log.debug ("Failed to compute the regular value.", e);
245: return null;
246: }
247: }
248:
249:
255: public Object computeValue() throws DataSourceException
256: {
257: try
258: {
259: if (initialized == false)
260: {
261: initialized = true;
262: return computeInitialValue();
263: }
264: return computeRegularValue();
265: }
266: catch (Exception e)
267: {
268: return null;
269: }
270: }
271:
272:
281: public Object clone() throws CloneNotSupportedException
282: {
283: final FormulaFunction o = (FormulaFunction) super.clone();
284: if (compiledFormula != null)
285: {
286: o.compiledFormula = (Formula) compiledFormula.clone();
287: }
288: return o;
289: }
290:
291:
292:
299: public Formula getCompiledFormula()
300: throws ParseException
301: {
302: if (compiledFormula == null)
303: {
304: compiledFormula = new Formula(formulaExpression);
305: }
306: return compiledFormula;
307: }
308: }