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.components;
25
26 import org.apache.commons.digester.Digester;
27
28 import net.sf.jasperreports.components.barbecue.StandardBarbecueComponent;
29 import net.sf.jasperreports.components.barcode4j.CodabarComponent;
30 import net.sf.jasperreports.components.barcode4j.Code128Component;
31 import net.sf.jasperreports.components.barcode4j.Code39Component;
32 import net.sf.jasperreports.components.barcode4j.DataMatrixComponent;
33 import net.sf.jasperreports.components.barcode4j.EAN128Component;
34 import net.sf.jasperreports.components.barcode4j.EAN13Component;
35 import net.sf.jasperreports.components.barcode4j.EAN8Component;
36 import net.sf.jasperreports.components.barcode4j.ErrorCorrectionLevelEnum;
37 import net.sf.jasperreports.components.barcode4j.Interleaved2Of5Component;
38 import net.sf.jasperreports.components.barcode4j.OrientationRule;
39 import net.sf.jasperreports.components.barcode4j.PDF417Component;
40 import net.sf.jasperreports.components.barcode4j.POSTNETComponent;
41 import net.sf.jasperreports.components.barcode4j.QRCodeComponent;
42 import net.sf.jasperreports.components.barcode4j.RoyalMailCustomerComponent;
43 import net.sf.jasperreports.components.barcode4j.TextPositionEnum;
44 import net.sf.jasperreports.components.barcode4j.UPCAComponent;
45 import net.sf.jasperreports.components.barcode4j.UPCEComponent;
46 import net.sf.jasperreports.components.barcode4j.USPSIntelligentMailComponent;
47 import net.sf.jasperreports.components.iconlabel.IconLabelComponentDigester;
48 import net.sf.jasperreports.components.items.Item;
49 import net.sf.jasperreports.components.items.ItemData;
50 import net.sf.jasperreports.components.items.ItemDataXmlFactory;
51 import net.sf.jasperreports.components.items.ItemDatasetFactory;
52 import net.sf.jasperreports.components.items.ItemProperty;
53 import net.sf.jasperreports.components.items.ItemPropertyXmlFactory;
54 import net.sf.jasperreports.components.items.ItemXmlFactory;
55 import net.sf.jasperreports.components.list.DesignListContents;
56 import net.sf.jasperreports.components.list.ListComponent;
57 import net.sf.jasperreports.components.list.StandardListComponent;
58 import net.sf.jasperreports.components.map.MapXmlFactory;
59 import net.sf.jasperreports.components.sort.SortComponentDigester;
60 import net.sf.jasperreports.components.spiderchart.SpiderChartDigester;
61 import net.sf.jasperreports.components.table.DesignBaseCell;
62 import net.sf.jasperreports.components.table.DesignCell;
63 import net.sf.jasperreports.components.table.StandardColumn;
64 import net.sf.jasperreports.components.table.StandardColumnGroup;
65 import net.sf.jasperreports.components.table.StandardGroupCell;
66 import net.sf.jasperreports.components.table.StandardGroupRow;
67 import net.sf.jasperreports.components.table.StandardRow;
68 import net.sf.jasperreports.components.table.StandardTableFactory;
69 import net.sf.jasperreports.components.table.TableComponent;
70 import net.sf.jasperreports.engine.JRElementDataset;
71 import net.sf.jasperreports.engine.JRExpression;
72 import net.sf.jasperreports.engine.component.XmlDigesterConfigurer;
73 import net.sf.jasperreports.engine.type.EvaluationTimeEnum;
74 import net.sf.jasperreports.engine.type.PrintOrderEnum;
75 import net.sf.jasperreports.engine.type.RotationEnum;
76 import net.sf.jasperreports.engine.xml.DatasetRunReportContextRule;
77 import net.sf.jasperreports.engine.xml.JRExpressionFactory;
78 import net.sf.jasperreports.engine.xml.JRXmlConstants;
79 import net.sf.jasperreports.engine.xml.JRXmlWriter;
80 import net.sf.jasperreports.engine.xml.StyleContainerRule;
81 import net.sf.jasperreports.engine.xml.UuidPropertyRule;
82 import net.sf.jasperreports.engine.xml.XmlConstantPropertyRule;
83
84 /**
85  * XML digester for built-in component implementations.
86  * 
87  * @author Lucian Chirita (lucianc@users.sourceforge.net)
88  * @see ComponentsExtensionsRegistryFactory
89  */

90 public class ComponentsXmlDigesterConfigurer implements XmlDigesterConfigurer
91 {
92     
93     private static final String[] BARCODE4J_IGNORED_PROPERTIES = {
94             JRXmlConstants.ATTRIBUTE_evaluationTime,
95             "orientation",
96             "textPosition"};
97
98     private static final String[] QRCODE_IGNORED_PROPERTIES = {
99             JRXmlConstants.ATTRIBUTE_evaluationTime,
100             "errorCorrectionLevel"};
101     
102     @Override
103     public void configureDigester(Digester digester)
104     {
105         addListRules(digester);
106         addBarbecueRules(digester);
107         addBarcode4jRules(digester);
108         addTableRules(digester);
109         SpiderChartDigester.addSpiderChartRules(digester);
110         addMapRules(digester);
111         SortComponentDigester.addSortComponentRules(digester);
112         IconLabelComponentDigester.addIconLabelComponentRules(digester);
113     }
114
115     protected void addListRules(Digester digester)
116     {
117         String listPattern = "*/componentElement/list";
118         digester.addObjectCreate(listPattern, StandardListComponent.class);
119         digester.addSetProperties(listPattern,
120                 //properties to be ignored by this rule
121                 new String[]{"printOrder"}, 
122                 new String[0]);
123         digester.addRule(listPattern, new XmlConstantPropertyRule(
124                 "printOrder""printOrderValue", PrintOrderEnum.values()));
125         
126         String listContentsPattern = listPattern + "/listContents";
127         digester.addObjectCreate(listContentsPattern, DesignListContents.class);
128         digester.addSetProperties(listContentsPattern);
129         digester.addSetNext(listContentsPattern, "setContents");
130         // rule to set the context dataset name
131         digester.addRule(listContentsPattern, new DatasetRunReportContextRule<>(ListComponent.class));
132     }
133
134     @SuppressWarnings("deprecation")
135     protected void addBarbecueRules(Digester digester)
136     {
137         String barcodePattern = "*/componentElement/barbecue";
138         digester.addObjectCreate(barcodePattern, StandardBarbecueComponent.class);
139         digester.addSetProperties(barcodePattern,
140                 //properties to be ignored by this rule
141                 new String[]{JRXmlConstants.ATTRIBUTE_evaluationTime, StandardBarbecueComponent.PROPERTY_ROTATION}, 
142                 new String[0]);
143         digester.addRule(barcodePattern, 
144                 new XmlConstantPropertyRule(
145                         JRXmlConstants.ATTRIBUTE_evaluationTime, "evaluationTimeValue",
146                         EvaluationTimeEnum.values()));
147         digester.addRule(barcodePattern, 
148                 new XmlConstantPropertyRule(
149                         StandardBarbecueComponent.PROPERTY_ROTATION,
150                         RotationEnum.values()));
151
152         String barcodeExpressionPattern = barcodePattern + "/codeExpression";
153         digester.addFactoryCreate(barcodeExpressionPattern, 
154                 JRExpressionFactory.StringExpressionFactory.class.getName());
155         digester.addCallMethod(barcodeExpressionPattern, "setText", 0);
156         digester.addSetNext(barcodeExpressionPattern, "setCodeExpression"
157                 JRExpression.class.getName());
158
159         String applicationIdentifierExpressionPattern = barcodePattern 
160                 + "/applicationIdentifierExpression";
161         digester.addFactoryCreate(applicationIdentifierExpressionPattern, 
162                 JRExpressionFactory.StringExpressionFactory.class.getName());
163         digester.addCallMethod(applicationIdentifierExpressionPattern, "setText", 0);
164         digester.addSetNext(applicationIdentifierExpressionPattern, 
165                 "setApplicationIdentifierExpression"
166                 JRExpression.class.getName());
167     }
168
169     protected void addBarcode4jRules(Digester digester)
170     {
171         addBaseBarcode4jRules(digester, 
172                 "*/componentElement/Codabar"
173                 CodabarComponent.class);
174         addBaseBarcode4jRules(digester, 
175                 "*/componentElement/Code128"
176                 Code128Component.class);
177         addBaseBarcode4jRules(digester, 
178                 "*/componentElement/EAN128"
179                 EAN128Component.class);
180         addTemplateRules(digester, 
181                 "*/componentElement/EAN128");
182         addBaseBarcode4jRules(digester, 
183                 "*/componentElement/DataMatrix"
184                 DataMatrixComponent.class);
185         addBaseBarcode4jRules(digester, 
186                 "*/componentElement/RoyalMailCustomer"
187                 RoyalMailCustomerComponent.class);
188         addBaseBarcode4jRules(digester, 
189                 "*/componentElement/USPSIntelligentMail"
190                 USPSIntelligentMailComponent.class);
191         addBaseBarcode4jRules(digester, 
192                 "*/componentElement/Code39", Code39Component.class);
193         addBaseBarcode4jRules(digester, 
194                 "*/componentElement/Interleaved2Of5", Interleaved2Of5Component.class);
195         addBaseBarcode4jRules(digester, 
196                 "*/componentElement/UPCA", UPCAComponent.class);
197         addBaseBarcode4jRules(digester, 
198                 "*/componentElement/UPCE", UPCEComponent.class);
199         addBaseBarcode4jRules(digester, 
200                 "*/componentElement/EAN13", EAN13Component.class);
201         addBaseBarcode4jRules(digester, 
202                 "*/componentElement/EAN8", EAN8Component.class);
203         addBaseBarcode4jRules(digester, 
204                 "*/componentElement/POSTNET", POSTNETComponent.class);
205         addBaseBarcode4jRules(digester, 
206                 "*/componentElement/PDF417", PDF417Component.class);
207         addQRCodeRules(digester, 
208                 "*/componentElement/QRCode", QRCodeComponent.class);
209     }
210     
211     protected <T> void addBaseBarcode4jRules(Digester digester, 
212             String barcodePattern, Class<T> barcodeComponentClass)
213     {
214         addBarcodeRules(digester, barcodePattern, barcodeComponentClass, BARCODE4J_IGNORED_PROPERTIES);
215         addPatternExpressionRules(digester, barcodePattern);
216         
217         digester.addRule(barcodePattern, 
218                 new OrientationRule("orientation""orientation"));
219         digester.addRule(barcodePattern, 
220                 new XmlConstantPropertyRule(
221                         "textPosition""textPosition",
222                         TextPositionEnum.values()));
223     }
224     
225     @SuppressWarnings("deprecation")
226     protected <T> void addPatternExpressionRules(Digester digester, String barcodePattern)
227     {
228         String patternExpressionPattern = barcodePattern + "/patternExpression";
229         digester.addFactoryCreate(patternExpressionPattern, 
230                 JRExpressionFactory.StringExpressionFactory.class.getName());
231         digester.addCallMethod(patternExpressionPattern, "setText", 0);
232         digester.addSetNext(patternExpressionPattern, "setPatternExpression"
233                 JRExpression.class.getName());
234     }
235     
236     @SuppressWarnings("deprecation")
237     protected <T> void addBarcodeRules(Digester digester, 
238             String barcodePattern, Class<T> barcodeComponentClass,
239             String[] ignoredProperties)
240     {
241         digester.addObjectCreate(barcodePattern, barcodeComponentClass);
242         digester.addSetProperties(barcodePattern,
243                 //properties to be ignored by this rule
244                 ignoredProperties, 
245                 new String[0]);
246         //rule to set evaluation time
247         digester.addRule(barcodePattern, 
248                 new XmlConstantPropertyRule(
249                         JRXmlConstants.ATTRIBUTE_evaluationTime, "evaluationTimeValue",
250                         EvaluationTimeEnum.values()));
251         
252         String codeExpressionPattern = barcodePattern + "/codeExpression";
253         digester.addFactoryCreate(codeExpressionPattern, 
254                 JRExpressionFactory.StringExpressionFactory.class.getName());
255         digester.addCallMethod(codeExpressionPattern, "setText", 0);
256         digester.addSetNext(codeExpressionPattern, "setCodeExpression"
257                 JRExpression.class.getName());
258     }
259
260     protected <T> void addQRCodeRules(Digester digester, 
261             String barcodePattern, Class<T> barcodeComponentClass)
262     {
263         addBarcodeRules(digester, barcodePattern, barcodeComponentClass, QRCODE_IGNORED_PROPERTIES);
264
265         digester.addRule(barcodePattern, 
266                 new XmlConstantPropertyRule(
267                         "errorCorrectionLevel""errorCorrectionLevel",
268                         ErrorCorrectionLevelEnum.values()));
269     }
270     
271     @SuppressWarnings("deprecation")
272     protected void addTemplateRules(Digester digester, String barcodePattern)
273     {
274         String templateExpressionPattern = barcodePattern + "/templateExpression";
275         digester.addFactoryCreate(templateExpressionPattern, 
276                 JRExpressionFactory.StringExpressionFactory.class.getName());
277         digester.addCallMethod(templateExpressionPattern, "setText", 0);
278         digester.addSetNext(templateExpressionPattern, "setTemplateExpression"
279                 JRExpression.class.getName());
280     }
281
282     @SuppressWarnings("deprecation")
283     protected void addMapRules(Digester digester)
284     {
285         String mapPattern = "*/componentElement/map";
286         digester.addFactoryCreate(mapPattern, MapXmlFactory.class);
287
288         String latitudeExpressionPattern = mapPattern + "/latitudeExpression";
289         digester.addFactoryCreate(latitudeExpressionPattern, 
290                 JRExpressionFactory.class.getName());
291         digester.addCallMethod(latitudeExpressionPattern, "setText", 0);
292         digester.addSetNext(latitudeExpressionPattern, "setLatitudeExpression"
293                 JRExpression.class.getName());
294
295         String longitudeExpressionPattern = mapPattern + "/longitudeExpression";
296         digester.addFactoryCreate(longitudeExpressionPattern, 
297                 JRExpressionFactory.class.getName());
298         digester.addCallMethod(longitudeExpressionPattern, "setText", 0);
299         digester.addSetNext(longitudeExpressionPattern, "setLongitudeExpression"
300                 JRExpression.class.getName());
301         
302         String addressExpressionPattern = mapPattern + "/addressExpression";
303         digester.addFactoryCreate(addressExpressionPattern, 
304                 JRExpressionFactory.class.getName());
305         digester.addCallMethod(addressExpressionPattern, "setText", 0);
306         digester.addSetNext(addressExpressionPattern, "setAddressExpression"
307                 JRExpression.class.getName());
308         
309         String zoomExpressionPattern = mapPattern + "/zoomExpression";
310         digester.addFactoryCreate(zoomExpressionPattern, 
311                 JRExpressionFactory.class.getName());
312         digester.addCallMethod(zoomExpressionPattern, "setText", 0);
313         digester.addSetNext(zoomExpressionPattern, "setZoomExpression"
314                 JRExpression.class.getName());
315         
316         String languageExpressionPattern = mapPattern + "/languageExpression";
317         digester.addFactoryCreate(languageExpressionPattern, 
318                 JRExpressionFactory.class.getName());
319         digester.addCallMethod(languageExpressionPattern, "setText", 0);
320         digester.addSetNext(languageExpressionPattern, "setLanguageExpression"
321                 JRExpression.class.getName());
322
323         String componentNamespace = digester.getRuleNamespaceURI();
324         String jrNamespace = JRXmlConstants.JASPERREPORTS_NAMESPACE;
325
326         String markerDatasetPattern = mapPattern + "/markerDataset";
327         digester.addFactoryCreate(markerDatasetPattern, net.sf.jasperreports.components.map.MarkerDatasetXmlFactory.class.getName());
328         digester.addSetNext(markerDatasetPattern, "setMarkerDataset", net.sf.jasperreports.components.map.MarkerDataset.class.getName());
329
330         String markerPattern = markerDatasetPattern + "/marker";
331         digester.addFactoryCreate(markerPattern, net.sf.jasperreports.components.map.MarkerXmlFactory.class.getName());
332         digester.addSetNext(markerPattern, "addMarker", net.sf.jasperreports.components.map.Marker.class.getName());
333
334         String markerPropertyPattern = markerPattern + "/markerProperty";
335         digester.addFactoryCreate(markerPropertyPattern, net.sf.jasperreports.components.map.MarkerPropertyXmlFactory.class.getName());
336         digester.addSetNext(markerPropertyPattern, "addMarkerProperty", net.sf.jasperreports.components.map.MarkerProperty.class.getName());
337
338         digester.setRuleNamespaceURI(jrNamespace);
339         
340         String markerPropertyValueExpressionPattern = markerPropertyPattern + "/" + JRXmlConstants.ELEMENT_valueExpression;
341         digester.addFactoryCreate(markerPropertyValueExpressionPattern, JRExpressionFactory.class.getName());
342         digester.addCallMethod(markerPropertyValueExpressionPattern, "setText", 0);
343         digester.addSetNext(markerPropertyValueExpressionPattern, "setValueExpression", JRExpression.class.getName());
344         
345         digester.setRuleNamespaceURI(componentNamespace);
346         
347         String markerDataPattern = mapPattern + "/markerData";
348         digester.addFactoryCreate(markerDataPattern, ItemDataXmlFactory.class.getName());
349         digester.addSetNext(markerDataPattern, "addMarkerData", ItemData.class.getName());
350         
351         addItemRules(digester, markerDataPattern + "/item", jrNamespace);
352         
353         digester.setRuleNamespaceURI(jrNamespace);
354         digester.addFactoryCreate(markerDataPattern + "/dataset", ItemDatasetFactory.class.getName());
355         digester.addSetNext(markerDataPattern + "/dataset""setDataset", JRElementDataset.class.getName());
356         
357         digester.setRuleNamespaceURI(componentNamespace);
358         
359         String pathStylePattern = mapPattern + "/pathStyle";
360         digester.addFactoryCreate(pathStylePattern, ItemDataXmlFactory.class.getName());
361         digester.addSetNext(pathStylePattern, "addPathStyle", ItemData.class.getName());
362         
363         addItemRules(digester, pathStylePattern + "/item", jrNamespace);
364         
365         digester.setRuleNamespaceURI(jrNamespace);
366         digester.addFactoryCreate(pathStylePattern + "/dataset", ItemDatasetFactory.class.getName());
367         digester.addSetNext(pathStylePattern + "/dataset""setDataset", JRElementDataset.class.getName());
368         
369         digester.setRuleNamespaceURI(componentNamespace);
370         
371         String pathDataPattern = mapPattern + "/pathData";
372         digester.addFactoryCreate(pathDataPattern, ItemDataXmlFactory.class.getName());
373         digester.addSetNext(pathDataPattern, "addPathData", ItemData.class.getName());
374
375         addItemRules(digester, pathDataPattern + "/item", jrNamespace);
376
377         digester.setRuleNamespaceURI(jrNamespace);
378         digester.addFactoryCreate(pathDataPattern + "/dataset", ItemDatasetFactory.class.getName());
379         digester.addSetNext(pathDataPattern + "/dataset""setDataset", JRElementDataset.class.getName());
380         
381         digester.setRuleNamespaceURI(componentNamespace);
382         
383     }
384
385     protected void addItemRules(Digester digester, String itemPattern, String namespace)
386     {
387         digester.addFactoryCreate(itemPattern, ItemXmlFactory.class.getName());
388         digester.addSetNext(itemPattern, "addItem", Item.class.getName());
389
390         String locationItemPropertyPattern = itemPattern + "/itemProperty";
391         digester.addFactoryCreate(locationItemPropertyPattern, ItemPropertyXmlFactory.class.getName());
392         digester.addSetNext(locationItemPropertyPattern, "addItemProperty", ItemProperty.class.getName());
393
394         digester.setRuleNamespaceURI(namespace);
395         
396         String locationItemPropertyValueExpressionPattern = locationItemPropertyPattern + "/" + JRXmlConstants.ELEMENT_valueExpression;
397         digester.addFactoryCreate(locationItemPropertyValueExpressionPattern, JRExpressionFactory.class.getName());
398         digester.addCallMethod(locationItemPropertyValueExpressionPattern, "setText", 0);
399         digester.addSetNext(locationItemPropertyValueExpressionPattern, "setValueExpression", JRExpression.class.getName());
400     }
401
402     
403     @SuppressWarnings("deprecation")
404     protected void addTableRules(Digester digester)
405     {
406         String tablePattern = "*/componentElement/table";
407         //digester.addObjectCreate(tablePattern, StandardTable.class);
408         digester.addFactoryCreate(tablePattern, StandardTableFactory.class.getName());
409         
410         String columnPattern = "*/column";
411         digester.addObjectCreate(columnPattern, StandardColumn.class);
412         digester.addSetNext(columnPattern, "addColumn");
413         digester.addSetProperties(columnPattern,
414                 //properties to be ignored by this rule
415                 new String[]{"uuid"}, 
416                 new String[0]);
417         digester.addRule(columnPattern, new UuidPropertyRule("uuid""UUID"));
418         addExpressionRules(digester, columnPattern + "/printWhenExpression"
419                 JRExpressionFactory.BooleanExpressionFactory.class"setPrintWhenExpression",
420                 true);
421         addTableCellRules(digester, columnPattern + "/tableHeader""setTableHeader");
422         addTableCellRules(digester, columnPattern + "/tableFooter""setTableFooter");
423         addTableGroupCellRules(digester, columnPattern + "/groupHeader""addGroupHeader");
424         addTableGroupCellRules(digester, columnPattern + "/groupFooter""addGroupFooter");
425         addTableCellRules(digester, columnPattern + "/columnHeader""setColumnHeader");
426         addTableCellRules(digester, columnPattern + "/columnFooter""setColumnFooter");
427         addTableCellRules(digester, columnPattern + "/detailCell""setDetailCell");
428         
429         String columnGroupPattern = "*/columnGroup";
430         digester.addObjectCreate(columnGroupPattern, StandardColumnGroup.class);
431         digester.addSetNext(columnGroupPattern, "addColumn");
432         digester.addSetProperties(columnGroupPattern,
433                 //properties to be ignored by this rule
434                 new String[]{"uuid"}, 
435                 new String[0]);
436         digester.addRule(columnGroupPattern, new UuidPropertyRule("uuid""UUID"));
437         addExpressionRules(digester, columnGroupPattern + "/printWhenExpression"
438                 JRExpressionFactory.BooleanExpressionFactory.class"setPrintWhenExpression",
439                 true);
440         addTableCellRules(digester, columnGroupPattern + "/tableHeader""setTableHeader");
441         addTableCellRules(digester, columnGroupPattern + "/tableFooter""setTableFooter");
442         addTableGroupCellRules(digester, columnGroupPattern + "/groupHeader""addGroupHeader");
443         addTableGroupCellRules(digester, columnGroupPattern + "/groupFooter""addGroupFooter");
444         addTableCellRules(digester, columnGroupPattern + "/columnHeader""setColumnHeader");
445         addTableCellRules(digester, columnGroupPattern + "/columnFooter""setColumnFooter");
446
447         addTableRowRules(digester, tablePattern + "/tableHeader""setTableHeader");
448         addTableRowRules(digester, tablePattern + "/tableFooter""setTableFooter");
449         addTableGroupRowRules(digester, tablePattern + "/groupHeader""addGroupHeader");
450         addTableGroupRowRules(digester, tablePattern + "/groupFooter""addGroupFooter");
451         addTableRowRules(digester, tablePattern + "/columnHeader""setColumnHeader");
452         addTableRowRules(digester, tablePattern + "/columnFooter""setColumnFooter");
453         addTableRowRules(digester, tablePattern + "/detail""setDetail");
454         
455         addTableBaseCellRules(digester, tablePattern + "/noData""setNoData");
456     }
457     
458     protected void addTableBaseCellRules(Digester digester, String pattern, 
459             String setNextMethod)
460     {
461         digester.addObjectCreate(pattern, DesignBaseCell.class);
462         digester.addSetNext(pattern, setNextMethod);
463         // rule to set the context dataset name
464         digester.addRule(pattern, new DatasetRunReportContextRule<>(TableComponent.class));
465         
466         digester.addSetProperties(pattern,
467                 new String[]{JRXmlConstants.ATTRIBUTE_style}, 
468                 new String[0]);
469         digester.addRule(pattern, new StyleContainerRule());
470     }
471     
472     protected void addTableCellRules(Digester digester, String pattern, 
473             String setNextMethod)
474     {
475         digester.addObjectCreate(pattern, DesignCell.class);
476         digester.addSetNext(pattern, setNextMethod);
477         // rule to set the context dataset name
478         digester.addRule(pattern, new DatasetRunReportContextRule<>(TableComponent.class));
479         
480         digester.addSetProperties(pattern,
481                 new String[]{JRXmlConstants.ATTRIBUTE_style}, 
482                 new String[0]);
483         digester.addRule(pattern, new StyleContainerRule());
484     }
485     
486     protected void addTableGroupCellRules(Digester digester, String pattern, 
487             String setNextMethod)
488     {
489         digester.addObjectCreate(pattern, StandardGroupCell.class);
490         digester.addSetProperties(pattern);
491         addTableCellRules(digester, pattern + "/cell""setCell");
492         digester.addSetNext(pattern, setNextMethod);
493     }
494
495     @SuppressWarnings("deprecation")
496     protected void addTableRowRules(Digester digester, String pattern, 
497             String setNextMethod)
498     {
499         digester.addObjectCreate(pattern, StandardRow.class);
500         digester.addSetProperties(pattern);
501         digester.addSetNext(pattern, setNextMethod);
502         addExpressionRules(digester, pattern + "/printWhenExpression"
503                 JRExpressionFactory.BooleanExpressionFactory.class"setPrintWhenExpression",
504                 true);
505     }
506     
507     protected void addTableGroupRowRules(Digester digester, String pattern, 
508             String setNextMethod)
509     {
510         digester.addObjectCreate(pattern, StandardGroupRow.class);
511         digester.addSetProperties(pattern);
512         addTableRowRules(digester, pattern + "/row""setRow");
513         digester.addSetNext(pattern, setNextMethod);
514     }
515
516     protected <T> void addExpressionRules(Digester digester, String expressionPattern,
517             Class<T> factoryClass, String setterMethod, boolean jrNamespace)
518     {
519         String originalNamespace = digester.getRuleNamespaceURI();
520         if (jrNamespace)
521         {
522             digester.setRuleNamespaceURI(JRXmlWriter.JASPERREPORTS_NAMESPACE.getNamespaceURI());
523         }
524         
525         digester.addFactoryCreate(expressionPattern, factoryClass);
526         digester.addCallMethod(expressionPattern, "setText", 0);
527         digester.addSetNext(expressionPattern, setterMethod,
528                 JRExpression.class.getName());
529         
530         if (jrNamespace)
531         {
532             digester.setRuleNamespaceURI(originalNamespace);
533         }
534     }
535 }
536