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