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