- general maintenance
[mir.git] / source / mir / producer / reader / DefaultProducerNodeBuilders.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mir.producer.reader;
33
34 import java.util.*;
35 import mir.generator.*;
36 import mir.producer.*;
37 import mir.entity.adapter.*;
38 import mir.util.*;
39
40 public class DefaultProducerNodeBuilders {
41
42   public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary,
43        EntityAdapterModel aModel, Generator.GeneratorLibrary aGeneratorLibrary,
44        WriterEngine aWriterEngine) {
45
46     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
47     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
48     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
49     aBuilderLibrary.registerBuilder("Execute", ScriptCallingProducerNodeBuilder.class);
50     aBuilderLibrary.registerBuilder("Resource", ResourceBundleProducerNodeBuilder.class);
51
52     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
53     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
54     aBuilderLibrary.registerBuilder("If", ConditionalProducerNodeBuilder.class);
55     aBuilderLibrary.registerBuilder("While", LoopProducerNodeBuilder.class);
56
57
58     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
59     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
60     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
61
62     aBuilderLibrary.registerFactory("Generate",
63         new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
64   }
65
66   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
67     private Map attributes;
68     private Map subNodes;
69     private Set availableSubnodes;
70
71     public AbstractProducerNodeBuilder(String anAvailableSubNodes[]) {
72       attributes = new HashMap();
73       subNodes = new HashMap();
74       availableSubnodes = new HashSet(Arrays.asList(anAvailableSubNodes));
75     }
76
77     protected ProducerNode getSubNode(String aName) {
78       return (ProducerNode) subNodes.get(aName);
79     }
80
81     public void setSubNode(String aName, ProducerNode aNode) {
82       subNodes.put(aName, aNode);
83     };
84
85     public Set getAvailableSubNodes() {
86       return availableSubnodes;
87     };
88   }
89
90 ////////////////////////////////////////////////////////////////////////////////
91
92   // general attribute names, specifc builders reference these, to keep attribute
93   //    names consistent
94
95   public final static String   SELECTION_ATTRIBUTE = "selection";
96   public final static String   ORDER_ATTRIBUTE = "order";
97   public final static String   DEFINITION_ATTRIBUTE = "table";
98   public final static String   SKIP_ATTRIBUTE = "skip";
99   public final static String   KEY_ATTRIBUTE = "key";
100   public final static String   LIMIT_ATTRIBUTE = "limit";
101
102 ////////////////////////////////////////////////////////////////////////////////
103
104   public static class ExpandedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
105     private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
106     private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
107     private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
108     private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
109     private final static String[] ASSIGNMENT_SUBNODES = {};
110
111     private String key;
112     private String value;
113
114     public ExpandedAssignmentProducerNodeBuilder() {
115       super(ASSIGNMENT_SUBNODES);
116     }
117
118     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
119       ReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
120
121       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
122       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
123     };
124
125     public ProducerNode constructNode() {
126       return new ExpandedAssignmentProducerNode(key, value);
127     };
128   }
129
130 ////////////////////////////////////////////////////////////////////////////////
131
132   public static class EvaluatedAssignmentProducerNodeBuilder extends AbstractProducerNodeBuilder {
133     private final static String   ASSIGNMENT_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
134     private final static String   ASSIGNMENT_VALUE_ATTRIBUTE = "value";
135     private final static String[] ASSIGNMENT_REQUIRED_ATTRIBUTES = { ASSIGNMENT_KEY_ATTRIBUTE, ASSIGNMENT_VALUE_ATTRIBUTE };
136     private final static String[] ASSIGNMENT_OPTIONAL_ATTRIBUTES = {};
137     private final static String[] ASSIGNMENT_SUBNODES = {};
138
139     private String key;
140     private String value;
141
142     public EvaluatedAssignmentProducerNodeBuilder() {
143       super(ASSIGNMENT_SUBNODES);
144     }
145
146     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
147       ReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
148
149       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
150       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
151     };
152
153     public ProducerNode constructNode() {
154       return new EvaluatedAssignmentProducerNode(key, value);
155     };
156   }
157
158 ////////////////////////////////////////////////////////////////////////////////
159
160   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
161     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
162     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
163     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
164     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
165     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
166     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
167     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
168     private final static String[] ENUMERATION_REQUIRED_ATTRIBUTES = { ENUMERATION_KEY_ATTRIBUTE, ENUMERATION_DEFINITION_ATTRIBUTE };
169     private final static String[] ENUMERATION_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE};
170     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
171
172     private String key;
173     private String definition;
174     private String selection;
175     private String order;
176     private String limit;
177     private String skip;
178     private EntityAdapterModel model;
179
180     public EnumeratingProducerNodeBuilder(EntityAdapterModel aModel) {
181       super(ENUMERATION_SUBNODES);
182
183       model = aModel;
184     }
185
186     public void setAttributes(Map anAttributes) throws ProducerConfigExc  {
187       ReaderTool.checkAttributes(anAttributes, ENUMERATION_REQUIRED_ATTRIBUTES, ENUMERATION_OPTIONAL_ATTRIBUTES);
188
189       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
190       definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
191       selection = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
192       order = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
193       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
194       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
195     };
196
197     public ProducerNode constructNode() {
198       return new EntityEnumeratingProducerNode(key, model, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
199     };
200
201     public static class factory implements ProducerNodeBuilderFactory {
202       private EntityAdapterModel model;
203
204       public factory(EntityAdapterModel aModel) {
205         model = aModel;
206       }
207
208       public ProducerNodeBuilder makeBuilder() {
209         return new EnumeratingProducerNodeBuilder(model);
210       }
211     }
212   }
213
214 ////////////////////////////////////////////////////////////////////////////////
215
216   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
217     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
218     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
219     private final static String   LOOP_DEFAULT_SUBNODE = "default";
220     private final static String[] LOOP_REQUIRED_ATTRIBUTES = { LOOP_CONDITION_ATTRIBUTE };
221     private final static String[] LOOP_OPTIONAL_ATTRIBUTES = { LOOP_LIMIT_ATTRIBUTE };
222     private final static String[] LOOP_SUBNODES = {LOOP_DEFAULT_SUBNODE};
223
224     private String condition;
225     private String limit;
226
227     public LoopProducerNodeBuilder() {
228       super(LOOP_SUBNODES);
229     }
230
231     public void setAttributes(Map anAttributes) throws ProducerConfigExc  {
232       ReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
233
234       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
235       limit = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
236     };
237
238     public ProducerNode constructNode() {
239       return new LoopProducerNode(condition, limit, getSubNode( LOOP_DEFAULT_SUBNODE ));
240     };
241   }
242
243 ////////////////////////////////////////////////////////////////////////////////
244
245   public static class ListProducerNodeBuilder extends AbstractProducerNodeBuilder {
246     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
247     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
248     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
249     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
250     private final static String   LIST_DEFAULT_SUBNODE = "default";
251     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
252     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
253     private final static String[] LIST_REQUIRED_ATTRIBUTES = { LIST_KEY_ATTRIBUTE, LIST_DEFINITION_ATTRIBUTE };
254     private final static String[] LIST_OPTIONAL_ATTRIBUTES = { LIST_SELECTION_ATTRIBUTE, LIST_ORDER_ATTRIBUTE, LIST_SKIP_ATTRIBUTE, LIST_LIMIT_ATTRIBUTE};
255     private final static String[] LIST_SUBNODES = {};
256
257     private String key;
258     private String definition;
259     private String selection;
260     private String order;
261     private String limit;
262     private String skip;
263     private EntityAdapterModel model;
264
265     public ListProducerNodeBuilder(EntityAdapterModel aModel) {
266       super(LIST_SUBNODES);
267
268       model = aModel;
269     }
270
271     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
272       ReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
273
274       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
275       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
276       selection = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
277       order = (String) ReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
278       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
279       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
280     };
281
282     public ProducerNode constructNode() {
283       return new EntityListProducerNode(key, model, definition, selection, order, limit, skip, null );
284     };
285
286     public static class factory implements ProducerNodeBuilderFactory {
287       private EntityAdapterModel model;
288
289       public factory(EntityAdapterModel aModel) {
290         model = aModel;
291       }
292
293       public ProducerNodeBuilder makeBuilder() {
294         return new ListProducerNodeBuilder(model);
295       }
296     }
297   }
298
299 ////////////////////////////////////////////////////////////////////////////////
300
301   public static class LoggingProducerNodeBuilder extends AbstractProducerNodeBuilder {
302     private final static String   LOG_MESSAGE_ATTRIBUTE = "message";
303     private final static String[] LOG_REQUIRED_ATTRIBUTES = { LOG_MESSAGE_ATTRIBUTE };
304     private final static String[] LOG_OPTIONAL_ATTRIBUTES = {};
305     private final static String[] LOG_SUBNODES = {};
306
307     private String message;
308
309     public LoggingProducerNodeBuilder() {
310       super(LOG_SUBNODES);
311     }
312
313     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
314       ReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
315
316       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
317     };
318
319     public ProducerNode constructNode() {
320       return new LoggingProducerNode(message);
321     };
322   }
323
324 ////////////////////////////////////////////////////////////////////////////////
325
326   public static class ResourceBundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
327     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
328     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
329     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
330     private final static String   RESOURCEBUNDLE_DEFAULT_SUBNODE = "default";
331     private final static String[] RESOURCEBUNDLE_REQUIRED_ATTRIBUTES = { RESOURCEBUNDLE_KEY_ATTRIBUTE, RESOURCEBUNDLE_BUNDLE_ATTRIBUTE };
332     private final static String[] RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES = { RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE};
333     private final static String[] RESOURCEBUNDLE_SUBNODES = {};
334
335     private String key;
336     private String bundle;
337     private String language;
338
339     public ResourceBundleProducerNodeBuilder() {
340       super(RESOURCEBUNDLE_SUBNODES);
341     }
342
343     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
344       ReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
345
346       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
347       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
348       language = (String) anAttributes.get(RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE);
349     };
350
351     public ProducerNode constructNode() {
352       return new ResourceBundleProducerNode(key, bundle, language, null );
353     };
354   }
355
356 ////////////////////////////////////////////////////////////////////////////////
357
358   public static class FileDateSettingProducerNodeBuilder extends AbstractProducerNodeBuilder {
359     private final static String   FILEDATESETTING_FILE_ATTRIBUTE = "filename";
360     private final static String   FILEDATESETTING_DATE_ATTRIBUTE = "date";
361     private final static String[] FILEDATESETTING_REQUIRED_ATTRIBUTES = { FILEDATESETTING_FILE_ATTRIBUTE, FILEDATESETTING_DATE_ATTRIBUTE };
362     private final static String[] FILEDATESETTING_OPTIONAL_ATTRIBUTES = { };
363     private final static String[] FILEDATESETTING_SUBNODES = {};
364
365     private String fileNameKey;
366     private String dateKey;
367
368     public FileDateSettingProducerNodeBuilder() {
369       super(FILEDATESETTING_SUBNODES);
370     }
371
372     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
373       ReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
374
375       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
376       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
377     };
378
379     public ProducerNode constructNode() {
380       return new FileDateSettingProducerNode(fileNameKey, dateKey);
381     };
382   }
383
384 ////////////////////////////////////////////////////////////////////////////////
385
386   public static class FileDeletingProducerNodeBuilder extends AbstractProducerNodeBuilder {
387     private final static String   FILEDELETING_FILE_ATTRIBUTE = "filename";
388     private final static String[] FILEDELETING_REQUIRED_ATTRIBUTES = { FILEDELETING_FILE_ATTRIBUTE };
389     private final static String[] FILEDELETING_OPTIONAL_ATTRIBUTES = { };
390     private final static String[] FILEDELETING_SUBNODES = { };
391
392     private String fileNameKey;
393
394     public FileDeletingProducerNodeBuilder() {
395       super(FILEDELETING_SUBNODES);
396     }
397
398     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
399       ReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
400
401       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
402     };
403
404     public ProducerNode constructNode() {
405       return new FileDeletingProducerNode(fileNameKey);
406     };
407   }
408
409 ////////////////////////////////////////////////////////////////////////////////
410
411   public static class ScriptCallingProducerNodeBuilder extends AbstractProducerNodeBuilder {
412     private final static String   SCRIPT_COMMAND_ATTRIBUTE = "command";
413     private final static String[] SCRIPT_REQUIRED_ATTRIBUTES = { SCRIPT_COMMAND_ATTRIBUTE };
414     private final static String[] SCRIPT_OPTIONAL_ATTRIBUTES = {};
415     private final static String[] SCRIPT_SUBNODES = {};
416
417     private String command;
418
419     public ScriptCallingProducerNodeBuilder() {
420       super(SCRIPT_SUBNODES);
421     }
422
423     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
424       ReaderTool.checkAttributes(anAttributes, SCRIPT_REQUIRED_ATTRIBUTES, SCRIPT_OPTIONAL_ATTRIBUTES);
425
426       command = (String) anAttributes.get(SCRIPT_COMMAND_ATTRIBUTE);
427     };
428
429     public ProducerNode constructNode() {
430       return new ScriptCallingProducerNode(command);
431     };
432   }
433
434 ////////////////////////////////////////////////////////////////////////////////
435
436   public static class GeneratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
437     private final static String   GENERATION_GENERATOR_ATTRIBUTE = "generator";
438     private final static String   GENERATION_DESTINATION_ATTRIBUTE = "destination";
439     private final static String   GENERATION_PARAMETERS_ATTRIBUTE = "parameters";
440     private final static String[] GENERATION_REQUIRED_ATTRIBUTES = { GENERATION_GENERATOR_ATTRIBUTE, GENERATION_DESTINATION_ATTRIBUTE };
441     private final static String[] GENERATION_OPTIONAL_ATTRIBUTES = { GENERATION_PARAMETERS_ATTRIBUTE};
442     private final static String[] GENERATION_SUBNODES = {};
443
444     private String generator;
445     private String destination;
446     private String parameters;
447     private Generator.GeneratorLibrary generatorLibrary;
448     private WriterEngine writerEngine;
449
450     public GeneratingProducerNodeBuilder(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
451       super(GENERATION_SUBNODES);
452
453       writerEngine = aWriterEngine;
454       generatorLibrary = aGeneratorLibrary;
455     }
456
457     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
458       ReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
459
460       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
461       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
462       parameters = ReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
463     };
464
465     public ProducerNode constructNode() {
466       return new GeneratingProducerNode(generatorLibrary, writerEngine, generator, destination, parameters);
467     };
468
469     public static class factory implements ProducerNodeBuilderFactory {
470       private Generator.GeneratorLibrary generatorLibrary;
471       private WriterEngine writerEngine;
472
473       public factory(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
474         writerEngine = aWriterEngine;
475         generatorLibrary = aGeneratorLibrary;
476       }
477
478       public ProducerNodeBuilder makeBuilder() {
479         return new GeneratingProducerNodeBuilder(generatorLibrary, writerEngine);
480       }
481     }
482   }
483
484 ////////////////////////////////////////////////////////////////////////////////
485
486   public static class BatchingProducerNodeBuilder extends AbstractProducerNodeBuilder {
487
488     private final static String   BATCHER_DATAKEY_ATTRIBUTE = KEY_ATTRIBUTE;
489     private final static String   BATCHER_INFOKEY_ATTRIBUTE = "infokey";
490     private final static String   BATCHER_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
491     private final static String   BATCHER_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
492     private final static String   BATCHER_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
493
494     private final static String   BATCHER_BATCHSIZE_ATTRIBUTE = "batchsize";
495     private final static String   BATCHER_MINBATCHSIZE_ATTRIBUTE = "minbatchsize";
496     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
497
498     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
499
500     private final static String   BATCHER_BATCH_SUBNODE = "batches";
501     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
502     private final static String[] BATCHER_REQUIRED_ATTRIBUTES = { BATCHER_DATAKEY_ATTRIBUTE, BATCHER_INFOKEY_ATTRIBUTE, BATCHER_DEFINITION_ATTRIBUTE, BATCHER_BATCHSIZE_ATTRIBUTE };
503     private final static String[] BATCHER_OPTIONAL_ATTRIBUTES = { BATCHER_SELECTION_ATTRIBUTE, BATCHER_ORDER_ATTRIBUTE, BATCHER_MINBATCHSIZE_ATTRIBUTE, BATCHER_SKIP_ATTRIBUTE, BATCHER_PROCESS_ATTRIBUTE };
504     private final static String[] BATCHER_SUBNODES = { BATCHER_BATCH_SUBNODE, BATCHER_BATCHLIST_SUBNODE };
505
506     // ML: batchSize, minBatchSize, skip should be expressions!
507
508     private EntityAdapterModel model;
509     private String batchDataKey;
510     private String batchInfoKey;
511     private String definition;
512     private String selection;
513     private String order;
514     private String batchSize;
515     private String minBatchSize;
516     private String skip;
517     private String process;
518
519     public BatchingProducerNodeBuilder(EntityAdapterModel aModel) {
520       super(BATCHER_SUBNODES);
521
522       model = aModel;
523     }
524
525     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
526       ReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
527
528       batchDataKey = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
529       batchInfoKey = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
530       definition = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
531       selection = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
532       order = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
533
534       batchSize = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
535       minBatchSize = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
536       skip = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
537       process = ReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
538     };
539
540     public ProducerNode constructNode() {
541       return new EntityBatchingProducerNode(
542           batchDataKey,
543           batchInfoKey,
544           model,
545           definition,
546           selection,
547           order,
548           batchSize,
549           minBatchSize,
550           skip,
551           process,
552           getSubNode( BATCHER_BATCH_SUBNODE ),
553           getSubNode( BATCHER_BATCHLIST_SUBNODE )
554       );
555     };
556
557     public static class factory implements ProducerNodeBuilderFactory {
558       private EntityAdapterModel model;
559
560       public factory(EntityAdapterModel aModel) {
561         model = aModel;
562       }
563
564       public ProducerNodeBuilder makeBuilder() {
565         return new BatchingProducerNodeBuilder(model);
566       }
567     }
568   }
569
570 ////////////////////////////////////////////////////////////////////////////////
571
572   public static class ConditionalProducerNodeBuilder extends AbstractProducerNodeBuilder {
573     private final static String   IF_CONDITION_ATTRIBUTE = "condition";
574
575     private final static String   IF_TRUE_SUBNODE = "then";
576     private final static String   IF_FALSE_SUBNODE = "else";
577     private final static String[] IF_REQUIRED_ATTRIBUTES = { IF_CONDITION_ATTRIBUTE };
578     private final static String[] IF_OPTIONAL_ATTRIBUTES = {  };
579     private final static String[] IF_SUBNODES = { IF_TRUE_SUBNODE, IF_FALSE_SUBNODE };
580
581     private String condition;
582
583     public ConditionalProducerNodeBuilder() {
584       super(IF_SUBNODES);
585     }
586
587     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
588       ReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
589
590       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
591     };
592
593     public ProducerNode constructNode() {
594       return new ConditionalProducerNode(
595           condition,
596           getSubNode( IF_TRUE_SUBNODE ),
597           getSubNode( IF_FALSE_SUBNODE )
598       );
599     };
600
601   }
602
603 ////////////////////////////////////////////////////////////////////////////////
604
605   public static class ScriptedProducerParameterNodeBuilder implements ProducerNodeBuilder {
606     private String parameterName;
607     private String scriptedNodeName;
608
609     public ScriptedProducerParameterNodeBuilder(String aScriptedNodeName, String aParameterName) {
610       parameterName = aParameterName;
611       scriptedNodeName = aScriptedNodeName;
612     }
613
614     public void setSubNode(String aName, ProducerNode aNode) {
615     };
616
617     public Set getAvailableSubNodes() {
618       return new HashSet();
619     };
620
621     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
622       if (!anAttributes.isEmpty())
623         throw new ProducerConfigExc("No parameters allowed here");
624     };
625
626     public ProducerNode constructNode() {
627       return new ScriptedProducerNodeDefinition.NodeParameterProducerNode(scriptedNodeName, parameterName);
628     };
629   }
630
631 ////////////////////////////////////////////////////////////////////////////////
632
633   public static class ScriptedProducerNodeBuilder implements ProducerNodeBuilder {
634     private ScriptedProducerNodeDefinition definition;
635     private Map nodeParameterValues;
636     private Map integerParameterValues;
637     private Map stringParameterValues;
638
639     public ScriptedProducerNodeBuilder(ScriptedProducerNodeDefinition aDefinition) {
640       definition = aDefinition;
641
642       stringParameterValues = new HashMap();
643       stringParameterValues.putAll(definition.getStringParameters());
644
645       integerParameterValues = new HashMap();
646       integerParameterValues.putAll(definition.getIntegerParameters());
647
648       nodeParameterValues = new HashMap();
649     }
650
651     public void setSubNode(String aName, ProducerNode aNode) {
652       nodeParameterValues.put(aName, aNode);
653     };
654
655     public Set getAvailableSubNodes() {
656       return definition.getNodeParameters();
657     };
658
659     public void setAttributes(Map anAttributes) throws ProducerConfigExc {
660       ReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
661
662       Iterator i = anAttributes.entrySet().iterator();
663       while (i.hasNext()) {
664         Map.Entry entry = (Map.Entry) i.next();
665
666         if (definition.getIntegerParameters().keySet().contains(entry.getKey()))
667             integerParameterValues.put(entry.getKey(), entry.getValue());
668         else
669             stringParameterValues.put(entry.getKey(), entry.getValue());
670       }
671     };
672
673     public ProducerNode constructNode() {
674       return new ScriptedProducerNode(definition, stringParameterValues, integerParameterValues, nodeParameterValues);
675     };
676
677     public static class factory implements ProducerNodeBuilderFactory {
678       private ScriptedProducerNodeDefinition definition;
679
680       public factory(ScriptedProducerNodeDefinition aDefinition) {
681         definition = aDefinition;
682       }
683
684       public ProducerNodeBuilder makeBuilder() {
685         return new ScriptedProducerNodeBuilder(definition);
686       }
687     }
688   }
689 }