2de7d063c2b39a5b37760f30628acaf874ba7e38
[mir.git] / source / mir / producer / reader / ProducerConfigReader.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.io.File;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.Vector;
40
41 import mir.producer.CompositeProducerNode;
42 import mir.producer.ProducerFactory;
43 import mir.producer.ProducerNode;
44 import mir.producer.SimpleProducerVerb;
45 import mir.util.XMLReader;
46 import mir.util.XMLReaderTool;
47
48 public class ProducerConfigReader {
49   private ProducerNodeBuilderLibrary builderLibrary;
50   private ProducerNodeBuilderLibrary scriptedNodeBuilderLibrary;
51
52   public ProducerConfigReader() {
53     super();
54   };
55
56   public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories) throws ProducerConfigFailure {
57     parseFile(aFileName, aBuilderLibrary, aProducerFactories, new Vector());
58   }
59
60   public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories, List aUsedFiles) throws ProducerConfigFailure {
61     try {
62       XMLReader reader = new XMLReader();
63       aUsedFiles.add(new File(aFileName));
64
65       builderLibrary = aBuilderLibrary;
66       scriptedNodeBuilderLibrary = new ProducerNodeBuilderLibrary();
67
68       reader.parseFile(aFileName, new RootSectionHandler(aProducerFactories));
69
70     }
71     catch (Throwable e) {
72       if ((e instanceof XMLReader.XMLReaderExc) && ((XMLReader.XMLReaderExc) e).getHasLocation()) {
73         XMLReader.XMLReaderExc f = (XMLReader.XMLReaderExc) e;
74         throw new ProducerConfigFailure("'" + f.getMessage()+"' in " + f.getFilename()+"(line " + f.getLineNr()+", column " + f.getColumnNr() + ")", e);
75       }
76       throw new ProducerConfigFailure( e );
77     }
78   }
79
80
81   public class RootSectionHandler extends XMLReader.AbstractSectionHandler {
82     private List producers;
83
84     public RootSectionHandler(List aProducers) {
85       producers = aProducers;
86     }
87
88     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
89       if (aTag.equals("producers")) {
90         return new ProducersSectionHandler(producers);
91       }
92       else
93         throw new XMLReader.XMLReaderExc("Tag 'producers' expected, tag '"+aTag+"' found");
94     }
95
96     public void endElement(XMLReader.SectionHandler aHandler) {
97     }
98
99     public void finishSection() {
100     }
101   }
102
103
104   private final static String   PRODUCER_NAME_ATTRIBUTE = "name";
105   private final static String[] PRODUCER_REQUIRED_ATTRIBUTES = { PRODUCER_NAME_ATTRIBUTE };
106   private final static String[] PRODUCER_OPTIONAL_ATTRIBUTES = { };
107
108   private final static String   NODE_DEFINITION_NAME_ATTRIBUTE = "name";
109   private final static String[] NODE_DEFINITION_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_NAME_ATTRIBUTE };
110   private final static String[] NODE_DEFINITION_OPTIONAL_ATTRIBUTES = {  };
111
112   public class ProducersSectionHandler extends XMLReader.AbstractSectionHandler {
113     private List producers;
114     private Set producerNames;
115     private String name;
116
117     public ProducersSectionHandler(List aProducers) {
118       producers = aProducers;
119       producerNames = new HashSet();
120     }
121
122     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
123       if (aTag.equals("producer")) {
124         XMLReaderTool.checkAttributes(anAttributes,
125                                       PRODUCER_REQUIRED_ATTRIBUTES,
126                                       PRODUCER_OPTIONAL_ATTRIBUTES);
127
128         name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
129         XMLReaderTool.checkValidIdentifier(name);
130
131         if (producerNames.contains(name))
132           throw new XMLReader.XMLReaderExc("Duplicate producer name: '" +
133                                            name + "'");
134
135         name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
136
137         return new ProducerSectionHandler(name);
138       }
139       else if (aTag.equals("nodedefinition")) {
140         XMLReaderTool.checkAttributes(anAttributes,
141                                       NODE_DEFINITION_REQUIRED_ATTRIBUTES,
142                                       NODE_DEFINITION_OPTIONAL_ATTRIBUTES);
143
144         name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
145         XMLReaderTool.checkValidIdentifier(name);
146
147         name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
148
149         return new NodeDefinitionSectionHandler(name);
150       }
151       throw new XMLReader.XMLReaderExc("Unexpected tag: " + aTag);
152     }
153
154     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
155       if (aHandler instanceof ProducerSectionHandler) {
156         producers.add(((ProducerSectionHandler) aHandler).getProducerFactory());
157         producerNames.add(((ProducerSectionHandler) aHandler).getProducerFactory().getName());
158       }
159       else if (aHandler instanceof NodeDefinitionSectionHandler) {
160         scriptedNodeBuilderLibrary.registerFactory(name,
161             new DefaultProducerNodeBuilders.ScriptedProducerNodeBuilder.factory(
162                 ((NodeDefinitionSectionHandler) aHandler).getDefinition()));
163       }
164       else throw new XMLReader.XMLReaderExc("ProducersSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
165     }
166
167     public void finishSection() {
168     }
169   }
170
171   public class ProducerSectionHandler extends XMLReader.AbstractSectionHandler {
172     private ProducerFactory producerFactory;
173     private String factoryName;
174
175     private ProducerNode body;
176     private Map verbNodes;
177     private List verbs;
178     private String defaultVerb;
179
180     public ProducerSectionHandler(String aName) {
181       factoryName = aName;
182     }
183
184     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
185       if (aTag.equals("verbs")) {
186         if (verbs!=null)
187           throw new XMLReader.XMLReaderExc("Verbs already processed");
188         if (body!=null)
189           throw new XMLReader.XMLReaderExc("Verbs should come before body");
190         else
191           return new ProducerVerbsSectionHandler();
192       }
193       else if (aTag.equals("body")) {
194         if (body==null)
195           return new ProducerNodeSectionHandler();
196         else
197           throw new XMLReader.XMLReaderExc("Body already processed");
198       }
199       throw new XMLReader.XMLReaderExc("Unexpected tag: '"+aTag+"'");
200     }
201
202     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
203       if (aHandler instanceof ProducerNodeSectionHandler) {
204         body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
205       }
206       else if (aHandler instanceof ProducerVerbsSectionHandler)
207       {
208         verbs = ((ProducerVerbsSectionHandler) aHandler).getVerbs();
209         verbNodes = ((ProducerVerbsSectionHandler) aHandler).getVerbNodes();
210         defaultVerb = ((ProducerVerbsSectionHandler) aHandler).getDefaultVerb();
211       }
212       else throw new XMLReader.XMLReaderExc("ProducerSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
213     }
214
215     public void finishSection() throws XMLReader.XMLReaderExc {
216       if (verbs==null)
217         throw new XMLReader.XMLReaderExc("No verbs defined");
218
219       if (body==null)
220         throw new XMLReader.XMLReaderExc("No body defined");
221
222       producerFactory = new ScriptedProducerFactory(factoryName, verbs, verbNodes, body, defaultVerb);
223     }
224
225     public ProducerFactory getProducerFactory() {
226       return producerFactory;
227     }
228   }
229
230   private final static String   PRODUCER_VERB_NAME_ATTRIBUTE = "name";
231   private final static String   PRODUCER_VERB_DESCRIPTION_ATTRIBUTE = "description";
232   private final static String   PRODUCER_VERB_DEFAULT_ATTRIBUTE = "default";
233   private final static String[] PRODUCER_VERB_REQUIRED_ATTRIBUTES = { PRODUCER_VERB_NAME_ATTRIBUTE };
234   private final static String[] PRODUCER_VERB_OPTIONAL_ATTRIBUTES = { PRODUCER_VERB_DEFAULT_ATTRIBUTE, PRODUCER_VERB_DESCRIPTION_ATTRIBUTE };
235
236   public class ProducerVerbsSectionHandler extends XMLReader.AbstractSectionHandler {
237     private Map verbNodes;
238     private List verbs;
239     private String defaultVerb;
240     private String currentVerb;
241     private String currentVerbDescription;
242
243     public ProducerVerbsSectionHandler() {
244       verbNodes = new HashMap();
245       verbs = new Vector();
246       defaultVerb = null;
247     }
248
249     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
250       if (aTag.equals("verb")) {
251         XMLReaderTool.checkAttributes(anAttributes,
252                                       PRODUCER_VERB_REQUIRED_ATTRIBUTES,
253                                       PRODUCER_VERB_OPTIONAL_ATTRIBUTES);
254         currentVerb = (String) anAttributes.get(PRODUCER_VERB_NAME_ATTRIBUTE);
255
256         XMLReaderTool.checkValidIdentifier(currentVerb);
257
258         if (verbNodes.containsKey(currentVerb))
259           throw new XMLReader.XMLReaderExc("Duplicate definition of verb '" +
260                                            currentVerb + "'");
261
262         if (anAttributes.containsKey(PRODUCER_VERB_DEFAULT_ATTRIBUTE)) {
263           if (defaultVerb != null)
264             throw new XMLReader.XMLReaderExc("Default verb already declared");
265
266           defaultVerb = currentVerb;
267         }
268
269         if (anAttributes.containsKey(PRODUCER_VERB_DESCRIPTION_ATTRIBUTE))
270           currentVerbDescription = (String) anAttributes.get(
271               PRODUCER_VERB_DESCRIPTION_ATTRIBUTE);
272         else
273           currentVerbDescription = "";
274
275         return new ProducerNodeSectionHandler();
276       }
277       else
278         throw new XMLReader.XMLReaderExc("Only 'verb' tags allowed here, '" + aTag + "' encountered.");
279     }
280
281     public void endElement(XMLReader.SectionHandler aHandler) {
282       verbNodes.put(currentVerb, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
283       verbs.add(new SimpleProducerVerb(currentVerb, currentVerbDescription));
284     }
285
286     public void finishSection() {
287     }
288
289     public String getDefaultVerb() {
290       return defaultVerb;
291     }
292
293     public List getVerbs() {
294       return verbs;
295     }
296
297     public Map getVerbNodes() {
298       return verbNodes;
299     }
300   }
301
302   public class EmptySectionHandler extends XMLReader.AbstractSectionHandler {
303     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
304       throw new XMLReader.XMLReaderExc("No tags are allowed here");
305     }
306
307     public void endElement(XMLReader.SectionHandler aHandler) {
308     }
309
310     public void finishSection() {
311     }
312   }
313
314   public class MultiProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
315     private Map nodeParameters;
316     private Set validNodeParameters;
317     private String currentNodeParameter;
318     private String scriptedNodeName;
319     private Set allowedNodeParameterReferences;
320
321     public MultiProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences, Set aValidNodeParameters) {
322       allowedNodeParameterReferences = anAllowedNodeParameterReferences;
323       scriptedNodeName = aScriptedNodeName;
324       validNodeParameters = aValidNodeParameters;
325       nodeParameters = new HashMap();
326     }
327     public MultiProducerNodeSectionHandler(Set aValidNodeParameters) {
328       this("", new HashSet(), aValidNodeParameters);
329     }
330
331     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
332       if (!validNodeParameters.contains(aTag))
333         throw new XMLReader.XMLReaderExc("Invalid node parameter: '" + aTag + "'");
334       else if (nodeParameters.containsKey(aTag))
335         throw new XMLReader.XMLReaderExc("Node parameter: '" + aTag + "' already specified");
336       else if (anAttributes.size()>0)
337         throw new XMLReader.XMLReaderExc("No parameters are allowed here");
338
339       currentNodeParameter = aTag;
340
341       return new ProducerNodeSectionHandler(scriptedNodeName, allowedNodeParameterReferences);
342     }
343
344     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc  {
345       if (aHandler instanceof ProducerNodeSectionHandler) {
346         nodeParameters.put(currentNodeParameter, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
347       }
348       else {
349         throw new XMLReader.XMLReaderExc("Internal error: unknown section handler '" + aHandler.getClass().getName() + "'" );
350       }
351     }
352
353     public Map getNodeParameters() {
354       return nodeParameters;
355     }
356
357     public void finishSection() {
358     }
359   }
360
361   public class ProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
362     private CompositeProducerNode producerNode;
363     private ProducerNodeBuilder currentBuilder;
364     private String scriptedNodeName;
365     private Set allowedNodeParameterReferences;
366
367     public ProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences) {
368       producerNode = new CompositeProducerNode();
369       scriptedNodeName = aScriptedNodeName;
370       allowedNodeParameterReferences = anAllowedNodeParameterReferences;
371     }
372
373     public ProducerNodeSectionHandler() {
374       this("", new HashSet());
375     }
376
377     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
378       try {
379         if (allowedNodeParameterReferences.contains( (aTag))) {
380           if (!anAttributes.isEmpty()) {
381             throw new XMLReader.XMLReaderExc("No attributes allowed");
382           }
383
384           currentBuilder = new DefaultProducerNodeBuilders.
385               ScriptedProducerParameterNodeBuilder(scriptedNodeName, aTag);
386           return new EmptySectionHandler();
387         }
388         else if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag) ||
389                  builderLibrary.hasBuilderForName( (aTag))) {
390
391           if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag))
392             currentBuilder = scriptedNodeBuilderLibrary.constructBuilder(aTag);
393           else
394             currentBuilder = builderLibrary.constructBuilder(aTag);
395
396           currentBuilder.setAttributes(anAttributes);
397           if (currentBuilder.getAvailableSubNodes().isEmpty()) {
398             return new EmptySectionHandler();
399           }
400           if (currentBuilder.getAvailableSubNodes().size() > 1)
401             return new MultiProducerNodeSectionHandler(scriptedNodeName,
402                 allowedNodeParameterReferences,
403                 currentBuilder.getAvailableSubNodes());
404           else if (currentBuilder.getAvailableSubNodes().size() < 1)
405             return new EmptySectionHandler();
406           else {
407             return new ProducerNodeSectionHandler(scriptedNodeName,
408                 allowedNodeParameterReferences);
409           }
410         }
411         else
412           throw new XMLReader.XMLReaderExc("Unknown producer node tag: '" +
413                                            aTag + "'");
414       }
415       catch (Throwable t) {
416         throw new XMLReader.XMLReaderFailure(t);
417       }
418     }
419
420     public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc  {
421       try {
422         if (aHandler instanceof ProducerNodeSectionHandler) {
423           currentBuilder.setSubNode(
424                 (String) (currentBuilder.getAvailableSubNodes().iterator().next()),
425                 ((ProducerNodeSectionHandler) aHandler).getProducerNode());
426         }
427         else if (aHandler instanceof MultiProducerNodeSectionHandler) {
428           Iterator i;
429           Map nodeParameters;
430           Map.Entry entry;
431
432           nodeParameters = ( (MultiProducerNodeSectionHandler) aHandler).
433               getNodeParameters();
434           i = nodeParameters.entrySet().iterator();
435           while (i.hasNext()) {
436             entry = (Map.Entry) i.next();
437             currentBuilder.setSubNode( (String) entry.getKey(),
438                                       (ProducerNode) entry.getValue());
439           }
440         }
441         else if (aHandler instanceof EmptySectionHandler) {
442           // deliberately empty: nothing expected, so nothing to process
443         }
444         else {
445           throw new XMLReader.XMLReaderExc(
446               "Internal error: unknown section handler '" +
447               aHandler.getClass().getName() + "'");
448         }
449
450         producerNode.addSubNode(currentBuilder.constructNode());
451         currentBuilder = null;
452       }
453       catch (Throwable t) {
454         throw new XMLReader.XMLReaderFailure(t);
455       }
456     }
457
458     public ProducerNode getProducerNode() {
459       if (producerNode.getNrSubNodes()==1) {
460         return producerNode.getSubNode(0);
461       }
462       else {
463         return producerNode;
464       }
465     }
466
467     public void finishSection() {
468     }
469   }
470
471   public class NodeDefinitionSectionHandler extends XMLReader.AbstractSectionHandler {
472     private ScriptedProducerNodeDefinition nodeDefinition;
473     private ProducerNode body;
474     private Map stringParameters;
475     private Map integerParameters;
476     private Map nodeParameters;
477     private String name;
478
479     public NodeDefinitionSectionHandler(String aName) {
480       body = null;
481       nodeParameters = null;
482       stringParameters = null;
483       integerParameters = null;
484       name = aName;
485     }
486
487     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
488       if (aTag.equals("parameters")) {
489         if (!anAttributes.isEmpty()) {
490           throw new XMLReader.XMLReaderExc( "No attributes allowed for tag 'parameters'" );
491         }
492         if (nodeParameters!=null) {
493           throw new XMLReader.XMLReaderExc( "Parameters have already been declared" );
494         }
495         if (body!=null) {
496           throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
497         }
498
499         return new NodeDefinitionParametersSectionHandler();
500       }
501       else if (aTag.equals("definition")) {
502         if (nodeParameters==null)
503           throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'"  );
504
505         return new ProducerNodeSectionHandler(name, nodeParameters.keySet());
506       }
507       else throw new XMLReader.XMLReaderExc("Only 'definition' or 'parameters' tags allowed here, '" + aTag + "' encountered.");
508     }
509
510     public void endElement(XMLReader.SectionHandler aHandler) {
511       if (aHandler instanceof NodeDefinitionParametersSectionHandler) {
512         stringParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getStringParameters();
513         integerParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getIntegerParameters();
514         nodeParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getNodeParameters();
515       }
516       else if (aHandler instanceof ProducerNodeSectionHandler) {
517         body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
518       }
519     }
520
521     public void finishSection() throws XMLReader.XMLReaderExc {
522       Iterator i;
523       if (body == null)
524         throw new XMLReader.XMLReaderExc( "Definition missing" );
525
526       nodeDefinition = new ScriptedProducerNodeDefinition(name);
527
528       nodeDefinition.setBody(body);
529
530       i = nodeParameters.keySet().iterator();
531       while (i.hasNext()) {
532         nodeDefinition.addNodeParameter((String) i.next());
533       }
534
535       i = stringParameters.entrySet().iterator();
536       while (i.hasNext()) {
537         Map.Entry entry = (Map.Entry) i.next();
538         nodeDefinition.addStringParameter((String) entry.getKey(), (String) entry.getValue());
539       }
540
541       i = integerParameters.entrySet().iterator();
542       while (i.hasNext()) {
543         Map.Entry entry = (Map.Entry) i.next();
544         nodeDefinition.addIntegerParameter((String) entry.getKey(), (String) entry.getValue());
545       }
546     }
547
548     public ScriptedProducerNodeDefinition getDefinition() {
549       return nodeDefinition;
550     }
551   }
552
553   private final static String   NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE = "name";
554   private final static String   NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE = "defaultvalue";
555   private final static String[] NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE };
556   private final static String[] NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE };
557   private final static String[] NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES = { };
558
559   public class NodeDefinitionParametersSectionHandler extends XMLReader.AbstractSectionHandler {
560     private Map nodeParameters;
561     private Map stringParameters;
562     private Map integerParameters;
563
564     public NodeDefinitionParametersSectionHandler() {
565       nodeParameters = new HashMap();
566       stringParameters = new HashMap();
567       integerParameters = new HashMap();
568     }
569
570     public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
571       String parameterName;
572       String defaultValue;
573
574       if (aTag.equals("node")) {
575         XMLReaderTool.checkAttributes(anAttributes,
576             NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
577             NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES);
578         parameterName = (String) anAttributes.get(
579             NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
580
581         if (nodeParameters.containsKey(parameterName))
582           throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
583                                            parameterName + "'");
584
585         XMLReaderTool.checkValidIdentifier(parameterName);
586
587         nodeParameters.put(parameterName, parameterName);
588
589         return new EmptySectionHandler();
590       }
591       else if (aTag.equals("string") || aTag.equals("integer")) {
592         XMLReaderTool.checkAttributes(anAttributes,
593             NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
594             NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES);
595         parameterName = (String) anAttributes.get(
596             NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
597
598         if (stringParameters.containsKey(parameterName) ||
599             integerParameters.containsKey(parameterName))
600           throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
601                                            parameterName + "'");
602
603         XMLReaderTool.checkValidIdentifier(parameterName);
604
605         defaultValue = (String) anAttributes.get(
606             NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE);
607
608         if (aTag.equals("string"))
609           stringParameters.put(parameterName, defaultValue);
610         else
611           integerParameters.put(parameterName, defaultValue);
612
613         return new EmptySectionHandler();
614       }
615       else
616         throw new XMLReader.XMLReaderExc(
617             "Only 'string', 'integer' and 'node' tags allowed here, '" + aTag + "' encountered.");
618     }
619
620     public void endElement(XMLReader.SectionHandler aHandler) {
621     }
622
623     public void finishSection() {
624     }
625
626     public Map getNodeParameters() {
627       return nodeParameters;
628     }
629
630     public Map getStringParameters() {
631       return stringParameters;
632     }
633
634     public Map getIntegerParameters() {
635       return integerParameters;
636     }
637   }
638 }