some cosmetic change, organzied imports, and made some accesses in a static way
[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.EntityDeletingProducerNode;
47 import mir.producer.EntityEnumeratingProducerNode;
48 import mir.producer.EntityListProducerNode;
49 import mir.producer.EntityModifyingProducerNode;
50 import mir.producer.EvaluatedAssignmentProducerNode;
51 import mir.producer.ExpandedAssignmentProducerNode;
52 import mir.producer.FileDateSettingProducerNode;
53 import mir.producer.FileDeletingProducerNode;
54 import mir.producer.FreeQueryProducerNode;
55 import mir.producer.GeneratingProducerNode;
56 import mir.producer.ListEnumeratingProducerNode;
57 import mir.producer.LoggingProducerNode;
58 import mir.producer.LoopProducerNode;
59 import mir.producer.ProducerNode;
60 import mir.producer.RDFAggregatorProducerNode;
61 import mir.producer.RSSProducerNode;
62 import mir.producer.ResourceBundleProducerNode;
63 import mir.producer.ScriptCallingProducerNode;
64 import mir.producer.reader.ProducerNodeBuilder.ProducerNodeBuilderFactory;
65 import mir.util.XMLReader;
66 import mir.util.XMLReaderTool;
67
68 public class DefaultProducerNodeBuilders {
69
70   public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary,
71        EntityAdapterModel aModel, Generator.GeneratorLibrary aGeneratorLibrary,
72        WriterEngine aWriterEngine, String aSourceBasePath, String aDestinationBasePath) throws ProducerConfigExc {
73
74     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
75     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
76     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
77     aBuilderLibrary.registerBuilder("Execute", ScriptCallingProducerNodeBuilder.class);
78     aBuilderLibrary.registerBuilder("Resource", ResourceBundleProducerNodeBuilder.class);
79     aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory( aSourceBasePath, aDestinationBasePath));
80
81     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
82     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
83     aBuilderLibrary.registerBuilder("If", ConditionalProducerNodeBuilder.class);
84     aBuilderLibrary.registerBuilder("While", LoopProducerNodeBuilder.class);
85
86     aBuilderLibrary.registerBuilder("RSS", RSSProducerNodeBuilder.class);
87     aBuilderLibrary.registerBuilder("RDFAggregate", RDFAggregatorProducerNodeBuilder.class);
88
89     aBuilderLibrary.registerBuilder("FreeQuery", FreeQueryProducerNodeBuilder.class);
90
91     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
92     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
93     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
94
95     aBuilderLibrary.registerFactory("UpdateEntity", new UpdateEntityProducerNodeBuilder.factory(aModel));
96     aBuilderLibrary.registerFactory("CreateEntity", new CreateEntityProducerNodeBuilder.factory(aModel));
97     aBuilderLibrary.registerFactory("DeleteEntity", new DeleteEntityProducerNodeBuilder.factory(aModel));
98
99     aBuilderLibrary.registerFactory("Generate",
100         new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
101   }
102
103   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
104     private Map attributes;
105     private Map subNodes;
106     private Set availableSubnodes;
107
108     public AbstractProducerNodeBuilder(String anAvailableSubNodes[]) {
109       attributes = new HashMap();
110       subNodes = new HashMap();
111       availableSubnodes = new HashSet(Arrays.asList(anAvailableSubNodes));
112     }
113
114     protected ProducerNode getSubNode(String aName) {
115       return (ProducerNode) subNodes.get(aName);
116     }
117
118     public void setSubNode(String aName, ProducerNode aNode) {
119       subNodes.put(aName, aNode);
120     };
121
122     public Set getAvailableSubNodes() {
123       return availableSubnodes;
124     };
125   }
126
127 ////////////////////////////////////////////////////////////////////////////////
128
129   // general attribute names, specifc builders reference these, to keep attribute
130   //    names consistent
131
132   public final static String   SELECTION_ATTRIBUTE = "selection";
133   public final static String   ORDER_ATTRIBUTE = "order";
134   public final static String   DEFINITION_ATTRIBUTE = "table";
135   public final static String   SKIP_ATTRIBUTE = "skip";
136   public final static String   KEY_ATTRIBUTE = "key";
137   public final static String   LIMIT_ATTRIBUTE = "limit";
138   public final static String   URL_ATTRIBUTE = "url";
139
140 ////////////////////////////////////////////////////////////////////////////////
141
142   private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
143   private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
144   private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
145   private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
146   private final static String[] ASSIGNMENT_SUBNODES = {};
147
148   public static class ExpandedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
149
150     private String key;
151     private String value;
152
153     public ExpandedAssignmentProducerNodeBuilder() {
154       super(ASSIGNMENT_SUBNODES);
155     }
156
157     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
158       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
159
160       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
161       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
162     };
163
164     public ProducerNode constructNode() {
165       return new ExpandedAssignmentProducerNode(key, value);
166     };
167   }
168
169 ////////////////////////////////////////////////////////////////////////////////
170
171   public static class EvaluatedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
172
173     private String key;
174     private String value;
175
176     public EvaluatedAssignmentProducerNodeBuilder() {
177       super(ASSIGNMENT_SUBNODES);
178     }
179
180     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
181       XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
182
183       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
184       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
185     };
186
187     public ProducerNode constructNode() {
188       return new EvaluatedAssignmentProducerNode(key, value);
189     };
190   }
191
192 ////////////////////////////////////////////////////////////////////////////////
193
194   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
195     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
196     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
197     private final static String   ENUMERATION_LIST_ATTRIBUTE = "list";
198     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
199     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
200     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
201     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
202     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
203     private final static String[] ENUMERATION_LIST_REQUIRED_ATTRIBUTES = { ENUMERATION_LIST_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
204     private final static String[] ENUMERATION_LIST_OPTIONAL_ATTRIBUTES = { };
205     private final static String[] ENUMERATION_QUERY_REQUIRED_ATTRIBUTES = { ENUMERATION_DEFINITION_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
206     private final static String[] ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE};
207     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
208
209     private String key;
210     private String definition;
211     private String list;
212     private String selection;
213     private String order;
214     private String limit;
215     private String skip;
216     private EntityAdapterModel model;
217
218     public EnumeratingProducerNodeBuilder(EntityAdapterModel aModel) {
219       super(ENUMERATION_SUBNODES);
220
221       model = aModel;
222     }
223
224     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
225       definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
226       list = (String) anAttributes.get(ENUMERATION_LIST_ATTRIBUTE);
227
228       if ((list==null && definition==null) || (list!=null && definition!=null))
229         throw new ProducerConfigExc("Exactly one of "+ENUMERATION_DEFINITION_ATTRIBUTE+" and "+ENUMERATION_LIST_ATTRIBUTE+" must be set");
230
231
232       if (list!=null)
233         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
234       if (definition!=null)
235         XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
236
237
238       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
239       selection = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
240       order = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
241       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
242       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
243     };
244
245     public ProducerNode constructNode() {
246       if (definition!=null)
247         return new EntityEnumeratingProducerNode(key, model, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
248       else
249         return new ListEnumeratingProducerNode(key, list, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
250     };
251
252     public static class factory implements ProducerNodeBuilderFactory {
253       private EntityAdapterModel model;
254
255       public factory(EntityAdapterModel aModel) {
256         model = aModel;
257       }
258
259       public ProducerNodeBuilder makeBuilder() {
260         return new EnumeratingProducerNodeBuilder(model);
261       }
262     }
263   }
264
265 ////////////////////////////////////////////////////////////////////////////////
266
267   public static class UpdateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
268     private final static String   UPDATE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
269     private final static String   UPDATE_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
270     private final static String[] UPDATE_SUBNODES = {};
271
272     private String key;
273     private String definition;
274     private Map fieldValues;
275
276     private EntityAdapterModel model;
277
278     public UpdateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
279       super(UPDATE_SUBNODES);
280
281       model = aModel;
282       fieldValues = new HashMap();
283     }
284
285     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
286       key = (String) anAttributes.get(UPDATE_KEY_ATTRIBUTE);
287
288       if (key == null)
289         throw new XMLReader.XMLReaderExc("missing required attribute '" + UPDATE_KEY_ATTRIBUTE + "'" );
290       definition = (String) anAttributes.get(UPDATE_DEFINITION_ATTRIBUTE);
291
292       fieldValues.putAll(anAttributes);
293       fieldValues.remove(UPDATE_KEY_ATTRIBUTE);
294       fieldValues.remove(UPDATE_DEFINITION_ATTRIBUTE);
295     };
296
297     public ProducerNode constructNode() {
298       return new EntityModifyingProducerNode(model, false, definition, key, fieldValues);
299     };
300
301     public static class factory implements ProducerNodeBuilderFactory {
302       private EntityAdapterModel model;
303
304       public factory(EntityAdapterModel aModel) {
305         model = aModel;
306       }
307
308       public ProducerNodeBuilder makeBuilder() {
309         return new UpdateEntityProducerNodeBuilder(model);
310       }
311     }
312   }
313
314 ////////////////////////////////////////////////////////////////////////////////
315
316   public static class CreateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
317     private final static String   CREATEENTITY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
318     private final static String   CREATEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
319     private final static String[] CREATEENTITY_SUBNODES = {};
320
321     private String key;
322     private String definition;
323     private Map fieldValues;
324
325     private EntityAdapterModel model;
326
327     public CreateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
328       super(CREATEENTITY_SUBNODES);
329
330       model = aModel;
331       fieldValues = new HashMap();
332     }
333
334     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
335       key = (String) anAttributes.get(CREATEENTITY_KEY_ATTRIBUTE);
336       definition = (String) anAttributes.get(CREATEENTITY_DEFINITION_ATTRIBUTE);
337
338       if (key == null)
339         throw new XMLReader.XMLReaderExc("missing required attribute '" + CREATEENTITY_KEY_ATTRIBUTE + "'" );
340       if (definition == null)
341         throw new XMLReader.XMLReaderExc("missing required attribute '" + CREATEENTITY_DEFINITION_ATTRIBUTE + "'" );
342
343       fieldValues.putAll(anAttributes);
344       fieldValues.remove(CREATEENTITY_KEY_ATTRIBUTE);
345       fieldValues.remove(CREATEENTITY_DEFINITION_ATTRIBUTE);
346     };
347
348     public ProducerNode constructNode() {
349       return new EntityModifyingProducerNode(model, true, definition, key, fieldValues);
350     };
351
352     public static class factory implements ProducerNodeBuilderFactory {
353       private EntityAdapterModel model;
354
355       public factory(EntityAdapterModel aModel) {
356         model = aModel;
357       }
358
359       public ProducerNodeBuilder makeBuilder() {
360         return new CreateEntityProducerNodeBuilder(model);
361       }
362     }
363   }
364
365 ////////////////////////////////////////////////////////////////////////////////
366
367   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
368     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
369     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
370     private final static String   LOOP_DEFAULT_SUBNODE = "default";
371     private final static String[] LOOP_REQUIRED_ATTRIBUTES = { LOOP_CONDITION_ATTRIBUTE };
372     private final static String[] LOOP_OPTIONAL_ATTRIBUTES = { LOOP_LIMIT_ATTRIBUTE };
373     private final static String[] LOOP_SUBNODES = {LOOP_DEFAULT_SUBNODE};
374
375     private String condition;
376     private String limit;
377
378     public LoopProducerNodeBuilder() {
379       super(LOOP_SUBNODES);
380     }
381
382     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
383       XMLReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
384
385       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
386       limit = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
387     };
388
389     public ProducerNode constructNode() {
390       return new LoopProducerNode(condition, limit, getSubNode( LOOP_DEFAULT_SUBNODE ));
391     };
392   }
393
394 ////////////////////////////////////////////////////////////////////////////////
395
396   public static class ListProducerNodeBuilder extends AbstractProducerNodeBuilder {
397     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
398     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
399     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
400     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
401     private final static String   LIST_DEFAULT_SUBNODE = "default";
402     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
403     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
404     private final static String[] LIST_REQUIRED_ATTRIBUTES = { LIST_KEY_ATTRIBUTE, LIST_DEFINITION_ATTRIBUTE };
405     private final static String[] LIST_OPTIONAL_ATTRIBUTES = { LIST_SELECTION_ATTRIBUTE, LIST_ORDER_ATTRIBUTE, LIST_SKIP_ATTRIBUTE, LIST_LIMIT_ATTRIBUTE};
406     private final static String[] LIST_SUBNODES = {};
407
408     private String key;
409     private String definition;
410     private String selection;
411     private String order;
412     private String limit;
413     private String skip;
414     private EntityAdapterModel model;
415
416     public ListProducerNodeBuilder(EntityAdapterModel aModel) {
417       super(LIST_SUBNODES);
418
419       model = aModel;
420     }
421
422     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
423       XMLReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
424
425       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
426       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
427       selection = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
428       order = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
429       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
430       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
431     };
432
433     public ProducerNode constructNode() {
434       return new EntityListProducerNode(key, model, definition, selection, order, limit, skip, null );
435     };
436
437     public static class factory implements ProducerNodeBuilderFactory {
438       private EntityAdapterModel model;
439
440       public factory(EntityAdapterModel aModel) {
441         model = aModel;
442       }
443
444       public ProducerNodeBuilder makeBuilder() {
445         return new ListProducerNodeBuilder(model);
446       }
447     }
448   }
449
450 ////////////////////////////////////////////////////////////////////////////////
451
452   public static class DeleteEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
453     private final static String   DELETEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
454     private final static String   DELETEENTITY_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
455     private final static String[] DELETEENTITY_REQUIRED_ATTRIBUTES = { DELETEENTITY_SELECTION_ATTRIBUTE, DELETEENTITY_DEFINITION_ATTRIBUTE };
456     private final static String[] DELETEENTITY_OPTIONAL_ATTRIBUTES = { };
457     private final static String[] DELETEENTITY_SUBNODES = {};
458
459     private String definition;
460     private String selection;
461
462     private EntityAdapterModel model;
463
464     public DeleteEntityProducerNodeBuilder(EntityAdapterModel aModel) {
465       super(DELETEENTITY_SUBNODES);
466
467       model = aModel;
468     }
469
470     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
471       XMLReaderTool.checkAttributes(anAttributes, DELETEENTITY_REQUIRED_ATTRIBUTES, DELETEENTITY_OPTIONAL_ATTRIBUTES);
472
473       definition = (String) anAttributes.get(DELETEENTITY_DEFINITION_ATTRIBUTE);
474       selection = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, DELETEENTITY_SELECTION_ATTRIBUTE, "");
475     };
476
477     public ProducerNode constructNode() {
478       return new EntityDeletingProducerNode(model, definition, selection);
479     };
480
481     public static class factory implements ProducerNodeBuilderFactory {
482       private EntityAdapterModel model;
483
484       public factory(EntityAdapterModel aModel) {
485         model = aModel;
486       }
487
488       public ProducerNodeBuilder makeBuilder() {
489         return new DeleteEntityProducerNodeBuilder(model);
490       }
491     }
492   }
493
494 ////////////////////////////////////////////////////////////////////////////////
495
496   public static class LoggingProducerNodeBuilder extends AbstractProducerNodeBuilder {
497     private final static String   LOG_MESSAGE_ATTRIBUTE = "message";
498     private final static String   LOG_TYPE_ATTRIBUTE = "type";
499     private final static String[] LOG_REQUIRED_ATTRIBUTES = { LOG_MESSAGE_ATTRIBUTE };
500     private final static String[] LOG_OPTIONAL_ATTRIBUTES = { LOG_TYPE_ATTRIBUTE };
501     private final static String[] LOG_SUBNODES = {};
502
503     private String message;
504     private int type = LoggerWrapper.INFO_MESSAGE;
505
506     public LoggingProducerNodeBuilder() {
507       super(LOG_SUBNODES);
508     }
509
510     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
511       String typeString;
512
513       XMLReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
514
515       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
516       if (anAttributes.containsKey(LOG_TYPE_ATTRIBUTE)) {
517         typeString = ((String) anAttributes.get( LOG_TYPE_ATTRIBUTE ));
518
519         if (typeString.toLowerCase().equals("debug"))
520           type = LoggerWrapper.DEBUG_MESSAGE;
521         else if (typeString.toLowerCase().equals("info"))
522           type = LoggerWrapper.INFO_MESSAGE;
523         else if (typeString.toLowerCase().equals("error"))
524           type = LoggerWrapper.ERROR_MESSAGE;
525         else if (typeString.toLowerCase().equals("warning"))
526           type = LoggerWrapper.WARN_MESSAGE;
527         else if (typeString.toLowerCase().equals("fatal"))
528           type = LoggerWrapper.FATAL_MESSAGE;
529         else
530           throw new ProducerConfigExc("unknown log type: " + typeString + " (allowed are debug, info, warning, error, fatal)");
531       }
532       else
533         type = LoggerWrapper.INFO_MESSAGE;
534     };
535
536     public ProducerNode constructNode() {
537       return new LoggingProducerNode(message, type);
538     };
539   }
540
541 ////////////////////////////////////////////////////////////////////////////////
542
543   public static class FreeQueryProducerNodeBuilder extends AbstractProducerNodeBuilder {
544     private final static String   FREEQUERY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
545     private final static String   FREEQUERY_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
546     private final static String   FREEQUERY_QUERY_ATTRIBUTE = "query";
547     private final static String   FREEQUERY_TYPE_ATTRIBUTE = "type";
548     private final static String[] FREEQUERY_REQUIRED_ATTRIBUTES = { KEY_ATTRIBUTE, FREEQUERY_QUERY_ATTRIBUTE };
549     private final static String[] FREEQUERY_OPTIONAL_ATTRIBUTES = { LIMIT_ATTRIBUTE, FREEQUERY_TYPE_ATTRIBUTE };
550     private final static String[] FREEQUERY_SUBNODES = {};
551
552     private String key;
553     private String query;
554     private String limit;
555     private int type;
556
557     public FreeQueryProducerNodeBuilder() {
558       super(FREEQUERY_SUBNODES);
559     }
560
561     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
562       String typeString;
563
564       XMLReaderTool.checkAttributes(anAttributes, FREEQUERY_REQUIRED_ATTRIBUTES, FREEQUERY_OPTIONAL_ATTRIBUTES);
565
566       key = (String) anAttributes.get(FREEQUERY_KEY_ATTRIBUTE);
567       query = (String) anAttributes.get(FREEQUERY_QUERY_ATTRIBUTE);
568       limit = (String) anAttributes.get(FREEQUERY_LIMIT_ATTRIBUTE);
569
570       if (anAttributes.containsKey(FREEQUERY_TYPE_ATTRIBUTE)) {
571         typeString = ((String) anAttributes.get( FREEQUERY_TYPE_ATTRIBUTE ));
572
573         if (typeString.toLowerCase().equals("set"))
574           type = FreeQueryProducerNode.QUERY_TYPE_SET;
575         else if (typeString.toLowerCase().equals("row"))
576           type = FreeQueryProducerNode.QUERY_TYPE_ROW;
577         else if (typeString.toLowerCase().equals("value"))
578           type = FreeQueryProducerNode.QUERY_TYPE_VALUE;
579         else if (typeString.toLowerCase().equals("update"))
580           type = FreeQueryProducerNode.QUERY_TYPE_UPDATE;
581         else
582           throw new ProducerConfigExc("unknown query type: " + typeString + " (allowed are set, row and value)");
583       }
584       else
585         type = FreeQueryProducerNode.QUERY_TYPE_SET;
586     };
587
588     public ProducerNode constructNode() {
589       return new FreeQueryProducerNode(key, query, limit, type);
590     };
591   }
592
593 ////////////////////////////////////////////////////////////////////////////////
594
595   public static class ResourceBundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
596     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
597     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
598     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
599     private final static String   RESOURCEBUNDLE_DEFAULT_SUBNODE = "default";
600     private final static String[] RESOURCEBUNDLE_REQUIRED_ATTRIBUTES = { RESOURCEBUNDLE_KEY_ATTRIBUTE, RESOURCEBUNDLE_BUNDLE_ATTRIBUTE };
601     private final static String[] RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES = { RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE};
602     private final static String[] RESOURCEBUNDLE_SUBNODES = {};
603
604     private String key;
605     private String bundle;
606     private String language;
607
608     public ResourceBundleProducerNodeBuilder() {
609       super(RESOURCEBUNDLE_SUBNODES);
610     }
611
612     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
613       XMLReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
614
615       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
616       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
617       language = (String) anAttributes.get(RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE);
618     };
619
620     public ProducerNode constructNode() {
621       return new ResourceBundleProducerNode(key, bundle, language);
622     };
623   }
624
625 ////////////////////////////////////////////////////////////////////////////////
626
627   public static class FileDateSettingProducerNodeBuilder extends AbstractProducerNodeBuilder {
628     private final static String   FILEDATESETTING_FILE_ATTRIBUTE = "filename";
629     private final static String   FILEDATESETTING_DATE_ATTRIBUTE = "date";
630     private final static String[] FILEDATESETTING_REQUIRED_ATTRIBUTES = { FILEDATESETTING_FILE_ATTRIBUTE, FILEDATESETTING_DATE_ATTRIBUTE };
631     private final static String[] FILEDATESETTING_OPTIONAL_ATTRIBUTES = { };
632     private final static String[] FILEDATESETTING_SUBNODES = {};
633
634     private String fileNameKey;
635     private String dateKey;
636
637     public FileDateSettingProducerNodeBuilder() {
638       super(FILEDATESETTING_SUBNODES);
639     }
640
641     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
642       XMLReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
643
644       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
645       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
646     };
647
648     public ProducerNode constructNode() {
649       return new FileDateSettingProducerNode(fileNameKey, dateKey);
650     };
651   }
652
653 ////////////////////////////////////////////////////////////////////////////////
654
655   public static class FileDeletingProducerNodeBuilder extends AbstractProducerNodeBuilder {
656     private final static String   FILEDELETING_FILE_ATTRIBUTE = "filename";
657     private final static String[] FILEDELETING_REQUIRED_ATTRIBUTES = { FILEDELETING_FILE_ATTRIBUTE };
658     private final static String[] FILEDELETING_OPTIONAL_ATTRIBUTES = { };
659     private final static String[] FILEDELETING_SUBNODES = { };
660
661     private String fileNameKey;
662
663     public FileDeletingProducerNodeBuilder() {
664       super(FILEDELETING_SUBNODES);
665     }
666
667     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
668       XMLReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
669
670       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
671     };
672
673     public ProducerNode constructNode() {
674       return new FileDeletingProducerNode(fileNameKey);
675     };
676   }
677
678 ////////////////////////////////////////////////////////////////////////////////
679
680   public static class ScriptCallingProducerNodeBuilder extends AbstractProducerNodeBuilder {
681     private final static String   SCRIPT_COMMAND_ATTRIBUTE = "command";
682     private final static String[] SCRIPT_REQUIRED_ATTRIBUTES = { SCRIPT_COMMAND_ATTRIBUTE };
683     private final static String[] SCRIPT_OPTIONAL_ATTRIBUTES = {};
684     private final static String[] SCRIPT_SUBNODES = {};
685
686     private String command;
687
688     public ScriptCallingProducerNodeBuilder() {
689       super(SCRIPT_SUBNODES);
690     }
691
692     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
693       XMLReaderTool.checkAttributes(anAttributes, SCRIPT_REQUIRED_ATTRIBUTES, SCRIPT_OPTIONAL_ATTRIBUTES);
694
695       command = (String) anAttributes.get(SCRIPT_COMMAND_ATTRIBUTE);
696     };
697
698     public ProducerNode constructNode() {
699       return new ScriptCallingProducerNode(command);
700     };
701   }
702
703 ////////////////////////////////////////////////////////////////////////////////
704
705   private final static String   DIRCOPY_SOURCE_ATTRIBUTE = "source";
706   private final static String   DIRCOPY_DESTINATION_ATTRIBUTE = "destination";
707   private final static String[] DIRCOPY_REQUIRED_ATTRIBUTES = { DIRCOPY_SOURCE_ATTRIBUTE, DIRCOPY_DESTINATION_ATTRIBUTE };
708   private final static String[] DIRCOPY_OPTIONAL_ATTRIBUTES = {};
709   private final static String[] DIRCOPY_SUBNODES = {};
710
711   public static class DirCopyProducerNodeBuilder extends AbstractProducerNodeBuilder {
712     private String source;
713     private String destination;
714     private String sourceBasePath;
715     private String destinationBasePath;
716
717     public DirCopyProducerNodeBuilder(String aSourceBasePath, String aDestinationBasePath) {
718       super(DIRCOPY_SUBNODES);
719
720       sourceBasePath = aSourceBasePath;
721       destinationBasePath = aDestinationBasePath;
722     }
723
724     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
725       XMLReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
726
727       source = (String) anAttributes.get(DIRCOPY_SOURCE_ATTRIBUTE);
728       destination = (String) anAttributes.get(DIRCOPY_DESTINATION_ATTRIBUTE);
729     };
730
731     public ProducerNode constructNode() {
732       return new DirCopyingProducerNode(sourceBasePath, destinationBasePath, source, destination);
733     };
734
735     public static class factory implements ProducerNodeBuilderFactory {
736       private String sourceBasePath;
737       private String destinationBasePath;
738
739       public factory(String aSourceBasePath, String aDestinationBasePath) {
740         sourceBasePath = aSourceBasePath;
741         destinationBasePath = aDestinationBasePath;
742       }
743
744       public ProducerNodeBuilder makeBuilder() {
745         return new DirCopyProducerNodeBuilder(sourceBasePath, destinationBasePath);
746       }
747     }
748   }
749
750 ////////////////////////////////////////////////////////////////////////////////
751
752   public static class GeneratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
753     private final static String   GENERATION_GENERATOR_ATTRIBUTE = "generator";
754     private final static String   GENERATION_DESTINATION_ATTRIBUTE = "destination";
755     private final static String   GENERATION_PARAMETERS_ATTRIBUTE = "parameters";
756     private final static String[] GENERATION_REQUIRED_ATTRIBUTES = { GENERATION_GENERATOR_ATTRIBUTE, GENERATION_DESTINATION_ATTRIBUTE };
757     private final static String[] GENERATION_OPTIONAL_ATTRIBUTES = { GENERATION_PARAMETERS_ATTRIBUTE};
758     private final static String[] GENERATION_SUBNODES = {};
759
760     private String generator;
761     private String destination;
762     private String parameters;
763     private Generator.GeneratorLibrary generatorLibrary;
764     private WriterEngine writerEngine;
765
766     public GeneratingProducerNodeBuilder(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
767       super(GENERATION_SUBNODES);
768
769       writerEngine = aWriterEngine;
770       generatorLibrary = aGeneratorLibrary;
771     }
772
773     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
774       XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
775
776       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
777       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
778       parameters = XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
779     };
780
781     public ProducerNode constructNode() {
782       return new GeneratingProducerNode(generatorLibrary, writerEngine, generator, destination, parameters);
783     };
784
785     public static class factory implements ProducerNodeBuilderFactory {
786       private Generator.GeneratorLibrary generatorLibrary;
787       private WriterEngine writerEngine;
788
789       public factory(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
790         writerEngine = aWriterEngine;
791         generatorLibrary = aGeneratorLibrary;
792       }
793
794       public ProducerNodeBuilder makeBuilder() {
795         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine);
796       }
797     }
798   }
799
800 ////////////////////////////////////////////////////////////////////////////////
801
802   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
803
804     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
805     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
806     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
807     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
808     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
809
810     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
811     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
812     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
813
814     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
815
816     private final static String   BATCHER_BATCH_SUBNODE = "batches";
817     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
818     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
819     private final static String[] BATCHER_OPTIONAL_ATTRIBUTES = { BATCHER_SELECTION_ATTRIBUTE, BATCHER_ORDER_ATTRIBUTE, BATCHER_MINBATCHSIZE_ATTRIBUTE, BATCHER_SKIP_ATTRIBUTE, BATCHER_PROCESS_ATTRIBUTE };
820     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
821
822     private EntityAdapterModel model;
823     private String batchDataKey;
824     private String batchInfoKey;
825     private String definition;
826     private String selection;
827     private String order;
828     private String batchSize;
829     private String minBatchSize;
830     private String skip;
831     private String process;
832
833     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
834       super(BATCHER_SUBNODES);
835
836       model = aModel;
837     }
838
839     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
840       XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
841
842       batchDataKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
843       batchInfoKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
844       definition = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
845       selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
846       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
847
848       batchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
849       minBatchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
850       skip = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
851       process = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
852     };
853
854     public ProducerNode constructNode() {
855       return new EntityBatchingProducerNode(
856           batchDataKey,
857           batchInfoKey,
858           model,
859           definition,
860           selection,
861           order,
862           batchSize,
863           minBatchSize,
864           skip,
865           process,
866           getSubNode( BATCHER_BATCH_SUBNODE ),
867           getSubNode( BATCHER_BATCHLIST_SUBNODE )
868       );
869     };
870
871     public static class factory implements ProducerNodeBuilderFactory {
872       private EntityAdapterModel model;
873
874       public factory(EntityAdapterModel aModel) {
875         model = aModel;
876       }
877
878       public ProducerNodeBuilder makeBuilder() {
879         return new BatchingProducerNodeBuilder(model);
880       }
881     }
882   }
883
884 ////////////////////////////////////////////////////////////////////////////////
885
886   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
887     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
888
889     private final static String   IF_TRUE_SUBNODE = "then";
890     private final static String   IF_FALSE_SUBNODE = "else";
891     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
892     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
893     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
894
895     private String condition;
896
897     public ConditionalProducerNodeBuilder() {
898       super(IF_SUBNODES);
899     }
900
901     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
902       XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
903
904       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
905     };
906
907     public ProducerNode constructNode() {
908       return new ConditionalProducerNode(
909           condition,
910           getSubNode( IF_TRUE_SUBNODE ),
911           getSubNode( IF_FALSE_SUBNODE )
912       );
913     };
914
915   }
916
917 ////////////////////////////////////////////////////////////////////////////////
918
919   public static class RSSProducerNodeBuilder extends AbstractProducerNodeBuilder {
920     private final static String   RSS_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
921     private final static String   RSS_URL_ATTRIBUTE = URL_ATTRIBUTE;
922     private final static String   RSS_VERSION_ATTRIBUTE = "version";
923
924     private final static String[] RSS_REQUIRED_ATTRIBUTES = { RSS_KEY_ATTRIBUTE, RSS_URL_ATTRIBUTE };
925     private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE };
926     private final static String[] RSS_SUBNODES = {  };
927
928     private String key;
929     private String url;
930     private String version;
931
932     public RSSProducerNodeBuilder() {
933       super(RSS_SUBNODES);
934     }
935
936     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
937       XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
938
939       key = (String) anAttributes.get( RSS_KEY_ATTRIBUTE );
940       url = (String) anAttributes.get( RSS_URL_ATTRIBUTE );
941       version = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
942     };
943
944     public ProducerNode constructNode() {
945       return new RSSProducerNode(key, url, version);
946     };
947   }
948
949 ////////////////////////////////////////////////////////////////////////////////
950
951   public static class RDFAggregatorProducerNodeBuilder extends AbstractProducerNodeBuilder {
952     private final static String   RDF_AGGREGATOR_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
953     private final static String   RDF_AGGREGATOR_SOURCE_ATTRIBUTE = "source";
954     private final static String   RDF_AGGREGATOR_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
955     private final static String   RDF_AGGREGATOR_FILTER_ATTRIBUTE = "filter";
956
957     private final static String[] RDF_AGGREGATOR_REQUIRED_ATTRIBUTES = { RDF_AGGREGATOR_KEY_ATTRIBUTE, RDF_AGGREGATOR_SOURCE_ATTRIBUTE };
958     private final static String[] RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES = { RDF_AGGREGATOR_ORDER_ATTRIBUTE, RDF_AGGREGATOR_FILTER_ATTRIBUTE };
959     private final static String[] RDF_AGGREGATOR_SUBNODES = {  };
960
961     private String key;
962     private String source;
963     private String order;
964     private String filter;
965
966     public RDFAggregatorProducerNodeBuilder() {
967       super(RDF_AGGREGATOR_SUBNODES);
968     }
969
970     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
971       XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
972
973       key = (String) anAttributes.get( RDF_AGGREGATOR_KEY_ATTRIBUTE );
974       source = (String) anAttributes.get( RDF_AGGREGATOR_SOURCE_ATTRIBUTE );
975       order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_SOURCE_ATTRIBUTE, "");
976       filter = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_FILTER_ATTRIBUTE, "");
977     };
978
979     public ProducerNode constructNode() {
980       return new RDFAggregatorProducerNode(key, source, order, filter);
981     };
982   }
983
984 ////////////////////////////////////////////////////////////////////////////////
985
986   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
987     private String parameterName;
988     private String scriptedNodeName;
989
990     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
991       parameterName = aParameterName;
992       scriptedNodeName = aScriptedNodeName;
993     }
994
995     public void setSubNode(String aName, ProducerNode aNode) {
996     };
997
998     public Set getAvailableSubNodes() {
999       return new HashSet();
1000     };
1001
1002     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
1003       if (!anAttributes.isEmpty())
1004         throw new ProducerConfigExc("No parameters allowed here");
1005     };
1006
1007     public ProducerNode constructNode() {
1008       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
1009     };
1010   }
1011
1012 ////////////////////////////////////////////////////////////////////////////////
1013
1014   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
1015     private ScriptedProducerNodeDefinition definition;
1016     private Map nodeParameterValues;
1017     private Map integerParameterValues;
1018     private Map stringParameterValues;
1019
1020     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
1021       definition = aDefinition;
1022
1023       stringParameterValues = new HashMap();
1024       stringParameterValues.putAll(definition.getStringParameters());
1025
1026       integerParameterValues = new HashMap();
1027       integerParameterValues.putAll(definition.getIntegerParameters());
1028
1029       nodeParameterValues = new HashMap();
1030     }
1031
1032     public void setSubNode(String aName, ProducerNode aNode) {
1033       nodeParameterValues.put(aName, aNode);
1034     };
1035
1036     public Set getAvailableSubNodes() {
1037       return definition.getNodeParameters();
1038     };
1039
1040     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc {
1041       XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
1042
1043       Iterator i = anAttributes.entrySet().iterator();
1044       while (i.hasNext()) {
1045         Map.Entry entry = (Map.Entry) i.next();
1046
1047         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
1048           integerParameterValues.put(entry.getKey(), entry.getValue());
1049         else
1050           stringParameterValues.put(entry.getKey(), entry.getValue());
1051       }
1052     };
1053
1054     public ProducerNode constructNode() {
1055       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
1056     };
1057
1058     public static class factory implements ProducerNodeBuilderFactory {
1059       private ScriptedProducerNodeDefinition definition;
1060
1061       public factory(ScriptedProducerNodeDefinition aDefinition) {
1062         definition = aDefinition;
1063       }
1064
1065       public ProducerNodeBuilder makeBuilder() {
1066         return new ScriptedProducerNodeBuilder(definition);
1067       }
1068     }
1069   }
1070 }