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