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