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:
029: /*
030: * Contributors:
031: * Peter Severin - peter_p_s@users.sourceforge.net
032: * Gaganis Giorgos - gaganis@users.sourceforge.net
033: */
034: package net.sf.jasperreports.compilers;
035:
036: import java.text.SimpleDateFormat;
037: import java.util.ArrayList;
038: import java.util.Arrays;
039: import java.util.Collection;
040: import java.util.Collections;
041: import java.util.HashMap;
042: import java.util.Iterator;
043: import java.util.List;
044: import java.util.Map;
045:
046: import net.sf.jasperreports.engine.JRException;
047: import net.sf.jasperreports.engine.JRExpression;
048: import net.sf.jasperreports.engine.JRExpressionChunk;
049: import net.sf.jasperreports.engine.JRField;
050: import net.sf.jasperreports.engine.JRParameter;
051: import net.sf.jasperreports.engine.JRVariable;
052: import net.sf.jasperreports.engine.design.JRSourceCompileTask;
053: import net.sf.jasperreports.engine.util.JRStringUtil;
054:
055: /**
056: * @author Teodor Danciu (teodord@users.sourceforge.net), Peter Severin (peter_p_s@users.sourceforge.net)
057: * @version $Id: JRGroovyGenerator.java 1609 2007-02-28 09:22:39Z shertage $
058: */
059: public class JRGroovyGenerator {
060:
061: /**
062: *
063: */
064: private static final int EXPR_MAX_COUNT_PER_METHOD = 100;
065:
066: private static Map fieldPrefixMap = null;
067: private static Map variablePrefixMap = null;
068: private static Map methodSuffixMap = null;
069:
070: static {
071: fieldPrefixMap = new HashMap();
072: fieldPrefixMap
073: .put(new Byte(JRExpression.EVALUATION_OLD), "Old");
074: fieldPrefixMap.put(new Byte(JRExpression.EVALUATION_ESTIMATED),
075: "");
076: fieldPrefixMap.put(new Byte(JRExpression.EVALUATION_DEFAULT),
077: "");
078:
079: variablePrefixMap = new HashMap();
080: variablePrefixMap.put(new Byte(JRExpression.EVALUATION_OLD),
081: "Old");
082: variablePrefixMap.put(new Byte(
083: JRExpression.EVALUATION_ESTIMATED), "Estimated");
084: variablePrefixMap.put(
085: new Byte(JRExpression.EVALUATION_DEFAULT), "");
086:
087: methodSuffixMap = new HashMap();
088: methodSuffixMap.put(new Byte(JRExpression.EVALUATION_OLD),
089: "Old");
090: methodSuffixMap.put(
091: new Byte(JRExpression.EVALUATION_ESTIMATED),
092: "Estimated");
093: methodSuffixMap.put(new Byte(JRExpression.EVALUATION_DEFAULT),
094: "");
095: }
096:
097: /**
098: *
099: */
100: protected final JRSourceCompileTask sourceTask;
101:
102: protected Map parametersMap;
103: protected Map fieldsMap;
104: protected Map variablesMap;
105: protected JRVariable[] variables;
106:
107: protected JRGroovyGenerator(JRSourceCompileTask sourceTask) {
108: this .sourceTask = sourceTask;
109:
110: this .parametersMap = sourceTask.getParametersMap();
111: this .fieldsMap = sourceTask.getFieldsMap();
112: this .variablesMap = sourceTask.getVariablesMap();
113: this .variables = sourceTask.getVariables();
114: }
115:
116: /**
117: *
118: */
119: public static String generateClass(JRSourceCompileTask sourceTask)
120: throws JRException {
121: JRGroovyGenerator generator = new JRGroovyGenerator(sourceTask);
122: return generator.generateClass();
123: }
124:
125: protected String generateClass() throws JRException {
126: StringBuffer sb = new StringBuffer();
127:
128: generateClassStart(sb);
129:
130: generateDeclarations(sb);
131:
132: generateInitMethod(sb);
133: generateInitParamsMethod(sb);
134: if (fieldsMap != null) {
135: generateInitFieldsMethod(sb);
136: }
137: generateInitVarsMethod(sb);
138:
139: List expressions = sourceTask.getExpressions();
140: sb.append(this .generateMethod(JRExpression.EVALUATION_DEFAULT,
141: expressions));
142: if (sourceTask.isOnlyDefaultEvaluation()) {
143: List empty = new ArrayList();
144: sb.append(this .generateMethod(JRExpression.EVALUATION_OLD,
145: empty));
146: sb.append(this .generateMethod(
147: JRExpression.EVALUATION_ESTIMATED, empty));
148: } else {
149: sb.append(this .generateMethod(JRExpression.EVALUATION_OLD,
150: expressions));
151: sb.append(this .generateMethod(
152: JRExpression.EVALUATION_ESTIMATED, expressions));
153: }
154:
155: sb.append("}\n");
156:
157: return sb.toString();
158: }
159:
160: private void generateInitMethod(StringBuffer sb) {
161: sb.append("\n");
162: sb.append("\n");
163: sb.append(" /**\n");
164: sb.append(" *\n");
165: sb.append(" */\n");
166: sb.append(" void customizedInit(\n");
167: sb.append(" Map pm,\n");
168: sb.append(" Map fm,\n");
169: sb.append(" Map vm\n");
170: sb.append(" )\n");
171: sb.append(" {\n");
172: sb.append(" initParams(pm);\n");
173: if (fieldsMap != null) {
174: sb.append(" initFields(fm);\n");
175: }
176: sb.append(" initVars(vm);\n");
177: sb.append(" }\n");
178: sb.append("\n");
179: sb.append("\n");
180: }
181:
182: protected final void generateClassStart(StringBuffer sb) {
183: /* */
184: sb.append("/*\n");
185: sb.append(" * Generated by JasperReports - ");
186: sb
187: .append((new SimpleDateFormat())
188: .format(new java.util.Date()));
189: sb.append("\n");
190: sb.append(" */\n");
191: sb.append("import net.sf.jasperreports.engine.*;\n");
192: sb.append("import net.sf.jasperreports.engine.fill.*;\n");
193: sb.append("\n");
194: sb.append("import java.util.*;\n");
195: sb.append("import java.math.*;\n");
196: sb.append("import java.text.*;\n");
197: sb.append("import java.io.*;\n");
198: sb.append("import java.net.*;\n");
199: sb.append("\n");
200:
201: /* */
202: String[] imports = sourceTask.getImports();
203: if (imports != null && imports.length > 0) {
204: for (int i = 0; i < imports.length; i++) {
205: sb.append("import ");
206: sb.append(imports[i]);
207: sb.append(";\n");
208: }
209: }
210:
211: /* */
212: sb.append("\n");
213: sb.append("\n");
214: sb.append("/**\n");
215: sb.append(" *\n");
216: sb.append(" */\n");
217: sb.append("class ");
218: sb.append(sourceTask.getUnitName());
219: sb.append(" extends JREvaluator\n");
220: sb.append("{\n");
221: sb.append("\n");
222: sb.append("\n");
223: sb.append(" /**\n");
224: sb.append(" *\n");
225: sb.append(" */\n");
226: }
227:
228: protected final void generateDeclarations(StringBuffer sb) {
229: if (parametersMap != null && parametersMap.size() > 0) {
230: Collection parameterNames = parametersMap.keySet();
231: for (Iterator it = parameterNames.iterator(); it.hasNext();) {
232: sb.append(" private JRFillParameter parameter_");
233: sb.append(JRStringUtil.getLiteral((String) it.next()));
234: sb.append(" = null;\n");
235: }
236: }
237:
238: if (fieldsMap != null && fieldsMap.size() > 0) {
239: Collection fieldNames = fieldsMap.keySet();
240: for (Iterator it = fieldNames.iterator(); it.hasNext();) {
241: sb.append(" private JRFillField field_");
242: sb.append(JRStringUtil.getLiteral((String) it.next()));
243: sb.append(" = null;\n");
244: }
245: }
246:
247: if (variables != null && variables.length > 0) {
248: for (int i = 0; i < variables.length; i++) {
249: sb.append(" private JRFillVariable variable_");
250: sb.append(JRStringUtil.getLiteral(variables[i]
251: .getName()));
252: sb.append(" = null;\n");
253: }
254: }
255: }
256:
257: protected final void generateInitParamsMethod(StringBuffer sb)
258: throws JRException {
259: Iterator parIt = null;
260: if (parametersMap != null && parametersMap.size() > 0) {
261: parIt = parametersMap.keySet().iterator();
262: } else {
263: parIt = Collections.EMPTY_SET.iterator();
264: }
265: generateInitParamsMethod(sb, parIt, 0);
266: }
267:
268: protected final void generateInitFieldsMethod(StringBuffer sb)
269: throws JRException {
270: Iterator fieldIt = null;
271: if (fieldsMap != null && fieldsMap.size() > 0) {
272: fieldIt = fieldsMap.keySet().iterator();
273: } else {
274: fieldIt = Collections.EMPTY_SET.iterator();
275: }
276: generateInitFieldsMethod(sb, fieldIt, 0);
277: }
278:
279: protected final void generateInitVarsMethod(StringBuffer sb)
280: throws JRException {
281: Iterator varIt = null;
282: if (variables != null && variables.length > 0) {
283: varIt = Arrays.asList(variables).iterator();
284: } else {
285: varIt = Collections.EMPTY_LIST.iterator();
286: }
287: generateInitVarsMethod(sb, varIt, 0);
288: }
289:
290: /**
291: *
292: */
293: private void generateInitParamsMethod(StringBuffer sb, Iterator it,
294: int index) throws JRException {
295: sb.append(" /**\n");
296: sb.append(" *\n");
297: sb.append(" */\n");
298: sb.append(" void initParams");
299: if (index > 0) {
300: sb.append(index);
301: }
302: sb.append("(Map pm)\n");
303: sb.append(" {\n");
304: for (int i = 0; i < EXPR_MAX_COUNT_PER_METHOD && it.hasNext(); i++) {
305: String parameterName = (String) it.next();
306: sb.append(" parameter_");
307: sb.append(JRStringUtil.getLiteral(parameterName));
308: sb.append(" = (JRFillParameter)pm.get(\"");
309: sb.append(parameterName);
310: sb.append("\");\n");
311: }
312: if (it.hasNext()) {
313: sb.append(" initParams");
314: sb.append(index + 1);
315: sb.append("(pm);\n");
316: }
317: sb.append(" }\n");
318: sb.append("\n");
319: sb.append("\n");
320:
321: if (it.hasNext()) {
322: generateInitParamsMethod(sb, it, index + 1);
323: }
324: }
325:
326: /**
327: *
328: */
329: private void generateInitFieldsMethod(StringBuffer sb, Iterator it,
330: int index) throws JRException {
331: sb.append(" /**\n");
332: sb.append(" *\n");
333: sb.append(" */\n");
334: sb.append(" void initFields");
335: if (index > 0) {
336: sb.append(index);
337: }
338: sb.append("(Map fm)\n");
339: sb.append(" {\n");
340: for (int i = 0; i < EXPR_MAX_COUNT_PER_METHOD && it.hasNext(); i++) {
341: String fieldName = (String) it.next();
342: sb.append(" field_");
343: sb.append(JRStringUtil.getLiteral(fieldName));
344: sb.append(" = (JRFillField)fm.get(\"");
345: sb.append(fieldName);
346: sb.append("\");\n");
347: }
348: if (it.hasNext()) {
349: sb.append(" initFields");
350: sb.append(index + 1);
351: sb.append("(fm);\n");
352: }
353: sb.append(" }\n");
354: sb.append("\n");
355: sb.append("\n");
356:
357: if (it.hasNext()) {
358: generateInitFieldsMethod(sb, it, index + 1);
359: }
360: }
361:
362: /**
363: *
364: */
365: private void generateInitVarsMethod(StringBuffer sb, Iterator it,
366: int index) throws JRException {
367: sb.append(" /**\n");
368: sb.append(" *\n");
369: sb.append(" */\n");
370: sb.append(" void initVars");
371: if (index > 0) {
372: sb.append(index);
373: }
374: sb.append("(Map vm)\n");
375: sb.append(" {\n");
376: for (int i = 0; i < EXPR_MAX_COUNT_PER_METHOD && it.hasNext(); i++) {
377: String variableName = ((JRVariable) it.next()).getName();
378: sb.append(" variable_");
379: sb.append(JRStringUtil.getLiteral(variableName));
380: sb.append(" = (JRFillVariable)vm.get(\"");
381: sb.append(variableName);
382: sb.append("\");\n");
383: }
384: if (it.hasNext()) {
385: sb.append(" initVars");
386: sb.append(index + 1);
387: sb.append("(vm);\n");
388: }
389: sb.append(" }\n");
390: sb.append("\n");
391: sb.append("\n");
392:
393: if (it.hasNext()) {
394: generateInitVarsMethod(sb, it, index + 1);
395: }
396: }
397:
398: /**
399: *
400: */
401: protected final String generateMethod(byte evaluationType,
402: List expressionsList) throws JRException {
403: StringBuffer sb = new StringBuffer();
404:
405: if (expressionsList != null && !expressionsList.isEmpty()) {
406: sb.append(generateMethod(expressionsList.iterator(), 0,
407: evaluationType, expressionsList.size()));
408: } else {
409: /* */
410: sb.append(" /**\n");
411: sb.append(" *\n");
412: sb.append(" */\n");
413: sb.append(" Object evaluate");
414: sb.append((String) methodSuffixMap.get(new Byte(
415: evaluationType)));
416: sb.append("(int id)\n");
417: sb.append(" {\n");
418: sb.append(" return null;\n");
419: sb.append(" }\n");
420: sb.append("\n");
421: sb.append("\n");
422: }
423:
424: return sb.toString();
425: }
426:
427: /**
428: *
429: */
430: private String generateMethod(Iterator it, int index,
431: byte evaluationType, int expressionCount)
432: throws JRException {
433: StringBuffer sb = new StringBuffer();
434:
435: /* */
436: sb.append(" /**\n");
437: sb.append(" *\n");
438: sb.append(" */\n");
439: sb.append(" Object evaluate");
440: sb.append((String) methodSuffixMap
441: .get(new Byte(evaluationType)));
442: if (index > 0) {
443: sb.append(index);
444: }
445: sb.append("(int id)\n");
446: sb.append(" {\n");
447: sb.append(" Object value = null;\n");
448: sb.append("\n");
449:
450: //NB: relying on the fact that the expression id is the same as the index of the expression in the list
451: int expressionIdLimit = (index + 1) * EXPR_MAX_COUNT_PER_METHOD;
452: boolean nextMethod = expressionCount > expressionIdLimit;
453:
454: if (nextMethod) {
455: sb.append(" if (id >= ");
456: sb.append(expressionIdLimit);
457: sb.append(")\n");
458: sb.append(" {\n");
459: sb.append(" value = evaluate");
460: sb.append((String) methodSuffixMap.get(new Byte(
461: evaluationType)));
462: sb.append(index + 1);
463: sb.append("(id);\n");
464: sb.append(" }\n");
465: }
466:
467: for (int i = 0; it.hasNext() && i < EXPR_MAX_COUNT_PER_METHOD; i++) {
468: JRExpression expression = (JRExpression) it.next();
469:
470: sb.append(" ");
471: if (i > 0 || nextMethod) {
472: sb.append("else ");
473: }
474: sb.append("if (id == ");
475: sb.append(sourceTask.getExpressionId(expression));
476: sb.append(")\n");
477: sb.append(" {\n");
478: sb.append(" value = (");
479: sb.append(expression.getValueClassName());
480: sb.append(")(");
481: sb.append(this .generateExpression(expression,
482: evaluationType));
483: sb.append(");\n");
484: sb.append(" }\n");
485: }
486:
487: sb.append("\n");
488: sb.append(" return value;\n");
489: sb.append(" }\n");
490: sb.append("\n");
491: sb.append("\n");
492:
493: if (nextMethod) {
494: sb.append(generateMethod(it, index + 1, evaluationType,
495: expressionCount));
496: }
497:
498: return sb.toString();
499: }
500:
501: /**
502: *
503: */
504: private String generateExpression(JRExpression expression,
505: byte evaluationType) {
506: JRParameter jrParameter = null;
507: JRField jrField = null;
508: JRVariable jrVariable = null;
509:
510: StringBuffer sb = new StringBuffer();
511:
512: JRExpressionChunk[] chunks = expression.getChunks();
513: JRExpressionChunk chunk = null;
514: String chunkText = null;
515: if (chunks != null && chunks.length > 0) {
516: for (int i = 0; i < chunks.length; i++) {
517: chunk = chunks[i];
518:
519: chunkText = chunk.getText();
520: if (chunkText == null) {
521: chunkText = "";
522: }
523:
524: switch (chunk.getType()) {
525: case JRExpressionChunk.TYPE_TEXT: {
526: sb.append(chunkText);
527: break;
528: }
529: case JRExpressionChunk.TYPE_PARAMETER: {
530: jrParameter = (JRParameter) parametersMap
531: .get(chunkText);
532:
533: sb.append("((");
534: sb.append(jrParameter.getValueClassName());
535: sb.append(")parameter_");
536: sb.append(JRStringUtil.getLiteral(chunkText));
537: sb.append(".getValue())");
538:
539: break;
540: }
541: case JRExpressionChunk.TYPE_FIELD: {
542: jrField = (JRField) fieldsMap.get(chunkText);
543:
544: sb.append("((");
545: sb.append(jrField.getValueClassName());
546: sb.append(")field_");
547: sb.append(JRStringUtil.getLiteral(chunkText));
548: sb.append(".get");
549: sb.append((String) fieldPrefixMap.get(new Byte(
550: evaluationType)));
551: sb.append("Value())");
552:
553: break;
554: }
555: case JRExpressionChunk.TYPE_VARIABLE: {
556: jrVariable = (JRVariable) variablesMap
557: .get(chunkText);
558:
559: sb.append("((");
560: sb.append(jrVariable.getValueClassName());
561: sb.append(")variable_");
562: sb.append(JRStringUtil.getLiteral(chunkText));
563: sb.append(".get");
564: sb.append((String) variablePrefixMap.get(new Byte(
565: evaluationType)));
566: sb.append("Value())");
567:
568: break;
569: }
570: case JRExpressionChunk.TYPE_RESOURCE: {
571: sb.append("str(\"");
572: sb.append(chunkText);
573: sb.append("\")");
574:
575: break;
576: }
577: }
578: }
579: }
580:
581: if (sb.length() == 0) {
582: sb.append("null");
583: }
584:
585: return sb.toString();
586: }
587: }
|