2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
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.
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.
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
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.
30 package mir.producer.reader;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
39 import java.util.Vector;
41 import mir.producer.CompositeProducerNode;
42 import mir.producer.ProducerFactory;
43 import mir.producer.ProducerNode;
44 import mir.producer.SimpleProducerVerb;
45 import mir.util.XMLReader;
48 public class ProducerConfigReader {
49 private ProducerNodeBuilderLibrary builderLibrary;
50 private ProducerNodeBuilderLibrary scriptedNodeBuilderLibrary;
52 public ProducerConfigReader() {
56 public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories) throws ProducerConfigFailure {
57 parseFile(aFileName, aBuilderLibrary, aProducerFactories, new Vector());
60 public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories, List aUsedFiles) throws ProducerConfigFailure {
62 XMLReader reader = new XMLReader();
63 aUsedFiles.add(new File(aFileName));
65 builderLibrary = aBuilderLibrary;
66 scriptedNodeBuilderLibrary = new ProducerNodeBuilderLibrary();
68 reader.parseFile(aFileName, new RootSectionHandler(aProducerFactories));
72 Throwable root = ExceptionFunctions.traceCauseException(e);
74 if ((root instanceof XMLReader.XMLReaderExc) && ((XMLReader.XMLReaderExc) root).getHasLocation()) {
75 XMLReader.XMLReaderExc f = (XMLReader.XMLReaderExc) root;
76 throw new ProducerConfigFailure("'" + f.getMessage()+"' in " + f.getFilename()+"(line " + f.getLineNr()+", column " + f.getColumnNr() + ")", e);
78 throw new ProducerConfigFailure(root);
83 public class RootSectionHandler extends XMLReader.AbstractSectionHandler {
84 private List producers;
86 public RootSectionHandler(List aProducers) {
87 producers = aProducers;
90 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
91 if (aTag.equals("producers")) {
92 return new ProducersSectionHandler(producers);
95 throw new XMLReader.XMLReaderExc("Tag 'producers' expected, tag '"+aTag+"' found");
98 public void endElement(XMLReader.SectionHandler aHandler) {
101 public void finishSection() {
106 private final static String PRODUCER_NAME_ATTRIBUTE = "name";
107 private final static String[] PRODUCER_REQUIRED_ATTRIBUTES = { PRODUCER_NAME_ATTRIBUTE };
108 private final static String[] PRODUCER_OPTIONAL_ATTRIBUTES = { };
110 private final static String NODE_DEFINITION_NAME_ATTRIBUTE = "name";
111 private final static String[] NODE_DEFINITION_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_NAME_ATTRIBUTE };
112 private final static String[] NODE_DEFINITION_OPTIONAL_ATTRIBUTES = { };
114 public class ProducersSectionHandler extends XMLReader.AbstractSectionHandler {
115 private List producers;
116 private Set producerNames;
119 public ProducersSectionHandler(List aProducers) {
120 producers = aProducers;
121 producerNames = new HashSet();
124 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
125 if (aTag.equals("producer")) {
126 XMLReaderTool.checkAttributes(anAttributes,
127 PRODUCER_REQUIRED_ATTRIBUTES,
128 PRODUCER_OPTIONAL_ATTRIBUTES);
130 name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
131 XMLReaderTool.checkValidIdentifier(name);
133 if (producerNames.contains(name))
134 throw new XMLReader.XMLReaderExc("Duplicate producer name: '" +
137 name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
139 return new ProducerSectionHandler(name);
141 else if (aTag.equals("nodedefinition")) {
142 XMLReaderTool.checkAttributes(anAttributes,
143 NODE_DEFINITION_REQUIRED_ATTRIBUTES,
144 NODE_DEFINITION_OPTIONAL_ATTRIBUTES);
146 name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
147 XMLReaderTool.checkValidIdentifier(name);
149 name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
151 return new NodeDefinitionSectionHandler(name);
153 throw new XMLReader.XMLReaderExc("Unexpected tag: " + aTag);
156 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
157 if (aHandler instanceof ProducerSectionHandler) {
158 producers.add(((ProducerSectionHandler) aHandler).getProducerFactory());
159 producerNames.add(((ProducerSectionHandler) aHandler).getProducerFactory().getName());
161 else if (aHandler instanceof NodeDefinitionSectionHandler) {
162 scriptedNodeBuilderLibrary.registerFactory(name,
163 new DefaultProducerNodeBuilders.ScriptedProducerNodeBuilder.factory(
164 ((NodeDefinitionSectionHandler) aHandler).getDefinition()));
166 else throw new XMLReader.XMLReaderExc("ProducersSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
169 public void finishSection() {
173 public class ProducerSectionHandler extends XMLReader.AbstractSectionHandler {
174 private ProducerFactory producerFactory;
175 private String factoryName;
177 private ProducerNode body;
178 private Map verbNodes;
180 private String defaultVerb;
182 public ProducerSectionHandler(String aName) {
186 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
187 if (aTag.equals("verbs")) {
189 throw new XMLReader.XMLReaderExc("Verbs already processed");
191 throw new XMLReader.XMLReaderExc("Verbs should come before body");
193 return new ProducerVerbsSectionHandler();
195 else if (aTag.equals("body")) {
197 return new ProducerNodeSectionHandler();
199 throw new XMLReader.XMLReaderExc("Body already processed");
201 throw new XMLReader.XMLReaderExc("Unexpected tag: '"+aTag+"'");
204 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
205 if (aHandler instanceof ProducerNodeSectionHandler) {
206 body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
208 else if (aHandler instanceof ProducerVerbsSectionHandler)
210 verbs = ((ProducerVerbsSectionHandler) aHandler).getVerbs();
211 verbNodes = ((ProducerVerbsSectionHandler) aHandler).getVerbNodes();
212 defaultVerb = ((ProducerVerbsSectionHandler) aHandler).getDefaultVerb();
214 else throw new XMLReader.XMLReaderExc("ProducerSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
217 public void finishSection() throws XMLReader.XMLReaderExc {
219 throw new XMLReader.XMLReaderExc("No verbs defined");
222 throw new XMLReader.XMLReaderExc("No body defined");
224 producerFactory = new ScriptedProducerFactory(factoryName, verbs, verbNodes, body, defaultVerb);
227 public ProducerFactory getProducerFactory() {
228 return producerFactory;
232 private final static String PRODUCER_VERB_NAME_ATTRIBUTE = "name";
233 private final static String PRODUCER_VERB_DESCRIPTION_ATTRIBUTE = "description";
234 private final static String PRODUCER_VERB_DEFAULT_ATTRIBUTE = "default";
235 private final static String[] PRODUCER_VERB_REQUIRED_ATTRIBUTES = { PRODUCER_VERB_NAME_ATTRIBUTE };
236 private final static String[] PRODUCER_VERB_OPTIONAL_ATTRIBUTES = { PRODUCER_VERB_DEFAULT_ATTRIBUTE, PRODUCER_VERB_DESCRIPTION_ATTRIBUTE };
238 public class ProducerVerbsSectionHandler extends XMLReader.AbstractSectionHandler {
239 private Map verbNodes;
241 private String defaultVerb;
242 private String currentVerb;
243 private String currentVerbDescription;
245 public ProducerVerbsSectionHandler() {
246 verbNodes = new HashMap();
247 verbs = new Vector();
251 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
252 if (aTag.equals("verb")) {
253 XMLReaderTool.checkAttributes(anAttributes,
254 PRODUCER_VERB_REQUIRED_ATTRIBUTES,
255 PRODUCER_VERB_OPTIONAL_ATTRIBUTES);
256 currentVerb = (String) anAttributes.get(PRODUCER_VERB_NAME_ATTRIBUTE);
258 XMLReaderTool.checkValidIdentifier(currentVerb);
260 if (verbNodes.containsKey(currentVerb))
261 throw new XMLReader.XMLReaderExc("Duplicate definition of verb '" +
264 if (anAttributes.containsKey(PRODUCER_VERB_DEFAULT_ATTRIBUTE)) {
265 if (defaultVerb != null)
266 throw new XMLReader.XMLReaderExc("Default verb already declared");
268 defaultVerb = currentVerb;
271 if (anAttributes.containsKey(PRODUCER_VERB_DESCRIPTION_ATTRIBUTE))
272 currentVerbDescription = (String) anAttributes.get(
273 PRODUCER_VERB_DESCRIPTION_ATTRIBUTE);
275 currentVerbDescription = "";
277 return new ProducerNodeSectionHandler();
280 throw new XMLReader.XMLReaderExc("Only 'verb' tags allowed here, '" + aTag + "' encountered.");
283 public void endElement(XMLReader.SectionHandler aHandler) {
284 verbNodes.put(currentVerb, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
285 verbs.add(new SimpleProducerVerb(currentVerb, currentVerbDescription));
288 public void finishSection() {
291 public String getDefaultVerb() {
295 public List getVerbs() {
299 public Map getVerbNodes() {
304 public class EmptySectionHandler extends XMLReader.AbstractSectionHandler {
305 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
306 throw new XMLReader.XMLReaderExc("No tags are allowed here");
309 public void endElement(XMLReader.SectionHandler aHandler) {
312 public void finishSection() {
316 public class MultiProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
317 private Map nodeParameters;
318 private Set validNodeParameters;
319 private String currentNodeParameter;
320 private String scriptedNodeName;
321 private Set allowedNodeParameterReferences;
323 public MultiProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences, Set aValidNodeParameters) {
324 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
325 scriptedNodeName = aScriptedNodeName;
326 validNodeParameters = aValidNodeParameters;
327 nodeParameters = new HashMap();
329 public MultiProducerNodeSectionHandler(Set aValidNodeParameters) {
330 this("", new HashSet(), aValidNodeParameters);
333 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
334 if (!validNodeParameters.contains(aTag))
335 throw new XMLReader.XMLReaderExc("Invalid node parameter: '" + aTag + "'");
336 else if (nodeParameters.containsKey(aTag))
337 throw new XMLReader.XMLReaderExc("Node parameter: '" + aTag + "' already specified");
338 else if (anAttributes.size()>0)
339 throw new XMLReader.XMLReaderExc("No parameters are allowed here");
341 currentNodeParameter = aTag;
343 return new ProducerNodeSectionHandler(scriptedNodeName, allowedNodeParameterReferences);
346 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
347 if (aHandler instanceof ProducerNodeSectionHandler) {
348 nodeParameters.put(currentNodeParameter, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
351 throw new XMLReader.XMLReaderExc("Internal error: unknown section handler '" + aHandler.getClass().getName() + "'" );
355 public Map getNodeParameters() {
356 return nodeParameters;
359 public void finishSection() {
363 public class ProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
364 private CompositeProducerNode producerNode;
365 private ProducerNodeBuilder currentBuilder;
366 private String scriptedNodeName;
367 private Set allowedNodeParameterReferences;
369 public ProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences) {
370 producerNode = new CompositeProducerNode();
371 scriptedNodeName = aScriptedNodeName;
372 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
375 public ProducerNodeSectionHandler() {
376 this("", new HashSet());
379 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
381 if (allowedNodeParameterReferences.contains( (aTag))) {
382 if (!anAttributes.isEmpty()) {
383 throw new XMLReader.XMLReaderExc("No attributes allowed");
386 currentBuilder = new DefaultProducerNodeBuilders.
387 ScriptedProducerParameterNodeBuilder(scriptedNodeName, aTag);
388 return new EmptySectionHandler();
390 else if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag) ||
391 builderLibrary.hasBuilderForName( (aTag))) {
393 if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag))
394 currentBuilder = scriptedNodeBuilderLibrary.constructBuilder(aTag);
396 currentBuilder = builderLibrary.constructBuilder(aTag);
398 currentBuilder.setAttributes(anAttributes);
399 if (currentBuilder.getAvailableSubNodes().isEmpty()) {
400 return new EmptySectionHandler();
402 if (currentBuilder.getAvailableSubNodes().size() > 1)
403 return new MultiProducerNodeSectionHandler(scriptedNodeName,
404 allowedNodeParameterReferences,
405 currentBuilder.getAvailableSubNodes());
406 else if (currentBuilder.getAvailableSubNodes().size() < 1)
407 return new EmptySectionHandler();
409 return new ProducerNodeSectionHandler(scriptedNodeName,
410 allowedNodeParameterReferences);
414 throw new XMLReader.XMLReaderExc("Unknown producer node tag: '" +
417 catch (Throwable t) {
418 throw new XMLReader.XMLReaderFailure(t);
422 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
424 if (aHandler instanceof ProducerNodeSectionHandler) {
425 currentBuilder.setSubNode(
426 (String) (currentBuilder.getAvailableSubNodes().iterator().next()),
427 ((ProducerNodeSectionHandler) aHandler).getProducerNode());
429 else if (aHandler instanceof MultiProducerNodeSectionHandler) {
434 nodeParameters = ( (MultiProducerNodeSectionHandler) aHandler).
436 i = nodeParameters.entrySet().iterator();
437 while (i.hasNext()) {
438 entry = (Map.Entry) i.next();
439 currentBuilder.setSubNode( (String) entry.getKey(),
440 (ProducerNode) entry.getValue());
443 else if (aHandler instanceof EmptySectionHandler) {
444 // deliberately empty: nothing expected, so nothing to process
447 throw new XMLReader.XMLReaderExc(
448 "Internal error: unknown section handler '" +
449 aHandler.getClass().getName() + "'");
452 producerNode.addSubNode(currentBuilder.constructNode());
453 currentBuilder = null;
455 catch (Throwable t) {
456 throw new XMLReader.XMLReaderFailure(t);
460 public ProducerNode getProducerNode() {
461 if (producerNode.getNrSubNodes()==1) {
462 return producerNode.getSubNode(0);
469 public void finishSection() {
473 public class NodeDefinitionSectionHandler extends XMLReader.AbstractSectionHandler {
474 private ScriptedProducerNodeDefinition nodeDefinition;
475 private ProducerNode body;
476 private Map stringParameters;
477 private Map integerParameters;
478 private Map nodeParameters;
481 public NodeDefinitionSectionHandler(String aName) {
483 nodeParameters = null;
484 stringParameters = null;
485 integerParameters = null;
489 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
490 if (aTag.equals("parameters")) {
491 if (!anAttributes.isEmpty()) {
492 throw new XMLReader.XMLReaderExc( "No attributes allowed for tag 'parameters'" );
494 if (nodeParameters!=null) {
495 throw new XMLReader.XMLReaderExc( "Parameters have already been declared" );
498 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
501 return new NodeDefinitionParametersSectionHandler();
503 else if (aTag.equals("definition")) {
504 if (nodeParameters==null)
505 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
507 return new ProducerNodeSectionHandler(name, nodeParameters.keySet());
509 else throw new XMLReader.XMLReaderExc("Only 'definition' or 'parameters' tags allowed here, '" + aTag + "' encountered.");
512 public void endElement(XMLReader.SectionHandler aHandler) {
513 if (aHandler instanceof NodeDefinitionParametersSectionHandler) {
514 stringParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getStringParameters();
515 integerParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getIntegerParameters();
516 nodeParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getNodeParameters();
518 else if (aHandler instanceof ProducerNodeSectionHandler) {
519 body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
523 public void finishSection() throws XMLReader.XMLReaderExc {
526 throw new XMLReader.XMLReaderExc( "Definition missing" );
528 nodeDefinition = new ScriptedProducerNodeDefinition(name);
530 nodeDefinition.setBody(body);
532 i = nodeParameters.keySet().iterator();
533 while (i.hasNext()) {
534 nodeDefinition.addNodeParameter((String) i.next());
537 i = stringParameters.entrySet().iterator();
538 while (i.hasNext()) {
539 Map.Entry entry = (Map.Entry) i.next();
540 nodeDefinition.addStringParameter((String) entry.getKey(), (String) entry.getValue());
543 i = integerParameters.entrySet().iterator();
544 while (i.hasNext()) {
545 Map.Entry entry = (Map.Entry) i.next();
546 nodeDefinition.addIntegerParameter((String) entry.getKey(), (String) entry.getValue());
550 public ScriptedProducerNodeDefinition getDefinition() {
551 return nodeDefinition;
555 private final static String NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE = "name";
556 private final static String NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE = "defaultvalue";
557 private final static String[] NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE };
558 private final static String[] NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE };
559 private final static String[] NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES = { };
561 public class NodeDefinitionParametersSectionHandler extends XMLReader.AbstractSectionHandler {
562 private Map nodeParameters;
563 private Map stringParameters;
564 private Map integerParameters;
566 public NodeDefinitionParametersSectionHandler() {
567 nodeParameters = new HashMap();
568 stringParameters = new HashMap();
569 integerParameters = new HashMap();
572 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
573 String parameterName;
576 if (aTag.equals("node")) {
577 XMLReaderTool.checkAttributes(anAttributes,
578 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
579 NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES);
580 parameterName = (String) anAttributes.get(
581 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
583 if (nodeParameters.containsKey(parameterName))
584 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
585 parameterName + "'");
587 XMLReaderTool.checkValidIdentifier(parameterName);
589 nodeParameters.put(parameterName, parameterName);
591 return new EmptySectionHandler();
593 else if (aTag.equals("string") || aTag.equals("integer")) {
594 XMLReaderTool.checkAttributes(anAttributes,
595 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
596 NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES);
597 parameterName = (String) anAttributes.get(
598 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
600 if (stringParameters.containsKey(parameterName) ||
601 integerParameters.containsKey(parameterName))
602 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
603 parameterName + "'");
605 XMLReaderTool.checkValidIdentifier(parameterName);
607 defaultValue = (String) anAttributes.get(
608 NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE);
610 if (aTag.equals("string"))
611 stringParameters.put(parameterName, defaultValue);
613 integerParameters.put(parameterName, defaultValue);
615 return new EmptySectionHandler();
618 throw new XMLReader.XMLReaderExc(
619 "Only 'string', 'integer' and 'node' tags allowed here, '" + aTag + "' encountered.");
622 public void endElement(XMLReader.SectionHandler aHandler) {
625 public void finishSection() {
628 public Map getNodeParameters() {
629 return nodeParameters;
632 public Map getStringParameters() {
633 return stringParameters;
636 public Map getIntegerParameters() {
637 return integerParameters;