1.1 restoration
[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.util.Arrays;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 import java.io.File;
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.ConditionalProducerNode;
46 import mir.producer.DirCopyingProducerNode;
47 import mir.producer.EntityBatchingProducerNode;
48 import mir.producer.EntityDeletingProducerNode;
49 import mir.producer.EntityEnumeratingProducerNode;
50 import mir.producer.EntityListProducerNode;
51 import mir.producer.EntityModifyingProducerNode;
52 import mir.producer.EvaluatedAssignmentProducerNode;
53 import mir.producer.ExpandedAssignmentProducerNode;
54 import mir.producer.ExternalDbProducerNode;
55 import mir.producer.FileDateSettingProducerNode;
56 import mir.producer.FileDeletingProducerNode;
57 import mir.producer.FreeQueryProducerNode;
58 import mir.producer.GeneratingProducerNode;
59 import mir.producer.ListEnumeratingProducerNode;
60 import mir.producer.LoggingProducerNode;
61 import mir.producer.LoopProducerNode;
62 import mir.producer.ProducerNode;
63 import mir.producer.RDFAggregatorProducerNode;
64 import mir.producer.RSSProducerNode;
65 import mir.producer.BundleProducerNode;
66 import mir.producer.ExecuteProgramProducerNode;
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        WriterEngine aWriterEngine, File aSourceBasePath, File aDestinationBasePath) throws ProducerConfigExc {
76
77     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
78     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
79     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
80     aBuilderLibrary.registerBuilder("Execute", ExecuteProgramProducerNodeBuilder.class);
81     aBuilderLibrary.registerBuilder("Resource", BundleProducerNodeBuilder.class);
82     aBuilderLibrary.registerBuilder("Bundle", BundleProducerNodeBuilder.class);
83     aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory(aSourceBasePath, aDestinationBasePath));
84
85     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
86     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
87     aBuilderLibrary.registerBuilder("If", ConditionalProducerNodeBuilder.class);
88     aBuilderLibrary.registerBuilder("While", LoopProducerNodeBuilder.class);
89
90     aBuilderLibrary.registerBuilder("RSS", RSSProducerNodeBuilder.class);
91     aBuilderLibrary.registerBuilder("RDFAggregate", RDFAggregatorProducerNodeBuilder.class);
92
93     aBuilderLibrary.registerBuilder("FreeQuery", FreeQueryProducerNodeBuilder.class);
94     aBuilderLibrary.registerBuilder("ExternalDbQuery", ExternalDbProducerNodeBuilder.class);
95
96     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
97     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
98     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
99
100     aBuilderLibrary.registerFactory("UpdateEntity", new UpdateEntityProducerNodeBuilder.factory(aModel));
101     aBuilderLibrary.registerFactory("CreateEntity", new CreateEntityProducerNodeBuilder.factory(aModel));
102     aBuilderLibrary.registerFactory("DeleteEntity", new DeleteEntityProducerNodeBuilder.factory(aModel));
103
104     aBuilderLibrary.registerFactory("Generate", new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
105   }
106
107   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
108     private Map subNodes;
109     private Set availableSubnodes;
110
111     public AbstractProducerNodeBuilder(String anAvailableSubNodes[]) {
112       subNodes = new HashMap();
113       availableSubnodes = new HashSet(Arrays.asList(anAvailableSubNodes));
114     }
115
116     protected ProducerNode getSubNode(String aName) {
117       return (ProducerNode) subNodes.get(aName);
118     }
119
120     public void setSubNode(String aName, ProducerNode aNode) {
121       subNodes.put(aName, aNode);
122     };
123
124     public Set getAvailableSubNodes() {
125       return availableSubnodes;
126     };
127   }
128
129 ////////////////////////////////////////////////////////////////////////////////
130
131   // general attribute names, specifc builders reference these, to keep attribute
132   //    names consistent
133
134   public final static String   EXTRA_TABLES_ATTRIBUTE = "extratables";
135   public final static String   SELECTION_ATTRIBUTE = "selection";
136   public final static String   ORDER_ATTRIBUTE = "order";
137   public final static String   DEFINITION_ATTRIBUTE = "table";
138   public final static String   SKIP_ATTRIBUTE = "skip";
139   public final static String   KEY_ATTRIBUTE = "key";
140   public final static String   LIMIT_ATTRIBUTE = "limit";
141   public final static String   URL_ATTRIBUTE = "url";
142
143 ////////////////////////////////////////////////////////////////////////////////
144
145   private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
146   private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
147   private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
148   private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
149   private final static String[] ASSIGNMENT_SUBNODES = {};
150
151   public static class ExpandedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
152
153     private String key;
154     private String value;
155
156     public ExpandedAssignmentProducerNodeBuilder() {
157       super(ASSIGNMENT_SUBNODES);
158     }
159
160     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
161       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
162
163       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
164       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
165     };
166
167     public ProducerNode constructNode() {
168       return new ExpandedAssignmentProducerNode(key, value);
169     };
170   }
171
172 ////////////////////////////////////////////////////////////////////////////////
173
174   public static class EvaluatedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
175
176     private String key;
177     private String value;
178
179     public EvaluatedAssignmentProducerNodeBuilder() {
180       super(ASSIGNMENT_SUBNODES);
181     }
182
183     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
184       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
185
186       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
187       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
188     };
189
190     public ProducerNode constructNode() {
191       return new EvaluatedAssignmentProducerNode(key, value);
192     };
193   }
194
195 ////////////////////////////////////////////////////////////////////////////////
196
197   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
198     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
199     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
200     private final static String   ENUMERATION_LIST_ATTRIBUTE = "list";
201     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
202     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
203     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
204     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
205     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
206     private final static String   ENUMERATION_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
207     private final static String[] ENUMERATION_LIST_REQUIRED_ATTRIBUTES = { ENUMERATION_LIST_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
208     private final static String[] ENUMERATION_LIST_OPTIONAL_ATTRIBUTES = { };
209     private final static String[] ENUMERATION_QUERY_REQUIRED_ATTRIBUTES = { ENUMERATION_DEFINITION_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
210     private final static String[] ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE,ENUMERATION_EXTRATABLES_ATTRIBUTE};
211     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
212
213     private String key;
214     private String definition;
215     private String mainTablePrefix;
216     private String extraTables;
217     private String list;
218     private String selection;
219     private String order;
220     private String limit;
221     private String skip;
222     private EntityAdapterModel model;
223
224     public EnumeratingProducerNodeBuilder(EntityAdapterModel aModel) {
225       super(ENUMERATION_SUBNODES);
226
227       model = aModel;
228     }
229
230     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
231       definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
232       list = (String) anAttributes.get(ENUMERATION_LIST_ATTRIBUTE);
233
234       if ((list==null && definition==null) || (list!=null && definition!=null))
235         throw new ProducerConfigExc("Exactly one of "+ENUMERATION_DEFINITION_ATTRIBUTE+" and "+ENUMERATION_LIST_ATTRIBUTE+" must be set");
236
237
238       if (list!=null)
239         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
240       if (definition!=null)
241         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
242
243
244       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
245       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
246       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
247       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
248       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
249       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_EXTRATABLES_ATTRIBUTE,"");
250       if (definition!=null) {
251         List parts = StringRoutines.splitString(definition.trim(), " ");
252         if (parts.size() > 0)
253           definition = (String) parts.get(0);
254         if (parts.size() > 1)
255           mainTablePrefix = (String) parts.get(1);
256       }
257     };
258
259     public ProducerNode constructNode() {
260       if (definition!=null)
261         return new EntityEnumeratingProducerNode(key, model, mainTablePrefix, extraTables, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
262       else
263         return new ListEnumeratingProducerNode(key, list, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
264     };
265
266     public static class factory implements ProducerNodeBuilderFactory {
267       private EntityAdapterModel model;
268
269       public factory(EntityAdapterModel aModel) {
270         model = aModel;
271       }
272
273       public ProducerNodeBuilder makeBuilder() {
274         return new EnumeratingProducerNodeBuilder(model);
275       }
276     }
277   }
278
279 ////////////////////////////////////////////////////////////////////////////////
280
281   public static class UpdateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
282     private final static String   UPDATE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
283     private final static String   UPDATE_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
284     private final static String[] UPDATE_SUBNODES = {};
285
286     private String key;
287     private String definition;
288     private Map fieldValues;
289
290     private EntityAdapterModel model;
291
292     public UpdateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
293       super(UPDATE_SUBNODES);
294
295       model = aModel;
296       fieldValues = new HashMap();
297     }
298
299     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
300       key = (String) anAttributes.get(UPDATE_KEY_ATTRIBUTE);
301
302       if (key == null)
303         throw new XMLParserExc("missing required attribute '" + UPDATE_KEY_ATTRIBUTE + "'" );
304       definition = (String) anAttributes.get(UPDATE_DEFINITION_ATTRIBUTE);
305
306       fieldValues.putAll(anAttributes);
307       fieldValues.remove(UPDATE_KEY_ATTRIBUTE);
308       fieldValues.remove(UPDATE_DEFINITION_ATTRIBUTE);
309     };
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
843     public GeneratingProducerNodeBuilder(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
844       super(GENERATION_SUBNODES);
845
846       writerEngine = aWriterEngine;
847       generatorLibrary = aGeneratorLibrary;
848     }
849
850     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
851       XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
852
853       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
854       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
855       parameters = XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
856     };
857
858     public ProducerNode constructNode() {
859       return new GeneratingProducerNode(generatorLibrary, writerEngine, generator, destination, parameters);
860     };
861
862     public static class factory implements ProducerNodeBuilderFactory {
863       private Generator.Library generatorLibrary;
864       private WriterEngine writerEngine;
865
866       public factory(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
867         writerEngine = aWriterEngine;
868         generatorLibrary = aGeneratorLibrary;
869       }
870
871       public ProducerNodeBuilder makeBuilder() {
872         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine);
873       }
874     }
875   }
876
877 ////////////////////////////////////////////////////////////////////////////////
878
879   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
880
881     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
882     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
883     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
884     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
885     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
886
887     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
888     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
889     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
890
891     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
892     private final static String   BATCHER_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
893
894     private final static String   BATCHER_BATCH_SUBNODE = "batches";
895     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
896     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
897     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 };
898     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
899
900     private EntityAdapterModel model;
901     private String batchDataKey;
902     private String batchInfoKey;
903     private String mainTablePrefix;
904     private String extraTables;
905     private String definition;
906     private String selection;
907     private String order;
908     private String batchSize;
909     private String minBatchSize;
910     private String skip;
911     private String process;
912
913     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
914       super(BATCHER_SUBNODES);
915
916       model = aModel;
917     }
918
919     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
920       XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
921
922       batchDataKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
923       batchInfoKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
924       definition = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
925       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
926       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
927
928       batchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
929       minBatchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
930       skip = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
931       process = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
932
933       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_EXTRATABLES_ATTRIBUTE, "");
934
935       List parts = StringRoutines.splitString(definition.trim(), " ");
936       if (parts.size()>0) definition = (String) parts.get(0);
937       if (parts.size()>1) mainTablePrefix = (String) parts.get(1);
938     };
939
940     public ProducerNode constructNode() {
941       return new EntityBatchingProducerNode(
942           batchDataKey,
943           batchInfoKey,
944           model,
945           mainTablePrefix,
946           extraTables,
947           definition,
948           selection,
949           order,
950           batchSize,
951           minBatchSize,
952           skip,
953           process,
954           getSubNode( BATCHER_BATCH_SUBNODE ),
955           getSubNode( BATCHER_BATCHLIST_SUBNODE )
956       );
957     };
958
959     public static class factory implements ProducerNodeBuilderFactory {
960       private EntityAdapterModel model;
961
962       public factory(EntityAdapterModel aModel) {
963         model = aModel;
964       }
965
966       public ProducerNodeBuilder makeBuilder() {
967         return new BatchingProducerNodeBuilder(model);
968       }
969     }
970   }
971
972 ////////////////////////////////////////////////////////////////////////////////
973
974   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
975     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
976
977     private final static String   IF_TRUE_SUBNODE = "then";
978     private final static String   IF_FALSE_SUBNODE = "else";
979     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
980     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
981     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
982
983     private String condition;
984
985     public ConditionalProducerNodeBuilder() {
986       super(IF_SUBNODES);
987     }
988
989     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
990       XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
991
992       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
993     };
994
995     public ProducerNode constructNode() {
996       return new ConditionalProducerNode(
997           condition,
998           getSubNode( IF_TRUE_SUBNODE ),
999           getSubNode( IF_FALSE_SUBNODE )
1000       );
1001     };
1002
1003   }
1004
1005 ////////////////////////////////////////////////////////////////////////////////
1006
1007   public static class RSSProducerNodeBuilder extends AbstractProducerNodeBuilder {
1008     private final static String   RSS_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1009     private final static String   RSS_URL_ATTRIBUTE = URL_ATTRIBUTE;
1010     private final static String   RSS_ENCODING_ATTRIBUTE = "encoding";
1011     private final static String   RSS_VERSION_ATTRIBUTE = "version";
1012
1013     private final static String[] RSS_REQUIRED_ATTRIBUTES = { RSS_KEY_ATTRIBUTE, RSS_URL_ATTRIBUTE };
1014     private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE, RSS_ENCODING_ATTRIBUTE };
1015     private final static String[] RSS_SUBNODES = {  };
1016
1017     private String key;
1018     private String url;
1019     private String version;
1020     private String encoding;
1021
1022     public RSSProducerNodeBuilder() {
1023       super(RSS_SUBNODES);
1024     }
1025
1026     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1027       XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
1028
1029       key = (String) anAttributes.get( RSS_KEY_ATTRIBUTE );
1030       url = (String) anAttributes.get( RSS_URL_ATTRIBUTE );
1031       version = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
1032       encoding = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_ENCODING_ATTRIBUTE, null);
1033     };
1034
1035     public ProducerNode constructNode() {
1036       return new RSSProducerNode(key, url, version, encoding);
1037     };
1038   }
1039
1040 ////////////////////////////////////////////////////////////////////////////////
1041
1042   public static class RDFAggregatorProducerNodeBuilder extends AbstractProducerNodeBuilder {
1043     private final static String   RDF_AGGREGATOR_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1044     private final static String   RDF_AGGREGATOR_SOURCE_ATTRIBUTE = "source";
1045     private final static String   RDF_AGGREGATOR_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
1046     private final static String   RDF_AGGREGATOR_FILTER_ATTRIBUTE = "filter";
1047
1048     private final static String[] RDF_AGGREGATOR_REQUIRED_ATTRIBUTES = { RDF_AGGREGATOR_KEY_ATTRIBUTE, RDF_AGGREGATOR_SOURCE_ATTRIBUTE };
1049     private final static String[] RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES = { RDF_AGGREGATOR_ORDER_ATTRIBUTE, RDF_AGGREGATOR_FILTER_ATTRIBUTE };
1050     private final static String[] RDF_AGGREGATOR_SUBNODES = {  };
1051
1052     private String key;
1053     private String source;
1054     private String order;
1055     private String filter;
1056
1057     public RDFAggregatorProducerNodeBuilder() {
1058       super(RDF_AGGREGATOR_SUBNODES);
1059     }
1060
1061     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1062       XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
1063
1064       key = (String) anAttributes.get( RDF_AGGREGATOR_KEY_ATTRIBUTE );
1065       source = (String) anAttributes.get( RDF_AGGREGATOR_SOURCE_ATTRIBUTE );
1066       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_SOURCE_ATTRIBUTE, "");
1067       filter = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_FILTER_ATTRIBUTE, "");
1068     };
1069
1070     public ProducerNode constructNode() {
1071       return new RDFAggregatorProducerNode(key, source, order, filter);
1072     };
1073   }
1074
1075 ////////////////////////////////////////////////////////////////////////////////
1076
1077   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
1078     private String parameterName;
1079     private String scriptedNodeName;
1080
1081     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
1082       parameterName = aParameterName;
1083       scriptedNodeName = aScriptedNodeName;
1084     }
1085
1086     public void setSubNode(String aName, ProducerNode aNode) {
1087     };
1088
1089     public Set getAvailableSubNodes() {
1090       return new HashSet();
1091     };
1092
1093     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
1094       if (!anAttributes.isEmpty())
1095         throw new ProducerConfigExc("No parameters allowed here");
1096     };
1097
1098     public ProducerNode constructNode() {
1099       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
1100     };
1101   }
1102
1103 ////////////////////////////////////////////////////////////////////////////////
1104
1105   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
1106     private ScriptedProducerNodeDefinition definition;
1107     private Map nodeParameterValues;
1108     private Map integerParameterValues;
1109     private Map stringParameterValues;
1110
1111     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
1112       definition = aDefinition;
1113
1114       stringParameterValues = new HashMap();
1115       stringParameterValues.putAll(definition.getStringParameters());
1116
1117       integerParameterValues = new HashMap();
1118       integerParameterValues.putAll(definition.getIntegerParameters());
1119
1120       nodeParameterValues = new HashMap();
1121     }
1122
1123     public void setSubNode(String aName, ProducerNode aNode) {
1124       nodeParameterValues.put(aName, aNode);
1125     };
1126
1127     public Set getAvailableSubNodes() {
1128       return definition.getNodeParameters();
1129     };
1130
1131     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1132       XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
1133
1134       Iterator i = anAttributes.entrySet().iterator();
1135       while (i.hasNext()) {
1136         Map.Entry entry = (Map.Entry) i.next();
1137
1138         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
1139           integerParameterValues.put(entry.getKey(), entry.getValue());
1140         else
1141           stringParameterValues.put(entry.getKey(), entry.getValue());
1142       }
1143     };
1144
1145     public ProducerNode constructNode() {
1146       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
1147     };
1148
1149     public static class factory implements ProducerNodeBuilderFactory {
1150       private ScriptedProducerNodeDefinition definition;
1151
1152       public factory(ScriptedProducerNodeDefinition aDefinition) {
1153         definition = aDefinition;
1154       }
1155
1156       public ProducerNodeBuilder makeBuilder() {
1157         return new ScriptedProducerNodeBuilder(definition);
1158       }
1159     }
1160   }
1161 }