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