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