cleanup / abuse system fix / prepping for a release
[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        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                         return new ListEnumeratingProducerNode(key, list, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
263     }
264
265     public static class factory implements ProducerNodeBuilderFactory {
266       private EntityAdapterModel model;
267
268       public factory(EntityAdapterModel aModel) {
269         model = aModel;
270       }
271
272       public ProducerNodeBuilder makeBuilder() {
273         return new EnumeratingProducerNodeBuilder(model);
274       }
275     }
276   }
277
278 ////////////////////////////////////////////////////////////////////////////////
279
280   public static class UpdateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
281     private final static String   UPDATE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
282     private final static String   UPDATE_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
283     private final static String[] UPDATE_SUBNODES = {};
284
285     private String key;
286     private String definition;
287     private Map fieldValues;
288
289     private EntityAdapterModel model;
290
291     public UpdateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
292       super(UPDATE_SUBNODES);
293
294       model = aModel;
295       fieldValues = new HashMap();
296     }
297
298     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
299       key = (String) anAttributes.get(UPDATE_KEY_ATTRIBUTE);
300
301       if (key == null)
302         throw new XMLParserExc("missing required attribute '" + UPDATE_KEY_ATTRIBUTE + "'" );
303       definition = (String) anAttributes.get(UPDATE_DEFINITION_ATTRIBUTE);
304
305       fieldValues.putAll(anAttributes);
306       fieldValues.remove(UPDATE_KEY_ATTRIBUTE);
307       fieldValues.remove(UPDATE_DEFINITION_ATTRIBUTE);
308     }
309     public ProducerNode constructNode() {
310       return new EntityModifyingProducerNode(model, false, definition, key, fieldValues);
311     }
312
313     public static class factory implements ProducerNodeBuilderFactory {
314       private EntityAdapterModel model;
315
316       public factory(EntityAdapterModel aModel) {
317         model = aModel;
318       }
319
320       public ProducerNodeBuilder makeBuilder() {
321         return new UpdateEntityProducerNodeBuilder(model);
322       }
323     }
324   }
325
326 ////////////////////////////////////////////////////////////////////////////////
327
328   public static class CreateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
329     private final static String   CREATEENTITY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
330     private final static String   CREATEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
331     private final static String[] CREATEENTITY_SUBNODES = {};
332
333     private String key;
334     private String definition;
335     private Map fieldValues;
336
337     private EntityAdapterModel model;
338
339     public CreateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
340       super(CREATEENTITY_SUBNODES);
341
342       model = aModel;
343       fieldValues = new HashMap();
344     }
345
346     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
347       key = (String) anAttributes.get(CREATEENTITY_KEY_ATTRIBUTE);
348       definition = (String) anAttributes.get(CREATEENTITY_DEFINITION_ATTRIBUTE);
349
350       if (key == null)
351         throw new XMLParserExc("missing required attribute '" + CREATEENTITY_KEY_ATTRIBUTE + "'" );
352       if (definition == null)
353         throw new XMLParserExc("missing required attribute '" + CREATEENTITY_DEFINITION_ATTRIBUTE + "'" );
354
355       fieldValues.putAll(anAttributes);
356       fieldValues.remove(CREATEENTITY_KEY_ATTRIBUTE);
357       fieldValues.remove(CREATEENTITY_DEFINITION_ATTRIBUTE);
358     }
359
360     public ProducerNode constructNode() {
361       return new EntityModifyingProducerNode(model, true, definition, key, fieldValues);
362     }
363
364     public static class factory implements ProducerNodeBuilderFactory {
365       private EntityAdapterModel model;
366
367       public factory(EntityAdapterModel aModel) {
368         model = aModel;
369       }
370
371       public ProducerNodeBuilder makeBuilder() {
372         return new CreateEntityProducerNodeBuilder(model);
373       }
374     }
375   }
376
377 ////////////////////////////////////////////////////////////////////////////////
378
379   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
380     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
381     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
382     private final static String   LOOP_DEFAULT_SUBNODE = "default";
383     private final static String[] LOOP_REQUIRED_ATTRIBUTES = { LOOP_CONDITION_ATTRIBUTE };
384     private final static String[] LOOP_OPTIONAL_ATTRIBUTES = { LOOP_LIMIT_ATTRIBUTE };
385     private final static String[] LOOP_SUBNODES = {LOOP_DEFAULT_SUBNODE};
386
387     private String condition;
388     private String limit;
389
390     public LoopProducerNodeBuilder() {
391       super(LOOP_SUBNODES);
392     }
393
394     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
395       XMLReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
396
397       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
398       limit = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
399     }
400
401     public ProducerNode constructNode() {
402       return new LoopProducerNode(condition, limit, getSubNode( LOOP_DEFAULT_SUBNODE ));
403     }
404   }
405
406 ////////////////////////////////////////////////////////////////////////////////
407
408   public static class ListProducerNodeBuilder extends AbstractProducerNodeBuilder {
409     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
410     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
411     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
412     private final static String   LIST_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
413     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
414     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
415     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
416     private final static String[] LIST_REQUIRED_ATTRIBUTES = { LIST_KEY_ATTRIBUTE, LIST_DEFINITION_ATTRIBUTE };
417     private final static String[] LIST_OPTIONAL_ATTRIBUTES = { LIST_SELECTION_ATTRIBUTE, LIST_ORDER_ATTRIBUTE, LIST_SKIP_ATTRIBUTE, LIST_LIMIT_ATTRIBUTE,LIST_EXTRATABLES_ATTRIBUTE};
418     private final static String[] LIST_SUBNODES = {};
419
420     private String key;
421     private String definition;
422     private String mainTablePrefix;
423     private String extraTables;
424     private String selection;
425     private String order;
426     private String limit;
427     private String skip;
428     private EntityAdapterModel model;
429
430     public ListProducerNodeBuilder(EntityAdapterModel aModel) {
431       super(LIST_SUBNODES);
432
433       model = aModel;
434     }
435
436     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
437       XMLReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
438
439       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
440       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
441       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
442       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
443       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
444       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
445       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_EXTRATABLES_ATTRIBUTE,"");
446       List parts = StringRoutines.splitString(definition.trim()," ");
447       if (parts.size()>0) definition=(String)parts.get(0);
448       if (parts.size()>1) mainTablePrefix=(String)parts.get(1);
449
450     }
451
452     public ProducerNode constructNode() {
453       return new EntityListProducerNode(key, model, mainTablePrefix, extraTables, definition, selection, order, limit, skip, null );
454     }
455
456     public static class factory implements ProducerNodeBuilderFactory {
457       private EntityAdapterModel model;
458
459       public factory(EntityAdapterModel aModel) {
460         model = aModel;
461       }
462
463       public ProducerNodeBuilder makeBuilder() {
464         return new ListProducerNodeBuilder(model);
465       }
466     }
467   }
468
469 ////////////////////////////////////////////////////////////////////////////////
470
471   public static class DeleteEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
472     private final static String   DELETEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
473     private final static String   DELETEENTITY_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
474     private final static String[] DELETEENTITY_REQUIRED_ATTRIBUTES = { DELETEENTITY_SELECTION_ATTRIBUTE, DELETEENTITY_DEFINITION_ATTRIBUTE };
475     private final static String[] DELETEENTITY_OPTIONAL_ATTRIBUTES = { };
476     private final static String[] DELETEENTITY_SUBNODES = {};
477
478     private String definition;
479     private String selection;
480
481     private EntityAdapterModel model;
482
483     public DeleteEntityProducerNodeBuilder(EntityAdapterModel aModel) {
484       super(DELETEENTITY_SUBNODES);
485
486       model = aModel;
487     }
488
489     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
490       XMLReaderTool.checkAttributes(anAttributes, DELETEENTITY_REQUIRED_ATTRIBUTES, DELETEENTITY_OPTIONAL_ATTRIBUTES);
491
492       definition = (String) anAttributes.get(DELETEENTITY_DEFINITION_ATTRIBUTE);
493       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, DELETEENTITY_SELECTION_ATTRIBUTE, "");
494     }
495
496     public ProducerNode constructNode() {
497       return new EntityDeletingProducerNode(model, definition, selection);
498     }
499
500     public static class factory implements ProducerNodeBuilderFactory {
501       private EntityAdapterModel model;
502
503       public factory(EntityAdapterModel aModel) {
504         model = aModel;
505       }
506
507       public ProducerNodeBuilder makeBuilder() {
508         return new DeleteEntityProducerNodeBuilder(model);
509       }
510     }
511   }
512
513 ////////////////////////////////////////////////////////////////////////////////
514
515   public static class LoggingProducerNodeBuilder extends AbstractProducerNodeBuilder {
516     private final static String   LOG_MESSAGE_ATTRIBUTE = "message";
517     private final static String   LOG_TYPE_ATTRIBUTE = "type";
518     private final static String[] LOG_REQUIRED_ATTRIBUTES = { LOG_MESSAGE_ATTRIBUTE };
519     private final static String[] LOG_OPTIONAL_ATTRIBUTES = { LOG_TYPE_ATTRIBUTE };
520     private final static String[] LOG_SUBNODES = {};
521
522     private String message;
523     private int type = LoggerWrapper.INFO_MESSAGE;
524
525     public LoggingProducerNodeBuilder() {
526       super(LOG_SUBNODES);
527     }
528
529     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
530       String typeString;
531
532       XMLReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
533
534       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
535       if (anAttributes.containsKey(LOG_TYPE_ATTRIBUTE)) {
536         typeString = ((String) anAttributes.get( LOG_TYPE_ATTRIBUTE ));
537
538         if (typeString.toLowerCase().equals("debug"))
539           type = LoggerWrapper.DEBUG_MESSAGE;
540         else if (typeString.toLowerCase().equals("info"))
541           type = LoggerWrapper.INFO_MESSAGE;
542         else if (typeString.toLowerCase().equals("error"))
543           type = LoggerWrapper.ERROR_MESSAGE;
544         else if (typeString.toLowerCase().equals("warning"))
545           type = LoggerWrapper.WARN_MESSAGE;
546         else if (typeString.toLowerCase().equals("fatal"))
547           type = LoggerWrapper.FATAL_MESSAGE;
548         else
549           throw new ProducerConfigExc("unknown log type: " + typeString + " (allowed are debug, info, warning, error, fatal)");
550       }
551       else
552         type = LoggerWrapper.INFO_MESSAGE;
553     }
554
555     public ProducerNode constructNode() {
556       return new LoggingProducerNode(message, type);
557     }
558   }
559
560 ////////////////////////////////////////////////////////////////////////////////
561
562   public static class FreeQueryProducerNodeBuilder extends AbstractProducerNodeBuilder {
563     private final static String   FREEQUERY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
564     private final static String   FREEQUERY_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
565     private final static String   FREEQUERY_QUERY_ATTRIBUTE = "query";
566     private final static String   FREEQUERY_TYPE_ATTRIBUTE = "type";
567     private final static String[] FREEQUERY_REQUIRED_ATTRIBUTES = { KEY_ATTRIBUTE, FREEQUERY_QUERY_ATTRIBUTE };
568     private final static String[] FREEQUERY_OPTIONAL_ATTRIBUTES = { LIMIT_ATTRIBUTE, FREEQUERY_TYPE_ATTRIBUTE };
569     private final static String[] FREEQUERY_SUBNODES = {};
570
571     private String key;
572     private String query;
573     private String limit;
574     private int type;
575
576     public FreeQueryProducerNodeBuilder() {
577       super(FREEQUERY_SUBNODES);
578     }
579
580     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
581       String typeString;
582
583       XMLReaderTool.checkAttributes(anAttributes, FREEQUERY_REQUIRED_ATTRIBUTES, FREEQUERY_OPTIONAL_ATTRIBUTES);
584
585       key = (String) anAttributes.get(FREEQUERY_KEY_ATTRIBUTE);
586       query = (String) anAttributes.get(FREEQUERY_QUERY_ATTRIBUTE);
587       limit = (String) anAttributes.get(FREEQUERY_LIMIT_ATTRIBUTE);
588
589       if (anAttributes.containsKey(FREEQUERY_TYPE_ATTRIBUTE)) {
590         typeString = ((String) anAttributes.get( FREEQUERY_TYPE_ATTRIBUTE ));
591
592         if (typeString.toLowerCase().equals("set"))
593           type = FreeQueryProducerNode.QUERY_TYPE_SET;
594         else if (typeString.toLowerCase().equals("row"))
595           type = FreeQueryProducerNode.QUERY_TYPE_ROW;
596         else if (typeString.toLowerCase().equals("value"))
597           type = FreeQueryProducerNode.QUERY_TYPE_VALUE;
598         else if (typeString.toLowerCase().equals("update"))
599           type = FreeQueryProducerNode.QUERY_TYPE_UPDATE;
600         else
601           throw new ProducerConfigExc("unknown query type: " + typeString + " (allowed are set, row and value)");
602       }
603       else
604         type = FreeQueryProducerNode.QUERY_TYPE_SET;
605     }
606
607     public ProducerNode constructNode() {
608       return new FreeQueryProducerNode(key, query, limit, type);
609     }
610   }
611 ////////////////////////////////////////////////////////////////////////////////
612
613   public static class ExternalDbProducerNodeBuilder extends AbstractProducerNodeBuilder {
614     private final static String   EXTDB_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
615     private final static String   EXTDB_DRIVER_ATTRIBUTE = "driver";
616     private final static String   EXTDB_HOST_ATTRIBUTE = "host";
617     private final static String   EXTDB_PORT_ATTRIBUTE = "port";
618     private final static String   EXTDB_DATABASE_ATTRIBUTE = "database";
619     private final static String   EXTDB_USERNAME_ATTRIBUTE = "username";
620     private final static String   EXTDB_PASSWORD_ATTRIBUTE = "password";
621     private final static String   EXTDB_QUERY_ATTRIBUTE = "query";
622     private final static String   EXTDB_DEFAULT_SUBNODE = "default";
623     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 };
624     private final static String[] EXTDB_OPTIONAL_ATTRIBUTES = { };
625     private final static String[] EXTDB_SUBNODES = {EXTDB_DEFAULT_SUBNODE};
626
627     private String key;
628     private String driver;
629     private String host;
630     private String port;
631     private String database;
632     private String username;
633     private String password;
634     private String query;   
635
636
637     public ExternalDbProducerNodeBuilder() {
638       super(EXTDB_SUBNODES);
639     }
640
641     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
642       XMLReaderTool.checkAttributes(anAttributes, EXTDB_REQUIRED_ATTRIBUTES, EXTDB_OPTIONAL_ATTRIBUTES);
643
644       key = (String) anAttributes.get(EXTDB_KEY_ATTRIBUTE);
645       driver = (String) anAttributes.get(EXTDB_DRIVER_ATTRIBUTE);
646       host = (String) anAttributes.get(EXTDB_HOST_ATTRIBUTE);
647       port = (String) anAttributes.get(EXTDB_PORT_ATTRIBUTE);
648       database = (String) anAttributes.get(EXTDB_DATABASE_ATTRIBUTE);
649       username = (String) anAttributes.get(EXTDB_USERNAME_ATTRIBUTE);
650       password = (String) anAttributes.get(EXTDB_PASSWORD_ATTRIBUTE);
651       query = (String) anAttributes.get(EXTDB_QUERY_ATTRIBUTE);
652     }
653
654     public ProducerNode constructNode() {
655       return new ExternalDbProducerNode(key, driver, host, port, database, username, password, query,  getSubNode(EXTDB_DEFAULT_SUBNODE));
656     }
657   }
658
659 ////////////////////////////////////////////////////////////////////////////////
660
661   public static class BundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
662     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
663     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
664     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
665     private final static String[] RESOURCEBUNDLE_REQUIRED_ATTRIBUTES = { RESOURCEBUNDLE_KEY_ATTRIBUTE, RESOURCEBUNDLE_BUNDLE_ATTRIBUTE };
666     private final static String[] RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES = { RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE};
667     private final static String[] RESOURCEBUNDLE_SUBNODES = {};
668
669     private String key;
670     private String bundle;
671     private String language;
672
673     public BundleProducerNodeBuilder() {
674       super(RESOURCEBUNDLE_SUBNODES);
675     }
676
677     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
678       XMLReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
679
680       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
681       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
682       language = (String) anAttributes.get(RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE);
683     }
684
685     public ProducerNode constructNode() {
686       return new BundleProducerNode(key, bundle, language);
687     }
688   }
689
690 ////////////////////////////////////////////////////////////////////////////////
691
692   public static class FileDateSettingProducerNodeBuilder extends AbstractProducerNodeBuilder {
693     private final static String   FILEDATESETTING_FILE_ATTRIBUTE = "filename";
694     private final static String   FILEDATESETTING_DATE_ATTRIBUTE = "date";
695     private final static String[] FILEDATESETTING_REQUIRED_ATTRIBUTES = { FILEDATESETTING_FILE_ATTRIBUTE, FILEDATESETTING_DATE_ATTRIBUTE };
696     private final static String[] FILEDATESETTING_OPTIONAL_ATTRIBUTES = { };
697     private final static String[] FILEDATESETTING_SUBNODES = {};
698
699     private String fileNameKey;
700     private String dateKey;
701
702     public FileDateSettingProducerNodeBuilder() {
703       super(FILEDATESETTING_SUBNODES);
704     }
705
706     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
707       XMLReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
708
709       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
710       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
711     }
712
713     public ProducerNode constructNode() {
714       return new FileDateSettingProducerNode(fileNameKey, dateKey);
715     }
716   }
717
718 ////////////////////////////////////////////////////////////////////////////////
719
720   public static class FileDeletingProducerNodeBuilder extends AbstractProducerNodeBuilder {
721     private final static String   FILEDELETING_FILE_ATTRIBUTE = "filename";
722     private final static String[] FILEDELETING_REQUIRED_ATTRIBUTES = { FILEDELETING_FILE_ATTRIBUTE };
723     private final static String[] FILEDELETING_OPTIONAL_ATTRIBUTES = { };
724     private final static String[] FILEDELETING_SUBNODES = { };
725
726     private String fileNameKey;
727
728     public FileDeletingProducerNodeBuilder() {
729       super(FILEDELETING_SUBNODES);
730     }
731
732     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
733       XMLReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
734
735       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
736     }
737
738     public ProducerNode constructNode() {
739       return new FileDeletingProducerNode(fileNameKey);
740     }
741   }
742
743 ////////////////////////////////////////////////////////////////////////////////
744
745   public static class ExecuteProgramProducerNodeBuilder extends AbstractProducerNodeBuilder {
746     private final static String   EXECUTEPROGRAM_COMMAND_ATTRIBUTE = "command";
747     private final static String   EXECUTEPROGRAM_MAXTIME_ATTRIBUTE = "maxduration";
748     private final static String   EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE = "resultvar";
749     private final static String   EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE = "returnvaluevar";
750     private final static String[] EXECUTEPROGRAM_REQUIRED_ATTRIBUTES = { EXECUTEPROGRAM_COMMAND_ATTRIBUTE };
751     private final static String[] EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES = { EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE };
752     private final static String[] EXECUTEPROGRAM_SUBNODES = {};
753
754     private String command;
755     private String time;
756     private String resultvar;
757     private String returnValueVar;
758
759     public ExecuteProgramProducerNodeBuilder() {
760       super(EXECUTEPROGRAM_SUBNODES);
761     }
762
763     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
764       XMLReaderTool.checkAttributes(anAttributes, EXECUTEPROGRAM_REQUIRED_ATTRIBUTES, EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES);
765
766       command = (String) anAttributes.get(EXECUTEPROGRAM_COMMAND_ATTRIBUTE);
767       time = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, null);
768       resultvar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE, null);
769       returnValueVar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE, null);
770     }
771
772     public ProducerNode constructNode() {
773       return new
774           ExecuteProgramProducerNode(command, time, resultvar, returnValueVar);
775     }
776   }
777
778 ////////////////////////////////////////////////////////////////////////////////
779
780   private final static String   DIRCOPY_SOURCE_ATTRIBUTE = "source";
781   private final static String   DIRCOPY_DESTINATION_ATTRIBUTE = "destination";
782   private final static String[] DIRCOPY_REQUIRED_ATTRIBUTES = { DIRCOPY_SOURCE_ATTRIBUTE, DIRCOPY_DESTINATION_ATTRIBUTE };
783   private final static String[] DIRCOPY_OPTIONAL_ATTRIBUTES = {};
784   private final static String[] DIRCOPY_SUBNODES = {};
785
786   public static class DirCopyProducerNodeBuilder extends AbstractProducerNodeBuilder {
787     private String source;
788     private String destination;
789     private File sourceBasePath;
790     private File destinationBasePath;
791
792     public DirCopyProducerNodeBuilder(File aSourceBasePath, File aDestinationBasePath) {
793       super(DIRCOPY_SUBNODES);
794
795       sourceBasePath = aSourceBasePath;
796       destinationBasePath = aDestinationBasePath;
797     }
798
799     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
800       XMLReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
801
802       source = (String) anAttributes.get(DIRCOPY_SOURCE_ATTRIBUTE);
803       destination = (String) anAttributes.get(DIRCOPY_DESTINATION_ATTRIBUTE);
804     }
805
806     public ProducerNode constructNode() {
807       return new DirCopyingProducerNode(sourceBasePath, destinationBasePath, source, destination);
808     }
809
810     public static class factory implements ProducerNodeBuilderFactory {
811       private File sourceBasePath;
812       private File destinationBasePath;
813
814       public factory(File aSourceBasePath, File aDestinationBasePath) {
815         sourceBasePath = aSourceBasePath;
816         destinationBasePath = aDestinationBasePath;
817       }
818
819       public ProducerNodeBuilder makeBuilder() {
820         return new DirCopyProducerNodeBuilder(sourceBasePath, destinationBasePath);
821       }
822     }
823   }
824
825 ////////////////////////////////////////////////////////////////////////////////
826
827   public static class GeneratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
828     private final static String   GENERATION_GENERATOR_ATTRIBUTE = "generator";
829     private final static String   GENERATION_DESTINATION_ATTRIBUTE = "destination";
830     private final static String   GENERATION_PARAMETERS_ATTRIBUTE = "parameters";
831     private final static String[] GENERATION_REQUIRED_ATTRIBUTES = { GENERATION_GENERATOR_ATTRIBUTE, GENERATION_DESTINATION_ATTRIBUTE };
832     private final static String[] GENERATION_OPTIONAL_ATTRIBUTES = { GENERATION_PARAMETERS_ATTRIBUTE};
833     private final static String[] GENERATION_SUBNODES = {};
834
835     private String generator;
836     private String destination;
837     private String parameters;
838     private Generator.Library generatorLibrary;
839     private WriterEngine writerEngine;
840
841     public GeneratingProducerNodeBuilder(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
842       super(GENERATION_SUBNODES);
843
844       writerEngine = aWriterEngine;
845       generatorLibrary = aGeneratorLibrary;
846     }
847
848     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
849       XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
850
851       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
852       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
853       parameters = XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
854     }
855
856     public ProducerNode constructNode() {
857       return new GeneratingProducerNode(generatorLibrary, writerEngine, generator, destination, parameters);
858     }
859
860     public static class factory implements ProducerNodeBuilderFactory {
861       private Generator.Library generatorLibrary;
862       private WriterEngine writerEngine;
863
864       public factory(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
865         writerEngine = aWriterEngine;
866         generatorLibrary = aGeneratorLibrary;
867       }
868
869       public ProducerNodeBuilder makeBuilder() {
870         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine);
871       }
872     }
873   }
874
875 ////////////////////////////////////////////////////////////////////////////////
876
877   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
878
879     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
880     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
881     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
882     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
883     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
884
885     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
886     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
887     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
888
889     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
890     private final static String   BATCHER_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
891
892     private final static String   BATCHER_BATCH_SUBNODE = "batches";
893     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
894     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
895     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 };
896     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
897
898     private EntityAdapterModel model;
899     private String batchDataKey;
900     private String batchInfoKey;
901     private String mainTablePrefix;
902     private String extraTables;
903     private String definition;
904     private String selection;
905     private String order;
906     private String batchSize;
907     private String minBatchSize;
908     private String skip;
909     private String process;
910
911     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
912       super(BATCHER_SUBNODES);
913
914       model = aModel;
915     }
916
917     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
918       XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
919
920       batchDataKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
921       batchInfoKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
922       definition = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
923       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
924       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
925
926       batchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
927       minBatchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
928       skip = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
929       process = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
930
931       extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_EXTRATABLES_ATTRIBUTE, "");
932
933       List parts = StringRoutines.splitString(definition.trim(), " ");
934       if (parts.size()>0) definition = (String) parts.get(0);
935       if (parts.size()>1) mainTablePrefix = (String) parts.get(1);
936     }
937
938     public ProducerNode constructNode() {
939       return new EntityBatchingProducerNode(
940           batchDataKey,
941           batchInfoKey,
942           model,
943           mainTablePrefix,
944           extraTables,
945           definition,
946           selection,
947           order,
948           batchSize,
949           minBatchSize,
950           skip,
951           process,
952           getSubNode( BATCHER_BATCH_SUBNODE ),
953           getSubNode( BATCHER_BATCHLIST_SUBNODE )
954       );
955     }
956
957     public static class factory implements ProducerNodeBuilderFactory {
958       private EntityAdapterModel model;
959
960       public factory(EntityAdapterModel aModel) {
961         model = aModel;
962       }
963
964       public ProducerNodeBuilder makeBuilder() {
965         return new BatchingProducerNodeBuilder(model);
966       }
967     }
968   }
969
970 ////////////////////////////////////////////////////////////////////////////////
971
972   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
973     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
974
975     private final static String   IF_TRUE_SUBNODE = "then";
976     private final static String   IF_FALSE_SUBNODE = "else";
977     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
978     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
979     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
980
981     private String condition;
982
983     public ConditionalProducerNodeBuilder() {
984       super(IF_SUBNODES);
985     }
986
987     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
988       XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
989
990       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
991     }
992
993     public ProducerNode constructNode() {
994       return new ConditionalProducerNode(
995           condition,
996           getSubNode( IF_TRUE_SUBNODE ),
997           getSubNode( IF_FALSE_SUBNODE )
998       );
999     }
1000
1001   }
1002
1003 ////////////////////////////////////////////////////////////////////////////////
1004
1005   public static class RSSProducerNodeBuilder extends AbstractProducerNodeBuilder {
1006     private final static String   RSS_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1007     private final static String   RSS_URL_ATTRIBUTE = URL_ATTRIBUTE;
1008     private final static String   RSS_ENCODING_ATTRIBUTE = "encoding";
1009     private final static String   RSS_VERSION_ATTRIBUTE = "version";
1010
1011     private final static String[] RSS_REQUIRED_ATTRIBUTES = { RSS_KEY_ATTRIBUTE, RSS_URL_ATTRIBUTE };
1012     private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE, RSS_ENCODING_ATTRIBUTE };
1013     private final static String[] RSS_SUBNODES = {  };
1014
1015     private String key;
1016     private String url;
1017     private String version;
1018     private String encoding;
1019
1020     public RSSProducerNodeBuilder() {
1021       super(RSS_SUBNODES);
1022     }
1023
1024     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1025       XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
1026
1027       key = (String) anAttributes.get( RSS_KEY_ATTRIBUTE );
1028       url = (String) anAttributes.get( RSS_URL_ATTRIBUTE );
1029       version = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
1030       encoding = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_ENCODING_ATTRIBUTE, null);
1031     }
1032
1033     public ProducerNode constructNode() {
1034       return new RSSProducerNode(key, url, version, encoding);
1035     }
1036   }
1037
1038 ////////////////////////////////////////////////////////////////////////////////
1039
1040   public static class RDFAggregatorProducerNodeBuilder extends AbstractProducerNodeBuilder {
1041     private final static String   RDF_AGGREGATOR_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
1042     private final static String   RDF_AGGREGATOR_SOURCE_ATTRIBUTE = "source";
1043
1044     private final static String[] RDF_AGGREGATOR_REQUIRED_ATTRIBUTES = { RDF_AGGREGATOR_KEY_ATTRIBUTE, RDF_AGGREGATOR_SOURCE_ATTRIBUTE };
1045     private final static String[] RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES = {  };
1046     private final static String[] RDF_AGGREGATOR_SUBNODES = {  };
1047
1048     private String key;
1049     private String source;
1050     private String order;
1051     private String filter;
1052
1053     public RDFAggregatorProducerNodeBuilder() {
1054       super(RDF_AGGREGATOR_SUBNODES);
1055     }
1056
1057     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1058       XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
1059
1060       key = (String) anAttributes.get( RDF_AGGREGATOR_KEY_ATTRIBUTE );
1061       source = (String) anAttributes.get( RDF_AGGREGATOR_SOURCE_ATTRIBUTE );
1062     }
1063
1064     public ProducerNode constructNode() {
1065       return new RDFAggregatorProducerNode(key, source);
1066     }
1067   }
1068
1069 ////////////////////////////////////////////////////////////////////////////////
1070
1071   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
1072     private String parameterName;
1073     private String scriptedNodeName;
1074
1075     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
1076       parameterName = aParameterName;
1077       scriptedNodeName = aScriptedNodeName;
1078     }
1079
1080     public void setSubNode(String aName, ProducerNode aNode) {
1081     }
1082
1083     public Set getAvailableSubNodes() {
1084       return new HashSet();
1085     }
1086
1087     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
1088       if (!anAttributes.isEmpty())
1089         throw new ProducerConfigExc("No parameters allowed here");
1090     }
1091
1092     public ProducerNode constructNode() {
1093       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
1094     }
1095   }
1096
1097 ////////////////////////////////////////////////////////////////////////////////
1098
1099   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
1100     private ScriptedProducerNodeDefinition definition;
1101     private Map nodeParameterValues;
1102     private Map integerParameterValues;
1103     private Map stringParameterValues;
1104
1105     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
1106       definition = aDefinition;
1107
1108       stringParameterValues = new HashMap();
1109       stringParameterValues.putAll(definition.getStringParameters());
1110
1111       integerParameterValues = new HashMap();
1112       integerParameterValues.putAll(definition.getIntegerParameters());
1113
1114       nodeParameterValues = new HashMap();
1115     }
1116
1117     public void setSubNode(String aName, ProducerNode aNode) {
1118       nodeParameterValues.put(aName, aNode);
1119     }
1120
1121     public Set getAvailableSubNodes() {
1122       return definition.getNodeParameters();
1123     }
1124
1125     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
1126       XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
1127
1128       Iterator i = anAttributes.entrySet().iterator();
1129       while (i.hasNext()) {
1130         Map.Entry entry = (Map.Entry) i.next();
1131
1132         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
1133           integerParameterValues.put(entry.getKey(), entry.getValue());
1134         else
1135           stringParameterValues.put(entry.getKey(), entry.getValue());
1136       }
1137     }
1138
1139     public ProducerNode constructNode() {
1140       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
1141     }
1142
1143     public static class factory implements ProducerNodeBuilderFactory {
1144       private ScriptedProducerNodeDefinition definition;
1145
1146       public factory(ScriptedProducerNodeDefinition aDefinition) {
1147         definition = aDefinition;
1148       }
1149
1150       public ProducerNodeBuilder makeBuilder() {
1151         return new ScriptedProducerNodeBuilder(definition);
1152       }
1153     }
1154   }
1155 }