1 /*
2  * JasperReports - Free Java Reporting Library.
3  * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4  * http://www.jaspersoft.com
5  *
6  * Unless you have purchased a commercial license agreement from Jaspersoft,
7  * the following license terms apply:
8  *
9  * This program is part of JasperReports.
10  *
11  * JasperReports is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * JasperReports is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23  */

24 package net.sf.jasperreports.compilers;
25
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import net.sf.jasperreports.engine.JRExpression;
30 import net.sf.jasperreports.engine.JRExpressionChunk;
31 import net.sf.jasperreports.engine.JRRuntimeException;
32 import net.sf.jasperreports.engine.fill.ExpressionValues;
33 import net.sf.jasperreports.engine.fill.FillExpressionDefaultValues;
34 import net.sf.jasperreports.engine.fill.FillExpressionEstimatedValues;
35 import net.sf.jasperreports.engine.fill.FillExpressionOldValues;
36 import net.sf.jasperreports.engine.fill.JREvaluator;
37 import net.sf.jasperreports.engine.fill.JRFillField;
38 import net.sf.jasperreports.engine.fill.JRFillParameter;
39 import net.sf.jasperreports.engine.fill.JRFillVariable;
40 import net.sf.jasperreports.engine.fill.SimpleTextExpressionEvaluator;
41
42 /**
43  * @author Lucian Chirita (lucianc@users.sourceforge.net)
44  */

45 public class StandardExpressionEvaluators implements DirectExpressionEvaluators
46 {
47     
48     private static DirectExpressionEvaluator NULL_PLACEHOLDER = new UniformExpressionEvaluator()
49     {
50         @Override
51         protected Object defaultEvaluate()
52         {
53             throw new UnsupportedOperationException();
54         }
55     };
56     
57     private Map<Integer, DirectExpressionEvaluation> directEvaluations;
58     private DirectExpressionValueFilter valueFilter;
59     
60     private Map<Integer, DirectExpressionEvaluator> evaluators;
61     
62     private JREvaluator evaluator;
63     private Map<String, JRFillParameter> parametersMap;
64     private Map<String, JRFillField> fieldsMap;
65     private Map<String, JRFillVariable> variablesMap;
66     
67     private ExpressionValues defaultValues;
68     private ExpressionValues oldValues;
69     private ExpressionValues estimatedValues;
70
71     public StandardExpressionEvaluators(Map<Integer, DirectExpressionEvaluation> directEvaluations,
72             DirectExpressionValueFilter valueFilter)
73     {
74         this.directEvaluations = directEvaluations;
75         this.valueFilter = valueFilter;
76         
77         this.evaluators = new HashMap<>();
78     }
79     
80     @Override
81     public void init(JREvaluator evaluator, Map<String, JRFillParameter> parametersMap,
82             Map<String, JRFillField> fieldsMap, Map<String, JRFillVariable> variablesMap)
83     {
84         this.evaluator = evaluator;
85         this.parametersMap = parametersMap;
86         this.fieldsMap = fieldsMap;
87         this.variablesMap = variablesMap;
88         
89         this.defaultValues = new FillExpressionDefaultValues(evaluator, parametersMap, fieldsMap, variablesMap);
90         this.oldValues =  new FillExpressionOldValues(evaluator, parametersMap, fieldsMap, variablesMap);
91         this.estimatedValues = new FillExpressionEstimatedValues(evaluator, parametersMap, fieldsMap, variablesMap);
92         
93         this.evaluators.clear();
94     }
95
96     @Override
97     public DirectExpressionEvaluator getEvaluator(JRExpression expression)
98     {
99         int expressionId = expression.getId();
100         DirectExpressionEvaluator evaluator = evaluators.get(expressionId);
101         if (evaluator == null)
102         {
103             DirectExpressionEvaluation directEvaluation = directEvaluation(expression.getId());
104             if (directEvaluation == null)
105             {
106                 evaluator = NULL_PLACEHOLDER;
107             }
108             else
109             {
110                 evaluator = createDirectEvaluator(directEvaluation);
111             }
112             evaluators.put(expressionId, evaluator);
113         }
114         return evaluator == NULL_PLACEHOLDER ? null : evaluator;
115     }
116     
117     protected DirectExpressionEvaluation directEvaluation(int expressionId)
118     {
119         DirectExpressionEvaluation directEvaluation = directEvaluations == null ? null 
120                 : directEvaluations.get(expressionId);
121         return directEvaluation;
122     }
123
124     protected DirectExpressionEvaluator createDirectEvaluator(DirectExpressionEvaluation evaluation)
125     {
126         DirectExpressionEvaluator evaluator;
127         switch (evaluation.getType())
128         {
129         case CONSTANT:
130             evaluator = new ConstantEvaluator(((ConstantExpressionEvaluation) evaluation).getValue());
131             break;
132         case SIMPLE_TEXT:
133             evaluator = new SimpleTextEvaluator(((SimpleTextEvaluation) evaluation).getChunks());
134             break;
135         case PARAMETER:
136             String parameterName = ((ParameterEvaluation) evaluation).getName();
137             JRFillParameter parameter = parametersMap.get(parameterName);
138             if (parameter == null)
139             {
140                 //shout not happen
141                 throw new JRRuntimeException("Did not find parameter " + parameterName);
142             }
143             evaluator = new ParameterEvaluator(parameter);
144             break;
145         case FIELD:
146             String fieldName = ((FieldEvaluation) evaluation).getName();
147             JRFillField field = fieldsMap.get(fieldName);
148             if (field == null)
149             {
150                 //shout not happen
151                 throw new JRRuntimeException("Did not find field " + fieldName);
152             }
153             evaluator = new FieldEvaluator(field);
154             break;
155         case VARIABLE:
156             String variableName = ((VariableEvaluation) evaluation).getName();
157             JRFillVariable variable = variablesMap.get(variableName);
158             if (variable == null)
159             {
160                 //shout not happen
161                 throw new JRRuntimeException("Did not find variable " + variableName);
162             }
163             evaluator = new VariableEvaluator(variable);
164             break;
165         case RESOURCE:
166             evaluator = new ResourceEvaluator(((ResourceEvaluation) evaluation).getMessageKey());
167             break;
168         default:
169             //should not happen
170             throw new JRRuntimeException("Unknown direct expression evaluation type " + evaluation.getType());
171         }
172         return evaluator;
173     }
174     
175     protected Object filterValue(Object value, Class<?> expectedType)
176     {
177         return valueFilter == null ? value : valueFilter.filterValue(value, expectedType);
178     }
179     
180     protected class ConstantEvaluator extends UniformExpressionEvaluator
181     {
182         private Object value;
183         
184         public ConstantEvaluator(Object value)
185         {
186             this.value = value;
187         }
188
189         @Override
190         protected Object defaultEvaluate()
191         {
192             return filterValue(value, null);
193         }
194     }
195     
196     protected class SimpleTextEvaluator implements DirectExpressionEvaluator
197     {
198         private JRExpressionChunk[] chunks;
199         
200         public SimpleTextEvaluator(JRExpressionChunk[] chunks)
201         {
202             this.chunks = chunks;
203         }
204
205         @Override
206         public Object evaluate()
207         {
208             return SimpleTextExpressionEvaluator.evaluate(chunks, defaultValues);
209         }
210
211         @Override
212         public Object evaluateOld()
213         {
214             return SimpleTextExpressionEvaluator.evaluate(chunks, oldValues);
215         }
216
217         @Override
218         public Object evaluateEstimated()
219         {
220             return SimpleTextExpressionEvaluator.evaluate(chunks, estimatedValues);
221         }    
222     }
223     
224     protected class ParameterEvaluator extends UniformExpressionEvaluator
225     {
226         private JRFillParameter parameter;
227         
228         public ParameterEvaluator(JRFillParameter parameter)
229         {
230             this.parameter = parameter;
231         }
232
233         @Override
234         protected Object defaultEvaluate()
235         {
236             return filterValue(parameter.getValue(), parameter.getValueClass());
237         }
238     }
239     
240     protected class FieldEvaluator implements DirectExpressionEvaluator
241     {
242         private JRFillField field;
243         
244         public FieldEvaluator(JRFillField field)
245         {
246             this.field = field;
247         }
248
249         @Override
250         public Object evaluate()
251         {
252             return filterValue(field.getValue(), field.getValueClass());
253         }
254
255         @Override
256         public Object evaluateOld()
257         {
258             return filterValue(field.getOldValue(), field.getValueClass());
259         }
260
261         @Override
262         public Object evaluateEstimated()
263         {
264             return filterValue(field.getValue(), field.getValueClass());
265         }
266     }
267     
268     protected class VariableEvaluator implements DirectExpressionEvaluator
269     {
270         private JRFillVariable variable;
271         
272         public VariableEvaluator(JRFillVariable variable)
273         {
274             this.variable = variable;
275         }
276
277         @Override
278         public Object evaluate()
279         {
280             return filterValue(variable.getValue(), variable.getValueClass());
281         }
282
283         @Override
284         public Object evaluateOld()
285         {
286             return filterValue(variable.getOldValue(), variable.getValueClass());
287         }
288
289         @Override
290         public Object evaluateEstimated()
291         {
292             return filterValue(variable.getEstimatedValue(), variable.getValueClass());
293         }
294     }
295     
296     protected class ResourceEvaluator extends UniformExpressionEvaluator
297     {
298         private String messageKey;
299         
300         public ResourceEvaluator(String messageKey)
301         {
302             this.messageKey = messageKey;
303         }
304
305         @Override
306         protected Object defaultEvaluate()
307         {
308             return filterValue(evaluator.str(messageKey), null);
309         }
310     }
311
312 }
313