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