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