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