3c28b999d8f4a770c23a9988c629ea71274ea7fc
[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 the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mir.producer.reader;
33
34 import java.util.*;
35 import mir.generator.*;
36 import mir.producer.*;
37 import mir.entity.adapter.*;
38 import mir.util.*;
39
40 public class DefaultProducerNodeBuilders {
41
42   public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary,
43        EntityAdapterModel aModel, Generator.GeneratorLibrary aGeneratorLibrary,
44        WriterEngine aWriterEngine, String aSourceBasePath, String aDestinationBasePath) {
45
46     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
47     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
48     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
49     aBuilderLibrary.registerBuilder("Execute", ScriptCallingProducerNodeBuilder.class);
50     aBuilderLibrary.registerBuilder("Resource", ResourceBundleProducerNodeBuilder.class);
51     aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory( aSourceBasePath, aDestinationBasePath));
52
53     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
54     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
55     aBuilderLibrary.registerBuilder("If", ConditionalProducerNodeBuilder.class);
56     aBuilderLibrary.registerBuilder("While", LoopProducerNodeBuilder.class);
57
58     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
59     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
60     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
61
62     aBuilderLibrary.registerFactory("Generate",
63         new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
64   }
65
66   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
67     private Map attributes;
68     private Map subNodes;
69     private Set availableSubnodes;
70
71     public AbstractProducerNodeBuilder(String anAvailableSubNodes[]) {
72       attributes = new HashMap();
73       subNodes = new HashMap();
74       availableSubnodes = new HashSet(Arrays.asList(anAvailableSubNodes));
75     }
76
77     protected ProducerNode getSubNode(String aName) {
78       return (ProducerNode) subNodes.get(aName);
79     }
80
81     public void setSubNode(String aName, ProducerNode aNode) {
82       subNodes.put(aName, aNode);
83     };
84
85     public Set getAvailableSubNodes() {
86       return availableSubnodes;
87     };
88   }
89
90 ////////////////////////////////////////////////////////////////////////////////
91
92   // general attribute names, specifc builders reference these, to keep attribute
93   //    names consistent
94
95   public final static String   SELECTION_ATTRIBUTE = "selection";
96   public final static String   ORDER_ATTRIBUTE = "order";
97   public final static String   DEFINITION_ATTRIBUTE = "table";
98   public final static String   SKIP_ATTRIBUTE = "skip";
99   public final static String   KEY_ATTRIBUTE = "key";
100   public final static String   LIMIT_ATTRIBUTE = "limit";
101
102 ////////////////////////////////////////////////////////////////////////////////
103
104   private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
105   private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
106   private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
107   private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
108   private final static String[] ASSIGNMENT_SUBNODES = {};
109
110   public static class ExpandedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
111
112     private String key;
113     private String value;
114
115     public ExpandedAssignmentProducerNodeBuilder() {
116       super(ASSIGNMENT_SUBNODES);
117     }
118
119     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
120       ReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
121
122       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
123       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
124     };
125
126     public ProducerNode constructNode() {
127       return new ExpandedAssignmentProducerNode(key, value);
128     };
129   }
130
131 ////////////////////////////////////////////////////////////////////////////////
132
133   public static class EvaluatedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
134
135     private String key;
136     private String value;
137
138     public EvaluatedAssignmentProducerNodeBuilder() {
139       super(ASSIGNMENT_SUBNODES);
140     }
141
142     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
143       ReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
144
145       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
146       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
147     };
148
149     public ProducerNode constructNode() {
150       return new EvaluatedAssignmentProducerNode(key, value);
151     };
152   }
153
154 ////////////////////////////////////////////////////////////////////////////////
155
156   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
157     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
158     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
159     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
160     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
161     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
162     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
163     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
164     private final static String[] ENUMERATION_REQUIRED_ATTRIBUTES = { ENUMERATION_KEY_ATTRIBUTE, ENUMERATION_DEFINITION_ATTRIBUTE };
165     private final static String[] ENUMERATION_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE};
166     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
167
168     private String key;
169     private String definition;
170     private String selection;
171     private String order;
172     private String limit;
173     private String skip;
174     private EntityAdapterModel model;
175
176     public EnumeratingProducerNodeBuilder(EntityAdapterModel aModel) {
177       super(ENUMERATION_SUBNODES);
178
179       model = aModel;
180     }
181
182     public void setAttributes(Map anAttributes) throws ProducerConfigExc  {
183       ReaderTool.checkAttributes(anAttributes, ENUMERATION_REQUIRED_ATTRIBUTES, ENUMERATION_OPTIONAL_ATTRIBUTES);
184
185       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
186       definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
187       selection = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
188       order = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
189       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
190       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
191     };
192
193     public ProducerNode constructNode() {
194       return new EntityEnumeratingProducerNode(key, model, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
195     };
196
197     public static class factory implements ProducerNodeBuilderFactory {
198       private EntityAdapterModel model;
199
200       public factory(EntityAdapterModel aModel) {
201         model = aModel;
202       }
203
204       public ProducerNodeBuilder makeBuilder() {
205         return new EnumeratingProducerNodeBuilder(model);
206       }
207     }
208   }
209
210 ////////////////////////////////////////////////////////////////////////////////
211
212   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
213     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
214     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
215     private final static String   LOOP_DEFAULT_SUBNODE = "default";
216     private final static String[] LOOP_REQUIRED_ATTRIBUTES = { LOOP_CONDITION_ATTRIBUTE };
217     private final static String[] LOOP_OPTIONAL_ATTRIBUTES = { LOOP_LIMIT_ATTRIBUTE };
218     private final static String[] LOOP_SUBNODES = {LOOP_DEFAULT_SUBNODE};
219
220     private String condition;
221     private String limit;
222
223     public LoopProducerNodeBuilder() {
224       super(LOOP_SUBNODES);
225     }
226
227     public void setAttributes(Map anAttributes) throws ProducerConfigExc  {
228       ReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
229
230       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
231       limit = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
232     };
233
234     public ProducerNode constructNode() {
235       return new LoopProducerNode(condition, limit, getSubNode( LOOP_DEFAULT_SUBNODE ));
236     };
237   }
238
239 ////////////////////////////////////////////////////////////////////////////////
240
241   public static class ListProducerNodeBuilder extends AbstractProducerNodeBuilder {
242     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
243     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
244     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
245     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
246     private final static String   LIST_DEFAULT_SUBNODE = "default";
247     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
248     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
249     private final static String[] LIST_REQUIRED_ATTRIBUTES = { LIST_KEY_ATTRIBUTE, LIST_DEFINITION_ATTRIBUTE };
250     private final static String[] LIST_OPTIONAL_ATTRIBUTES = { LIST_SELECTION_ATTRIBUTE, LIST_ORDER_ATTRIBUTE, LIST_SKIP_ATTRIBUTE, LIST_LIMIT_ATTRIBUTE};
251     private final static String[] LIST_SUBNODES = {};
252
253     private String key;
254     private String definition;
255     private String selection;
256     private String order;
257     private String limit;
258     private String skip;
259     private EntityAdapterModel model;
260
261     public ListProducerNodeBuilder(EntityAdapterModel aModel) {
262       super(LIST_SUBNODES);
263
264       model = aModel;
265     }
266
267     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
268       ReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
269
270       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
271       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
272       selection = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
273       order = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
274       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
275       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
276     };
277
278     public ProducerNode constructNode() {
279       return new EntityListProducerNode(key, model, definition, selection, order, limit, skip, null );
280     };
281
282     public static class factory implements ProducerNodeBuilderFactory {
283       private EntityAdapterModel model;
284
285       public factory(EntityAdapterModel aModel) {
286         model = aModel;
287       }
288
289       public ProducerNodeBuilder makeBuilder() {
290         return new ListProducerNodeBuilder(model);
291       }
292     }
293   }
294
295 ////////////////////////////////////////////////////////////////////////////////
296
297   public static class LoggingProducerNodeBuilder extends AbstractProducerNodeBuilder {
298     private final static String   LOG_MESSAGE_ATTRIBUTE = "message";
299     private final static String[] LOG_REQUIRED_ATTRIBUTES = { LOG_MESSAGE_ATTRIBUTE };
300     private final static String[] LOG_OPTIONAL_ATTRIBUTES = {};
301     private final static String[] LOG_SUBNODES = {};
302
303     private String message;
304
305     public LoggingProducerNodeBuilder() {
306       super(LOG_SUBNODES);
307     }
308
309     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
310       ReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
311
312       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
313     };
314
315     public ProducerNode constructNode() {
316       return new LoggingProducerNode(message);
317     };
318   }
319
320 ////////////////////////////////////////////////////////////////////////////////
321
322   public static class ResourceBundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
323     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
324     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
325     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
326     private final static String   RESOURCEBUNDLE_DEFAULT_SUBNODE = "default";
327     private final static String[] RESOURCEBUNDLE_REQUIRED_ATTRIBUTES = { RESOURCEBUNDLE_KEY_ATTRIBUTE, RESOURCEBUNDLE_BUNDLE_ATTRIBUTE };
328     private final static String[] RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES = { RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE};
329     private final static String[] RESOURCEBUNDLE_SUBNODES = {};
330
331     private String key;
332     private String bundle;
333     private String language;
334
335     public ResourceBundleProducerNodeBuilder() {
336       super(RESOURCEBUNDLE_SUBNODES);
337     }
338
339     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
340       ReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
341
342       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
343       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
344       language = (String) anAttributes.get(RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE);
345     };
346
347     public ProducerNode constructNode() {
348       return new ResourceBundleProducerNode(key, bundle, language);
349     };
350   }
351
352 ////////////////////////////////////////////////////////////////////////////////
353
354   public static class FileDateSettingProducerNodeBuilder extends AbstractProducerNodeBuilder {
355     private final static String   FILEDATESETTING_FILE_ATTRIBUTE = "filename";
356     private final static String   FILEDATESETTING_DATE_ATTRIBUTE = "date";
357     private final static String[] FILEDATESETTING_REQUIRED_ATTRIBUTES = { FILEDATESETTING_FILE_ATTRIBUTE, FILEDATESETTING_DATE_ATTRIBUTE };
358     private final static String[] FILEDATESETTING_OPTIONAL_ATTRIBUTES = { };
359     private final static String[] FILEDATESETTING_SUBNODES = {};
360
361     private String fileNameKey;
362     private String dateKey;
363
364     public FileDateSettingProducerNodeBuilder() {
365       super(FILEDATESETTING_SUBNODES);
366     }
367
368     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
369       ReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
370
371       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
372       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
373     };
374
375     public ProducerNode constructNode() {
376       return new FileDateSettingProducerNode(fileNameKey, dateKey);
377     };
378   }
379
380 ////////////////////////////////////////////////////////////////////////////////
381
382   public static class FileDeletingProducerNodeBuilder extends AbstractProducerNodeBuilder {
383     private final static String   FILEDELETING_FILE_ATTRIBUTE = "filename";
384     private final static String[] FILEDELETING_REQUIRED_ATTRIBUTES = { FILEDELETING_FILE_ATTRIBUTE };
385     private final static String[] FILEDELETING_OPTIONAL_ATTRIBUTES = { };
386     private final static String[] FILEDELETING_SUBNODES = { };
387
388     private String fileNameKey;
389
390     public FileDeletingProducerNodeBuilder() {
391       super(FILEDELETING_SUBNODES);
392     }
393
394     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
395       ReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
396
397       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
398     };
399
400     public ProducerNode constructNode() {
401       return new FileDeletingProducerNode(fileNameKey);
402     };
403   }
404
405 ////////////////////////////////////////////////////////////////////////////////
406
407   public static class ScriptCallingProducerNodeBuilder extends AbstractProducerNodeBuilder {
408     private final static String   SCRIPT_COMMAND_ATTRIBUTE = "command";
409     private final static String[] SCRIPT_REQUIRED_ATTRIBUTES = { SCRIPT_COMMAND_ATTRIBUTE };
410     private final static String[] SCRIPT_OPTIONAL_ATTRIBUTES = {};
411     private final static String[] SCRIPT_SUBNODES = {};
412
413     private String command;
414
415     public ScriptCallingProducerNodeBuilder() {
416       super(SCRIPT_SUBNODES);
417     }
418
419     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
420       ReaderTool.checkAttributes(anAttributes, SCRIPT_REQUIRED_ATTRIBUTES, SCRIPT_OPTIONAL_ATTRIBUTES);
421
422       command = (String) anAttributes.get(SCRIPT_COMMAND_ATTRIBUTE);
423     };
424
425     public ProducerNode constructNode() {
426       return new ScriptCallingProducerNode(command);
427     };
428   }
429
430 ////////////////////////////////////////////////////////////////////////////////
431
432   private final static String   DIRCOPY_SOURCE_ATTRIBUTE = "source";
433   private final static String   DIRCOPY_DESTINATION_ATTRIBUTE = "destination";
434   private final static String[] DIRCOPY_REQUIRED_ATTRIBUTES = { DIRCOPY_SOURCE_ATTRIBUTE, DIRCOPY_DESTINATION_ATTRIBUTE };
435   private final static String[] DIRCOPY_OPTIONAL_ATTRIBUTES = {};
436   private final static String[] DIRCOPY_SUBNODES = {};
437
438   public static class DirCopyProducerNodeBuilder extends AbstractProducerNodeBuilder {
439     private String source;
440     private String destination;
441     private String sourceBasePath;
442     private String destinationBasePath;
443
444     public DirCopyProducerNodeBuilder(String aSourceBasePath, String aDestinationBasePath) {
445       super(DIRCOPY_SUBNODES);
446
447       sourceBasePath = aSourceBasePath;
448       destinationBasePath = aDestinationBasePath;
449     }
450
451     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
452       ReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
453
454       source = (String) anAttributes.get(DIRCOPY_SOURCE_ATTRIBUTE);
455       destination = (String) anAttributes.get(DIRCOPY_DESTINATION_ATTRIBUTE);
456     };
457
458     public ProducerNode constructNode() {
459       return new DirCopyingProducerNode(sourceBasePath, destinationBasePath, source, destination);
460     };
461
462     public static class factory implements ProducerNodeBuilderFactory {
463       private String sourceBasePath;
464       private String destinationBasePath;
465
466       public factory(String aSourceBasePath, String aDestinationBasePath) {
467         sourceBasePath = aSourceBasePath;
468         destinationBasePath = aDestinationBasePath;
469       }
470
471       public ProducerNodeBuilder makeBuilder() {
472         return new DirCopyProducerNodeBuilder(sourceBasePath, destinationBasePath);
473       }
474     }
475   }
476
477 ////////////////////////////////////////////////////////////////////////////////
478
479   public static class GeneratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
480     private final static String   GENERATION_GENERATOR_ATTRIBUTE = "generator";
481     private final static String   GENERATION_DESTINATION_ATTRIBUTE = "destination";
482     private final static String   GENERATION_PARAMETERS_ATTRIBUTE = "parameters";
483     private final static String[] GENERATION_REQUIRED_ATTRIBUTES = { GENERATION_GENERATOR_ATTRIBUTE, GENERATION_DESTINATION_ATTRIBUTE };
484     private final static String[] GENERATION_OPTIONAL_ATTRIBUTES = { GENERATION_PARAMETERS_ATTRIBUTE};
485     private final static String[] GENERATION_SUBNODES = {};
486
487     private String generator;
488     private String destination;
489     private String parameters;
490     private Generator.GeneratorLibrary generatorLibrary;
491     private WriterEngine writerEngine;
492
493     public GeneratingProducerNodeBuilder(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
494       super(GENERATION_SUBNODES);
495
496       writerEngine = aWriterEngine;
497       generatorLibrary = aGeneratorLibrary;
498     }
499
500     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
501       ReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
502
503       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
504       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
505       parameters = ReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
506     };
507
508     public ProducerNode constructNode() {
509       return new GeneratingProducerNode(generatorLibrary, writerEngine, generator, destination, parameters);
510     };
511
512     public static class factory implements ProducerNodeBuilderFactory {
513       private Generator.GeneratorLibrary generatorLibrary;
514       private WriterEngine writerEngine;
515
516       public factory(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
517         writerEngine = aWriterEngine;
518         generatorLibrary = aGeneratorLibrary;
519       }
520
521       public ProducerNodeBuilder makeBuilder() {
522         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine);
523       }
524     }
525   }
526
527 ////////////////////////////////////////////////////////////////////////////////
528
529   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
530
531     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
532     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
533     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
534     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
535     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
536
537     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
538     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
539     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
540
541     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
542
543     private final static String   BATCHER_BATCH_SUBNODE = "batches";
544     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
545     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
546     private final static String[] BATCHER_OPTIONAL_ATTRIBUTES = { BATCHER_SELECTION_ATTRIBUTE, BATCHER_ORDER_ATTRIBUTE, BATCHER_MINBATCHSIZE_ATTRIBUTE, BATCHER_SKIP_ATTRIBUTE, BATCHER_PROCESS_ATTRIBUTE };
547     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
548
549     // ML: batchSize, minBatchSize, skip should be expressions!
550
551     private EntityAdapterModel model;
552     private String batchDataKey;
553     private String batchInfoKey;
554     private String definition;
555     private String selection;
556     private String order;
557     private String batchSize;
558     private String minBatchSize;
559     private String skip;
560     private String process;
561
562     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
563       super(BATCHER_SUBNODES);
564
565       model = aModel;
566     }
567
568     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
569       ReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
570
571       batchDataKey = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
572       batchInfoKey = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
573       definition = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
574       selection = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
575       order = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
576
577       batchSize = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
578       minBatchSize = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
579       skip = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
580       process = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
581     };
582
583     public ProducerNode constructNode() {
584       return new EntityBatchingProducerNode(
585           batchDataKey,
586           batchInfoKey,
587           model,
588           definition,
589           selection,
590           order,
591           batchSize,
592           minBatchSize,
593           skip,
594           process,
595           getSubNode( BATCHER_BATCH_SUBNODE ),
596           getSubNode( BATCHER_BATCHLIST_SUBNODE )
597       );
598     };
599
600     public static class factory implements ProducerNodeBuilderFactory {
601       private EntityAdapterModel model;
602
603       public factory(EntityAdapterModel aModel) {
604         model = aModel;
605       }
606
607       public ProducerNodeBuilder makeBuilder() {
608         return new BatchingProducerNodeBuilder(model);
609       }
610     }
611   }
612
613 ////////////////////////////////////////////////////////////////////////////////
614
615   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
616     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
617
618     private final static String   IF_TRUE_SUBNODE = "then";
619     private final static String   IF_FALSE_SUBNODE = "else";
620     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
621     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
622     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
623
624     private String condition;
625
626     public ConditionalProducerNodeBuilder() {
627       super(IF_SUBNODES);
628     }
629
630     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
631       ReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
632
633       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
634     };
635
636     public ProducerNode constructNode() {
637       return new ConditionalProducerNode(
638           condition,
639           getSubNode( IF_TRUE_SUBNODE ),
640           getSubNode( IF_FALSE_SUBNODE )
641       );
642     };
643
644   }
645
646 ////////////////////////////////////////////////////////////////////////////////
647
648   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
649     private String parameterName;
650     private String scriptedNodeName;
651
652     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
653       parameterName = aParameterName;
654       scriptedNodeName = aScriptedNodeName;
655     }
656
657     public void setSubNode(String aName, ProducerNode aNode) {
658     };
659
660     public Set getAvailableSubNodes() {
661       return new HashSet();
662     };
663
664     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
665       if (!anAttributes.isEmpty())
666         throw new ProducerConfigExc("No parameters allowed here");
667     };
668
669     public ProducerNode constructNode() {
670       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
671     };
672   }
673
674 ////////////////////////////////////////////////////////////////////////////////
675
676   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
677     private ScriptedProducerNodeDefinition definition;
678     private Map nodeParameterValues;
679     private Map integerParameterValues;
680     private Map stringParameterValues;
681
682     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
683       definition = aDefinition;
684
685       stringParameterValues = new HashMap();
686       stringParameterValues.putAll(definition.getStringParameters());
687
688       integerParameterValues = new HashMap();
689       integerParameterValues.putAll(definition.getIntegerParameters());
690
691       nodeParameterValues = new HashMap();
692     }
693
694     public void setSubNode(String aName, ProducerNode aNode) {
695       nodeParameterValues.put(aName, aNode);
696     };
697
698     public Set getAvailableSubNodes() {
699       return definition.getNodeParameters();
700     };
701
702     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
703       ReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
704
705       Iterator i = anAttributes.entrySet().iterator();
706       while (i.hasNext()) {
707         Map.Entry entry = (Map.Entry) i.next();
708
709         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
710           integerParameterValues.put(entry.getKey(), entry.getValue());
711         else
712           stringParameterValues.put(entry.getKey(), entry.getValue());
713       }
714     };
715
716     public ProducerNode constructNode() {
717       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
718     };
719
720     public static class factory implements ProducerNodeBuilderFactory {
721       private ScriptedProducerNodeDefinition definition;
722
723       public factory(ScriptedProducerNodeDefinition aDefinition) {
724         definition = aDefinition;
725       }
726
727       public ProducerNodeBuilder makeBuilder() {
728         return new ScriptedProducerNodeBuilder(definition);
729       }
730     }
731   }
732 }