aaaf59ae48160680af74951bea6a771b3cc797e7
[mir.git] / source / mir / producer / reader / DefaultProducerNodeBuilders.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mir.producer.reader;
31
32 import java.io.File;
33 import java.util.Arrays;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40
41 import mir.entity.adapter.EntityAdapterModel;
42 import mir.generator.Generator;
43 import mir.generator.WriterEngine;
44 import mir.log.LoggerWrapper;
45 import mir.producer.BundleProducerNode;
46 import mir.producer.ConditionalProducerNode;
47 import mir.producer.DirCopyingProducerNode;
48 import mir.producer.EntityBatchingProducerNode;
49 import mir.producer.EntityDeletingProducerNode;
50 import mir.producer.EntityEnumeratingProducerNode;
51 import mir.producer.EntityListProducerNode;
52 import mir.producer.EntityModifyingProducerNode;
53 import mir.producer.EvaluatedAssignmentProducerNode;
54 import mir.producer.ExecuteProgramProducerNode;
55 import mir.producer.ExpandedAssignmentProducerNode;
56 import mir.producer.ExternalDbProducerNode;
57 import mir.producer.FileDateSettingProducerNode;
58 import mir.producer.FileDeletingProducerNode;
59 import mir.producer.FreeQueryProducerNode;
60 import mir.producer.GeneratingProducerNode;
61 import mir.producer.ListEnumeratingProducerNode;
62 import mir.producer.LoggingProducerNode;
63 import mir.producer.LoopProducerNode;
64 import mir.producer.ProducerNode;
65 import mir.producer.RDFAggregatorProducerNode;
66 import mir.producer.RSSProducerNode;
67 import mir.util.StringRoutines;
68 import mir.util.xml.XMLParserExc;
69 import mir.util.xml.XMLReaderTool;
70
71 public class DefaultProducerNodeBuilders {
72
73   public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary,
74        EntityAdapterModel aModel, Generator.Library aGeneratorLibrary,
75        Generator.Interceptor anInterceptor,
76        WriterEngine aWriterEngine, File aSourceBasePath, File aDestinationBasePath) throws ProducerConfigExc {
77
78     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
79     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
80     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
81     aBuilderLibrary.registerBuilder("Execute", ExecuteProgramProducerNodeBuilder.class);
82     aBuilderLibrary.registerBuilder("Resource", BundleProducerNodeBuilder.class);
83     aBuilderLibrary.registerBuilder("Bundle", BundleProducerNodeBuilder.class);
84     aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory(aSourceBasePath, aDestinationBasePath));
85
86     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
87     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
88     aBuilderLibrary.registerBuilder("If", ConditionalProducerNodeBuilder.class);
89     aBuilderLibrary.registerBuilder("While", LoopProducerNodeBuilder.class);
90
91     aBuilderLibrary.registerBuilder("RSS", RSSProducerNodeBuilder.class);
92     aBuilderLibrary.registerBuilder("RDFAggregate", RDFAggregatorProducerNodeBuilder.class);
93
94     aBuilderLibrary.registerBuilder("FreeQuery", FreeQueryProducerNodeBuilder.class);
95     aBuilderLibrary.registerBuilder("ExternalDbQuery", ExternalDbProducerNodeBuilder.class);
96
97     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
98     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
99     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
100
101     aBuilderLibrary.registerFactory("UpdateEntity", new UpdateEntityProducerNodeBuilder.factory(aModel));
102     aBuilderLibrary.registerFactory("CreateEntity", new CreateEntityProducerNodeBuilder.factory(aModel));
103     aBuilderLibrary.registerFactory("DeleteEntity", new DeleteEntityProducerNodeBuilder.factory(aModel));
104
105     aBuilderLibrary.registerFactory("Generate", new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary,
106         aWriterEngine, anInterceptor));
107   }
108
109   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
110     private Map subNodes;
111     private Set availableSubnodes;
112
113     public AbstractProducerNodeBuilder(String anAvailableSubNodes[]) {
114       subNodes = new HashMap();
115       availableSubnodes = new HashSet(Arrays.asList(anAvailableSubNodes));
116     }
117
118     protected ProducerNode getSubNode(String aName) {
119       return (ProducerNode) subNodes.get(aName);
120     }
121
122     public void setSubNode(String aName, ProducerNode aNode) {
123       subNodes.put(aName, aNode);
124     }
125
126     public Set getAvailableSubNodes() {
127       return availableSubnodes;
128     }
129   }
130
131 ////////////////////////////////////////////////////////////////////////////////
132
133   // general attribute names, specifc builders reference these, to keep attribute
134   //    names consistent
135
136   public final static String   EXTRA_TABLES_ATTRIBUTE = "extratables";
137   public final static String   SELECTION_ATTRIBUTE = "selection";
138   public final static String   ORDER_ATTRIBUTE = "order";
139   public final static String   DEFINITION_ATTRIBUTE = "table";
140   public final static String   SKIP_ATTRIBUTE = "skip";
141   public final static String   KEY_ATTRIBUTE = "key";
142   public final static String   LIMIT_ATTRIBUTE = "limit";
143   public final static String   URL_ATTRIBUTE = "url";
144
145 ////////////////////////////////////////////////////////////////////////////////
146
147   private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
148   private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
149   private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
150   private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
151   private final static String[] ASSIGNMENT_SUBNODES = {};
152
153   public static class ExpandedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
154
155     private String key;
156     private String value;
157
158     public ExpandedAssignmentProducerNodeBuilder() {
159       super(ASSIGNMENT_SUBNODES);
160     }
161
162     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
163       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
164
165       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
166       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
167     }
168
169     public ProducerNode constructNode() {
170       return new ExpandedAssignmentProducerNode(key, value);
171     }
172   }
173
174 ////////////////////////////////////////////////////////////////////////////////
175
176   public static class EvaluatedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
177
178     private String key;
179     private String value;
180
181     public EvaluatedAssignmentProducerNodeBuilder() {
182       super(ASSIGNMENT_SUBNODES);
183     }
184
185     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
186       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
187
188       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
189       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
190     }
191
192     public ProducerNode constructNode() {
193       return new EvaluatedAssignmentProducerNode(key, value);
194     }
195   }
196
197 ////////////////////////////////////////////////////////////////////////////////
198
199   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
200     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
201     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
202     private final static String   ENUMERATION_LIST_ATTRIBUTE = "list";
203     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
204     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
205     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
206     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
207     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
208     private final static String   ENUMERATION_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
209     private final static String[] ENUMERATION_LIST_REQUIRED_ATTRIBUTES = { ENUMERATION_LIST_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
210     private final static String[] ENUMERATION_LIST_OPTIONAL_ATTRIBUTES = { };
211     private final static String[] ENUMERATION_QUERY_REQUIRED_ATTRIBUTES = { ENUMERATION_DEFINITION_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
212     private final static String[] ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE,ENUMERATION_EXTRATABLES_ATTRIBUTE};
213     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
214
215     private String key;
216     private String definition;
217     private String mainTablePrefix;
218     private String extraTables;
219     private String list;
220     private String selection;
221     private String order;
222     private String limit;
223     private String skip;
224     private EntityAdapterModel model;
225
226     public EnumeratingProducerNodeBuilder(EntityAdapterModel aModel) {
227       super(ENUMERATION_SUBNODES);
228
229       model = aModel;
230     }
231
232     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
233       definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
234       list = (String) anAttributes.get(ENUMERATION_LIST_ATTRIBUTE);
235
236       if ((list==null && definition==null) || (list!=null && definition!=null))
237         throw new ProducerConfigExc("Exactly one of "+ENUMERATION_DEFINITION_ATTRIBUTE+" and "+ENUMERATION_LIST_ATTRIBUTE+" must be set");
238
239
240       if (list!=null)
241         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
242       if (definition!=null)
243         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
244
245
246       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
247       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
248       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
249       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
250       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
251       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_EXTRATABLES_ATTRIBUTE,"");
252       if (definition!=null) {
253         List parts = StringRoutines.splitString(definition.trim(), " ");
254         if (parts.size() > 0)
255           definition = (String) parts.get(0);
256         if (parts.size() > 1)
257           mainTablePrefix = (String) parts.get(1);
258       }
259     }
260
261     public ProducerNode constructNode() {
262       if (definition!=null)
263         return new EntityEnumeratingProducerNode(key, model, mainTablePrefix, extraTables, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
264                         return new ListEnumeratingProducerNode(key, list, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
265     }
266
267     public static class factory implements ProducerNodeBuilderFactory {
268       private EntityAdapterModel model;
269
270       public factory(EntityAdapterModel aModel) {
271         model = aModel;
272       }
273
274       public ProducerNodeBuilder makeBuilder() {
275         return new EnumeratingProducerNodeBuilder(model);
276       }
277     }
278   }
279
280 ////////////////////////////////////////////////////////////////////////////////
281
282   public static class UpdateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
283     private final static String   UPDATE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
284     private final static String   UPDATE_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
285     private final static String[] UPDATE_SUBNODES = {};
286
287     private String key;
288     private String definition;
289     private Map fieldValues;
290
291     private EntityAdapterModel model;
292
293     public UpdateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
294       super(UPDATE_SUBNODES);
295
296       model = aModel;
297       fieldValues = new HashMap();
298     }
299
300     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
301       key = (String) anAttributes.get(UPDATE_KEY_ATTRIBUTE);
302
303       if (key == null)
304         throw new XMLParserExc("missing required attribute '" + UPDATE_KEY_ATTRIBUTE + "'" );
305       definition = (String) anAttributes.get(UPDATE_DEFINITION_ATTRIBUTE);
306
307       fieldValues.putAll(anAttributes);
308       fieldValues.remove(UPDATE_KEY_ATTRIBUTE);
309       fieldValues.remove(UPDATE_DEFINITION_ATTRIBUTE);
310     }
311     public ProducerNode constructNode() {
312       return new EntityModifyingProducerNode(model, false, definition, key, fieldValues);
313     }
314
315     public static class factory implements ProducerNodeBuilderFactory {
316       private EntityAdapterModel model;
317
318       public factory(EntityAdapterModel aModel) {
319         model = aModel;
320       }
321
322       public ProducerNodeBuilder makeBuilder() {
323         return new UpdateEntityProducerNodeBuilder(model);
324       }
325     }
326   }
327
328 ////////////////////////////////////////////////////////////////////////////////
329
330   public static class CreateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
331     private final static String   CREATEENTITY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
332     private final static String   CREATEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
333     private final static String[] CREATEENTITY_SUBNODES = {};
334
335     private String key;
336     private String definition;
337     private Map fieldValues;
338
339     private EntityAdapterModel model;
340
341     public CreateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
342       super(CREATEENTITY_SUBNODES);
343
344       model = aModel;
345       fieldValues = new HashMap();
346     }
347
348     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
349       key = (String) anAttributes.get(CREATEENTITY_KEY_ATTRIBUTE);
350       definition = (String) anAttributes.get(CREATEENTITY_DEFINITION_ATTRIBUTE);
351
352       if (key == null)
353         throw new XMLParserExc("missing required attribute '" + CREATEENTITY_KEY_ATTRIBUTE + "'" );
354       if (definition == null)
355         throw new XMLParserExc("missing required attribute '" + CREATEENTITY_DEFINITION_ATTRIBUTE + "'" );
356
357       fieldValues.putAll(anAttributes);
358       fieldValues.remove(CREATEENTITY_KEY_ATTRIBUTE);
359       fieldValues.remove(CREATEENTITY_DEFINITION_ATTRIBUTE);
360     }
361
362     public ProducerNode constructNode() {
363       return new EntityModifyingProducerNode(model, true, definition, key, fieldValues);
364     }
365
366     public static class factory implements ProducerNodeBuilderFactory {
367       private EntityAdapterModel model;
368
369       public factory(EntityAdapterModel aModel) {
370         model = aModel;
371       }
372
373       public ProducerNodeBuilder makeBuilder() {
374         return new CreateEntityProducerNodeBuilder(model);
375       }
376     }
377   }
378
379 ////////////////////////////////////////////////////////////////////////////////
380
381   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
382     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
383     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
384     private final static String   LOOP_DEFAULT_SUBNODE = "default";
385     private final static String[] LOOP_REQUIRED_ATTRIBUTES = { LOOP_CONDITION_ATTRIBUTE };
386     private final static String[] LOOP_OPTIONAL_ATTRIBUTES = { LOOP_LIMIT_ATTRIBUTE };
387     private final static String[] LOOP_SUBNODES = {LOOP_DEFAULT_SUBNODE};
388
389     private String condition;
390     private String limit;
391
392     public LoopProducerNodeBuilder() {
393       super(LOOP_SUBNODES);
394     }
395
396     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
397       XMLReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
398
399       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
400       limit = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
401     }
402
403     public ProducerNode constructNode() {
404       return new LoopProducerNode(condition, limit, getSubNode( LOOP_DEFAULT_SUBNODE ));
405     }
406   }
407
408 ////////////////////////////////////////////////////////////////////////////////
409
410   public static class ListProducerNodeBuilder extends AbstractProducerNodeBuilder {
411     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
412     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
413     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
414     private final static String   LIST_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
415     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
416     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
417     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
418     private final static String[] LIST_REQUIRED_ATTRIBUTES = { LIST_KEY_ATTRIBUTE, LIST_DEFINITION_ATTRIBUTE };
419     private final static String[] LIST_OPTIONAL_ATTRIBUTES = { LIST_SELECTION_ATTRIBUTE, LIST_ORDER_ATTRIBUTE, LIST_SKIP_ATTRIBUTE, LIST_LIMIT_ATTRIBUTE,LIST_EXTRATABLES_ATTRIBUTE};
420     private final static String[] LIST_SUBNODES = {};
421
422     private String key;
423     private String definition;
424     private String mainTablePrefix;
425     private String extraTables;
426     private String selection;
427     private String order;
428     private String limit;
429     private String skip;
430     private EntityAdapterModel model;
431
432     public ListProducerNodeBuilder(EntityAdapterModel aModel) {
433       super(LIST_SUBNODES);
434
435       model = aModel;
436     }
437
438     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
439       XMLReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
440
441       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
442       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
443       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
444       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
445       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
446       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
447       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_EXTRATABLES_ATTRIBUTE,"");
448       List parts = StringRoutines.splitString(definition.trim()," ");
449       if (parts.size()>0) definition=(String)parts.get(0);
450       if (parts.size()>1) mainTablePrefix=(String)parts.get(1);
451
452     }
453
454     public ProducerNode constructNode() {
455       return new EntityListProducerNode(key, model, mainTablePrefix, extraTables, definition, selection, order, limit, skip, null );
456     }
457
458     public static class factory implements ProducerNodeBuilderFactory {
459       private EntityAdapterModel model;
460
461       public factory(EntityAdapterModel aModel) {
462         model = aModel;
463       }
464
465       public ProducerNodeBuilder makeBuilder() {
466         return new ListProducerNodeBuilder(model);
467       }
468     }
469   }
470
471 ////////////////////////////////////////////////////////////////////////////////
472
473   public static class DeleteEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
474     private final static String   DELETEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
475     private final static String   DELETEENTITY_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
476     private final static String[] DELETEENTITY_REQUIRED_ATTRIBUTES = { DELETEENTITY_SELECTION_ATTRIBUTE, DELETEENTITY_DEFINITION_ATTRIBUTE };
477     private final static String[] DELETEENTITY_OPTIONAL_ATTRIBUTES = { };
478     private final static String[] DELETEENTITY_SUBNODES = {};
479
480     private String definition;
481     private String selection;
482
483     private EntityAdapterModel model;
484
485     public DeleteEntityProducerNodeBuilder(EntityAdapterModel aModel) {
486       super(DELETEENTITY_SUBNODES);
487
488       model = aModel;
489     }
490
491     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
492       XMLReaderTool.checkAttributes(anAttributes, DELETEENTITY_REQUIRED_ATTRIBUTES, DELETEENTITY_OPTIONAL_ATTRIBUTES);
493
494       definition = (String) anAttributes.get(DELETEENTITY_DEFINITION_ATTRIBUTE);
495       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, DELETEENTITY_SELECTION_ATTRIBUTE, "");
496     }
497
498     public ProducerNode constructNode() {
499       return new EntityDeletingProducerNode(model, definition, selection);
500     }
501
502     public static class factory implements ProducerNodeBuilderFactory {
503       private EntityAdapterModel model;
504
505       public factory(EntityAdapterModel aModel) {
506         model = aModel;
507       }
508
509       public ProducerNodeBuilder makeBuilder() {
510         return new DeleteEntityProducerNodeBuilder(model);
511       }
512     }
513   }
514
515 ////////////////////////////////////////////////////////////////////////////////
516
517   public static class LoggingProducerNodeBuilder extends AbstractProducerNodeBuilder {
518     private final static String   LOG_MESSAGE_ATTRIBUTE = "message";
519     private final static String   LOG_TYPE_ATTRIBUTE = "type";
520     private final static String[] LOG_REQUIRED_ATTRIBUTES = { LOG_MESSAGE_ATTRIBUTE };
521     private final static String[] LOG_OPTIONAL_ATTRIBUTES = { LOG_TYPE_ATTRIBUTE };
522     private final static String[] LOG_SUBNODES = {};
523
524     private String message;
525     private int type = LoggerWrapper.INFO_MESSAGE;
526
527     public LoggingProducerNodeBuilder() {
528       super(LOG_SUBNODES);
529     }
530
531     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
532       String typeString;
533
534       XMLReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
535
536       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
537       if (anAttributes.containsKey(LOG_TYPE_ATTRIBUTE)) {
538         typeString = ((String) anAttributes.get( LOG_TYPE_ATTRIBUTE ));
539
540         if (typeString.toLowerCase().equals("debug"))
541           type = LoggerWrapper.DEBUG_MESSAGE;
542         else if (typeString.toLowerCase().equals("info"))
543           type = LoggerWrapper.INFO_MESSAGE;
544         else if (typeString.toLowerCase().equals("error"))
545           type = LoggerWrapper.ERROR_MESSAGE;
546         else if (typeString.toLowerCase().equals("warning"))
547           type = LoggerWrapper.WARN_MESSAGE;
548         else if (typeString.toLowerCase().equals("fatal"))
549           type = LoggerWrapper.FATAL_MESSAGE;
550         else
551           throw new ProducerConfigExc("unknown log type: " + typeString + " (allowed are debug, info, warning, error, fatal)");
552       }
553       else
554         type = LoggerWrapper.INFO_MESSAGE;
555     }
556
557     public ProducerNode constructNode() {
558       return new LoggingProducerNode(message, type);
559     }
560   }
561
562 ////////////////////////////////////////////////////////////////////////////////
563
564   public static class FreeQueryProducerNodeBuilder extends AbstractProducerNodeBuilder {
565     private final static String   FREEQUERY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
566     private final static String   FREEQUERY_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
567     private final static String   FREEQUERY_QUERY_ATTRIBUTE = "query";
568     private final static String   FREEQUERY_TYPE_ATTRIBUTE = "type";
569     private final static String[] FREEQUERY_REQUIRED_ATTRIBUTES = { KEY_ATTRIBUTE, FREEQUERY_QUERY_ATTRIBUTE };
570     private final static String[] FREEQUERY_OPTIONAL_ATTRIBUTES = { LIMIT_ATTRIBUTE, FREEQUERY_TYPE_ATTRIBUTE };
571     private final static String[] FREEQUERY_SUBNODES = {};
572
573     private String key;
574     private String query;
575     private String limit;
576     private int type;
577
578     public FreeQueryProducerNodeBuilder() {
579       super(FREEQUERY_SUBNODES);
580     }
581
582     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
583       String typeString;
584
585       XMLReaderTool.checkAttributes(anAttributes, FREEQUERY_REQUIRED_ATTRIBUTES, FREEQUERY_OPTIONAL_ATTRIBUTES);
586
587       key = (String) anAttributes.get(FREEQUERY_KEY_ATTRIBUTE);
588       query = (String) anAttributes.get(FREEQUERY_QUERY_ATTRIBUTE);
589       limit = (String) anAttributes.get(FREEQUERY_LIMIT_ATTRIBUTE);
590
591       if (anAttributes.containsKey(FREEQUERY_TYPE_ATTRIBUTE)) {
592         typeString = ((String) anAttributes.get( FREEQUERY_TYPE_ATTRIBUTE ));
593
594         if (typeString.toLowerCase().equals("set"))
595           type = FreeQueryProducerNode.QUERY_TYPE_SET;
596         else if (typeString.toLowerCase().equals("row"))
597           type = FreeQueryProducerNode.QUERY_TYPE_ROW;
598         else if (typeString.toLowerCase().equals("value"))
599           type = FreeQueryProducerNode.QUERY_TYPE_VALUE;
600         else if (typeString.toLowerCase().equals("update"))
601           type = FreeQueryProducerNode.QUERY_TYPE_UPDATE;
602         else
603           throw new ProducerConfigExc("unknown query type: " + typeString + " (allowed are set, row and value)");
604       }
605       else
606         type = FreeQueryProducerNode.QUERY_TYPE_SET;
607     }
608
609     public ProducerNode constructNode() {
610       return new FreeQueryProducerNode(key, query, limit, type);
611     }
612   }
613 ////////////////////////////////////////////////////////////////////////////////
614
615   public static class ExternalDbProducerNodeBuilder extends AbstractProducerNodeBuilder {
616     private final static String   EXTDB_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
617     private final static String   EXTDB_DRIVER_ATTRIBUTE = "driver";
618     private final static String   EXTDB_HOST_ATTRIBUTE = "host";
619     private final static String   EXTDB_PORT_ATTRIBUTE = "port";
620     private final static String   EXTDB_DATABASE_ATTRIBUTE = "database";
621     private final static String   EXTDB_USERNAME_ATTRIBUTE = "username";
622     private final static String   EXTDB_PASSWORD_ATTRIBUTE = "password";
623     private final static String   EXTDB_QUERY_ATTRIBUTE = "query";
624     private final static String   EXTDB_DEFAULT_SUBNODE = "default";
625     private final static String[] EXTDB_REQUIRED_ATTRIBUTES = { KEY_ATTRIBUTE, EXTDB_DRIVER_ATTRIBUTE, EXTDB_HOST_ATTRIBUTE, EXTDB_PORT_ATTRIBUTE, EXTDB_DATABASE_ATTRIBUTE, EXTDB_USERNAME_ATTRIBUTE, EXTDB_PASSWORD_ATTRIBUTE, EXTDB_QUERY_ATTRIBUTE };
626     private final static String[] EXTDB_OPTIONAL_ATTRIBUTES = { };
627     private final static String[] EXTDB_SUBNODES = {EXTDB_DEFAULT_SUBNODE};
628
629     private String key;
630     private String driver;
631     private String host;
632     private String port;
633     private String database;
634     private String username;
635     private String password;
636     private String query;   
637
638
639     public ExternalDbProducerNodeBuilder() {
640       super(EXTDB_SUBNODES);
641     }
642
643     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
644       XMLReaderTool.checkAttributes(anAttributes, EXTDB_REQUIRED_ATTRIBUTES, EXTDB_OPTIONAL_ATTRIBUTES);
645
646       key = (String) anAttributes.get(EXTDB_KEY_ATTRIBUTE);
647       driver = (String) anAttributes.get(EXTDB_DRIVER_ATTRIBUTE);
648       host = (String) anAttributes.get(EXTDB_HOST_ATTRIBUTE);
649       port = (String) anAttributes.get(EXTDB_PORT_ATTRIBUTE);
650       database = (String) anAttributes.get(EXTDB_DATABASE_ATTRIBUTE);
651       username = (String) anAttributes.get(EXTDB_USERNAME_ATTRIBUTE);
652       password = (String) anAttributes.get(EXTDB_PASSWORD_ATTRIBUTE);
653       query = (String) anAttributes.get(EXTDB_QUERY_ATTRIBUTE);
654     }
655
656     public ProducerNode constructNode() {
657       return new ExternalDbProducerNode(key, driver, host, port, database, username, password, query,  getSubNode(EXTDB_DEFAULT_SUBNODE));
658     }
659   }
660
661 ////////////////////////////////////////////////////////////////////////////////
662
663   public static class BundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
664     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
665     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
666     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
667     private final static String[] RESOURCEBUNDLE_REQUIRED_ATTRIBUTES = { RESOURCEBUNDLE_KEY_ATTRIBUTE, RESOURCEBUNDLE_BUNDLE_ATTRIBUTE };
668     private final static String[] RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES = { RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE};
669     private final static String[] RESOURCEBUNDLE_SUBNODES = {};
670
671     private String key;
672     private String bundle;
673     private String language;
674
675     public BundleProducerNodeBuilder() {
676       super(RESOURCEBUNDLE_SUBNODES);
677     }
678
679     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
680       XMLReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
681
682       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
683       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
684       language = (String) anAttributes.get(RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE);
685     }
686
687     public ProducerNode constructNode() {
688       return new BundleProducerNode(key, bundle, language);
689     }
690   }
691
692 ////////////////////////////////////////////////////////////////////////////////
693
694   public static class FileDateSettingProducerNodeBuilder extends AbstractProducerNodeBuilder {
695     private final static String   FILEDATESETTING_FILE_ATTRIBUTE = "filename";
696     private final static String   FILEDATESETTING_DATE_ATTRIBUTE = "date";
697     private final static String[] FILEDATESETTING_REQUIRED_ATTRIBUTES = { FILEDATESETTING_FILE_ATTRIBUTE, FILEDATESETTING_DATE_ATTRIBUTE };
698     private final static String[] FILEDATESETTING_OPTIONAL_ATTRIBUTES = { };
699     private final static String[] FILEDATESETTING_SUBNODES = {};
700
701     private String fileNameKey;
702     private String dateKey;
703
704     public FileDateSettingProducerNodeBuilder() {
705       super(FILEDATESETTING_SUBNODES);
706     }
707
708     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
709       XMLReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
710
711       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
712       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
713     }
714
715     public ProducerNode constructNode() {
716       return new FileDateSettingProducerNode(fileNameKey, dateKey);
717     }
718   }
719
720 ////////////////////////////////////////////////////////////////////////////////
721
722   public static class FileDeletingProducerNodeBuilder extends AbstractProducerNodeBuilder {
723     private final static String   FILEDELETING_FILE_ATTRIBUTE = "filename";
724     private final static String[] FILEDELETING_REQUIRED_ATTRIBUTES = { FILEDELETING_FILE_ATTRIBUTE };
725     private final static String[] FILEDELETING_OPTIONAL_ATTRIBUTES = { };
726     private final static String[] FILEDELETING_SUBNODES = { };
727
728     private String fileNameKey;
729
730     public FileDeletingProducerNodeBuilder() {
731       super(FILEDELETING_SUBNODES);
732     }
733
734     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
735       XMLReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
736
737       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
738     }
739
740     public ProducerNode constructNode() {
741       return new FileDeletingProducerNode(fileNameKey);
742     }
743   }
744
745 ////////////////////////////////////////////////////////////////////////////////
746
747   public static class ExecuteProgramProducerNodeBuilder extends AbstractProducerNodeBuilder {
748     private final static String   EXECUTEPROGRAM_COMMAND_ATTRIBUTE = "command";
749     private final static String   EXECUTEPROGRAM_MAXTIME_ATTRIBUTE = "maxduration";
750     private final static String   EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE = "resultvar";
751     private final static String   EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE = "returnvaluevar";
752     private final static String[] EXECUTEPROGRAM_REQUIRED_ATTRIBUTES = { EXECUTEPROGRAM_COMMAND_ATTRIBUTE };
753     private final static String[] EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES = { EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE };
754     private final static String[] EXECUTEPROGRAM_SUBNODES = {};
755
756     private String command;
757     private String time;
758     private String resultvar;
759     private String returnValueVar;
760
761     public ExecuteProgramProducerNodeBuilder() {
762       super(EXECUTEPROGRAM_SUBNODES);
763     }
764
765     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
766       XMLReaderTool.checkAttributes(anAttributes, EXECUTEPROGRAM_REQUIRED_ATTRIBUTES, EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES);
767
768       command = (String) anAttributes.get(EXECUTEPROGRAM_COMMAND_ATTRIBUTE);
769       time = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, null);
770       resultvar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE, null);
771       returnValueVar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE, null);
772     }
773
774     public ProducerNode constructNode() {
775       return new
776           ExecuteProgramProducerNode(command, time, resultvar, returnValueVar);
777     }
778   }
779
780 ////////////////////////////////////////////////////////////////////////////////
781
782   private final static String   DIRCOPY_SOURCE_ATTRIBUTE = "source";
783   private final static String   DIRCOPY_DESTINATION_ATTRIBUTE = "destination";
784   private final static String[] DIRCOPY_REQUIRED_ATTRIBUTES = { DIRCOPY_SOURCE_ATTRIBUTE, DIRCOPY_DESTINATION_ATTRIBUTE };
785   private final static String[] DIRCOPY_OPTIONAL_ATTRIBUTES = {};
786   private final static String[] DIRCOPY_SUBNODES = {};
787
788   public static class DirCopyProducerNodeBuilder extends AbstractProducerNodeBuilder {
789     private String source;
790     private String destination;
791     private File sourceBasePath;
792     private File destinationBasePath;
793
794     public DirCopyProducerNodeBuilder(File aSourceBasePath, File aDestinationBasePath) {
795       super(DIRCOPY_SUBNODES);
796
797       sourceBasePath = aSourceBasePath;
798       destinationBasePath = aDestinationBasePath;
799     }
800
801     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
802       XMLReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
803
804       source = (String) anAttributes.get(DIRCOPY_SOURCE_ATTRIBUTE);
805       destination = (String) anAttributes.get(DIRCOPY_DESTINATION_ATTRIBUTE);
806     }
807
808     public ProducerNode constructNode() {
809       return new DirCopyingProducerNode(sourceBasePath, destinationBasePath, source, destination);
810     }
811
812     public static class factory implements ProducerNodeBuilderFactory {
813       private File sourceBasePath;
814       private File destinationBasePath;
815
816       public factory(File aSourceBasePath, File aDestinationBasePath) {
817         sourceBasePath = aSourceBasePath;
818         destinationBasePath = aDestinationBasePath;
819       }
820
821       public ProducerNodeBuilder makeBuilder() {
822         return new DirCopyProducerNodeBuilder(sourceBasePath, destinationBasePath);
823       }
824     }
825   }
826
827 ////////////////////////////////////////////////////////////////////////////////
828
829   public static class GeneratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
830     private final static String   GENERATION_GENERATOR_ATTRIBUTE = "generator";
831     private final static String   GENERATION_DESTINATION_ATTRIBUTE = "destination";
832     private final static String   GENERATION_PARAMETERS_ATTRIBUTE = "parameters";
833     private final static String[] GENERATION_REQUIRED_ATTRIBUTES = { GENERATION_GENERATOR_ATTRIBUTE, GENERATION_DESTINATION_ATTRIBUTE };
834     private final static String[] GENERATION_OPTIONAL_ATTRIBUTES = { GENERATION_PARAMETERS_ATTRIBUTE};
835     private final static String[] GENERATION_SUBNODES = {};
836
837     private String generator;
838     private String destination;
839     private String parameters;
840     private Generator.Library generatorLibrary;
841     private WriterEngine writerEngine;
842     private Generator.Interceptor interceptor;
843
844     public GeneratingProducerNodeBuilder(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine,
845                                          Generator.Interceptor anInterceptor) {
846       super(GENERATION_SUBNODES);
847
848       writerEngine = aWriterEngine;
849       generatorLibrary = aGeneratorLibrary;
850       interceptor = anInterceptor;
851     }
852
853     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
854       XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
855
856       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
857       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
858       parameters = XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
859     }
860
861     public ProducerNode constructNode() {
862       return new GeneratingProducerNode(generatorLibrary, writerEngine, interceptor, generator, destination, parameters);
863     }
864
865     public static class factory implements ProducerNodeBuilderFactory {
866       private Generator.Library generatorLibrary;
867       private WriterEngine writerEngine;
868       private Generator.Interceptor interceptor;
869
870       public factory(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine, Generator.Interceptor anInterceptor) {
871         writerEngine = aWriterEngine;
872         generatorLibrary = aGeneratorLibrary;
873         interceptor = anInterceptor;
874       }
875
876       public ProducerNodeBuilder makeBuilder() {
877         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine, interceptor);
878       }
879     }
880   }
881
882 ////////////////////////////////////////////////////////////////////////////////
883
884   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
885
886     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
887     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
888     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
889     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
890     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
891
892     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
893     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
894     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
895
896     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
897     private final static String   BATCHER_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
898
899     private final static String   BATCHER_BATCH_SUBNODE = "batches";
900     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
901     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
902     private final static String[] BATCHER_OPTIONAL_ATTRIBUTES = { BATCHER_SELECTION_ATTRIBUTE, BATCHER_ORDER_ATTRIBUTE, BATCHER_MINBATCHSIZE_ATTRIBUTE, BATCHER_SKIP_ATTRIBUTE, BATCHER_PROCESS_ATTRIBUTE, BATCHER_EXTRATABLES_ATTRIBUTE };
903     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
904
905     private EntityAdapterModel model;
906     private String batchDataKey;
907     private String batchInfoKey;
908     private String mainTablePrefix;
909     private String extraTables;
910     private String definition;
911     private String selection;
912     private String order;
913     private String batchSize;
914     private String minBatchSize;
915     private String skip;
916     private String process;
917
918     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
919       super(BATCHER_SUBNODES);
920
921       model = aModel;
922     }
923
924     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
925       XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
926
927       batchDataKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
928       batchInfoKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
929       definition = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
930       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
931       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
932
933       batchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
934       minBatchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
935       skip = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
936       process = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
937
938       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_EXTRATABLES_ATTRIBUTE, "");
939
940       List parts = StringRoutines.splitString(definition.trim(), " ");
941       if (parts.size()>0) definition = (String) parts.get(0);
942       if (parts.size()>1) mainTablePrefix = (String) parts.get(1);
943     }
944
945     public ProducerNode constructNode() {
946       return new EntityBatchingProducerNode(
947           batchDataKey,
948           batchInfoKey,
949           model,
950           mainTablePrefix,
951           extraTables,
952           definition,
953           selection,
954           order,
955           batchSize,
956           minBatchSize,
957           skip,
958           process,
959           getSubNode( BATCHER_BATCH_SUBNODE ),
960           getSubNode( BATCHER_BATCHLIST_SUBNODE )
961       );
962     }
963
964     public static class factory implements ProducerNodeBuilderFactory {
965       private EntityAdapterModel model;
966
967       public factory(EntityAdapterModel aModel) {
968         model = aModel;
969       }
970
971       public ProducerNodeBuilder makeBuilder() {
972         return new BatchingProducerNodeBuilder(model);
973       }
974     }
975   }
976
977 ////////////////////////////////////////////////////////////////////////////////
978
979   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
980     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
981
982     private final static String   IF_TRUE_SUBNODE = "then";
983     private final static String   IF_FALSE_SUBNODE = "else";
984     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
985     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
986     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
987
988     private String condition;
989
990     public ConditionalProducerNodeBuilder() {
991       super(IF_SUBNODES);
992     }
993
994     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
995       XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
996
997       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
998     }
999
1000     public ProducerNode constructNode() {
1001       return new ConditionalProducerNode(
1002           condition,
1003           getSubNode( IF_TRUE_SUBNODE ),
1004           getSubNode( IF_FALSE_SUBNODE )
1005       );
1006     }
1007
1008   }
1009
1010 ////////////////////////////////////////////////////////////////////////////////
1011
1012   public static class RSSProducerNodeBuilder extends AbstractProducerNodeBuilder {
1013     private final static String   RSS_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1014     private final static String   RSS_URL_ATTRIBUTE = URL_ATTRIBUTE;
1015     private final static String   RSS_ENCODING_ATTRIBUTE = "encoding";
1016     private final static String   RSS_VERSION_ATTRIBUTE = "version";
1017
1018     private final static String[] RSS_REQUIRED_ATTRIBUTES = { RSS_KEY_ATTRIBUTE, RSS_URL_ATTRIBUTE };
1019     private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE, RSS_ENCODING_ATTRIBUTE };
1020     private final static String[] RSS_SUBNODES = {  };
1021
1022     private String key;
1023     private String url;
1024     private String version;
1025     private String encoding;
1026
1027     public RSSProducerNodeBuilder() {
1028       super(RSS_SUBNODES);
1029     }
1030
1031     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1032       XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
1033
1034       key = (String) anAttributes.get( RSS_KEY_ATTRIBUTE );
1035       url = (String) anAttributes.get( RSS_URL_ATTRIBUTE );
1036       version = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
1037       encoding = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_ENCODING_ATTRIBUTE, null);
1038     }
1039
1040     public ProducerNode constructNode() {
1041       return new RSSProducerNode(key, url, version, encoding);
1042     }
1043   }
1044
1045 ////////////////////////////////////////////////////////////////////////////////
1046
1047   public static class RDFAggregatorProducerNodeBuilder extends AbstractProducerNodeBuilder {
1048     private final static String   RDF_AGGREGATOR_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1049     private final static String   RDF_AGGREGATOR_SOURCE_ATTRIBUTE = "source";
1050
1051     private final static String[] RDF_AGGREGATOR_REQUIRED_ATTRIBUTES = { RDF_AGGREGATOR_KEY_ATTRIBUTE, RDF_AGGREGATOR_SOURCE_ATTRIBUTE };
1052     private final static String[] RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES = {  };
1053     private final static String[] RDF_AGGREGATOR_SUBNODES = {  };
1054
1055     private String key;
1056     private String source;
1057     private String order;
1058     private String filter;
1059
1060     public RDFAggregatorProducerNodeBuilder() {
1061       super(RDF_AGGREGATOR_SUBNODES);
1062     }
1063
1064     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1065       XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
1066
1067       key = (String) anAttributes.get( RDF_AGGREGATOR_KEY_ATTRIBUTE );
1068       source = (String) anAttributes.get( RDF_AGGREGATOR_SOURCE_ATTRIBUTE );
1069     }
1070
1071     public ProducerNode constructNode() {
1072       return new RDFAggregatorProducerNode(key, source);
1073     }
1074   }
1075
1076 ////////////////////////////////////////////////////////////////////////////////
1077
1078   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
1079     private String parameterName;
1080     private String scriptedNodeName;
1081
1082     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
1083       parameterName = aParameterName;
1084       scriptedNodeName = aScriptedNodeName;
1085     }
1086
1087     public void setSubNode(String aName, ProducerNode aNode) {
1088     }
1089
1090     public Set getAvailableSubNodes() {
1091       return new HashSet();
1092     }
1093
1094     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
1095       if (!anAttributes.isEmpty())
1096         throw new ProducerConfigExc("No parameters allowed here");
1097     }
1098
1099     public ProducerNode constructNode() {
1100       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
1101     }
1102   }
1103
1104 ////////////////////////////////////////////////////////////////////////////////
1105
1106   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
1107     private ScriptedProducerNodeDefinition definition;
1108     private Map nodeParameterValues;
1109     private Map integerParameterValues;
1110     private Map stringParameterValues;
1111
1112     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
1113       definition = aDefinition;
1114
1115       stringParameterValues = new HashMap();
1116       stringParameterValues.putAll(definition.getStringParameters());
1117
1118       integerParameterValues = new HashMap();
1119       integerParameterValues.putAll(definition.getIntegerParameters());
1120
1121       nodeParameterValues = new HashMap();
1122     }
1123
1124     public void setSubNode(String aName, ProducerNode aNode) {
1125       nodeParameterValues.put(aName, aNode);
1126     }
1127
1128     public Set getAvailableSubNodes() {
1129       return definition.getNodeParameters();
1130     }
1131
1132     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1133       XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
1134
1135       Iterator i = anAttributes.entrySet().iterator();
1136       while (i.hasNext()) {
1137         Map.Entry entry = (Map.Entry) i.next();
1138
1139         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
1140           integerParameterValues.put(entry.getKey(), entry.getValue());
1141         else
1142           stringParameterValues.put(entry.getKey(), entry.getValue());
1143       }
1144     }
1145
1146     public ProducerNode constructNode() {
1147       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
1148     }
1149
1150     public static class factory implements ProducerNodeBuilderFactory {
1151       private ScriptedProducerNodeDefinition definition;
1152
1153       public factory(ScriptedProducerNodeDefinition aDefinition) {
1154         definition = aDefinition;
1155       }
1156
1157       public ProducerNodeBuilder makeBuilder() {
1158         return new ScriptedProducerNodeBuilder(definition);
1159       }
1160     }
1161   }
1162 }