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