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