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;
46 import mir.util.XMLReaderTool;
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 if ((e instanceof XMLReader.XMLReaderExc) && ((XMLReader.XMLReaderExc) e).getHasLocation()) {
73 XMLReader.XMLReaderExc f = (XMLReader.XMLReaderExc) e;
74 throw new ProducerConfigFailure("'" + f.getMessage()+"' in " + f.getFilename()+"(line " + f.getLineNr()+", column " + f.getColumnNr() + ")", e);
76 throw new ProducerConfigFailure( e );
81 public class RootSectionHandler extends XMLReader.AbstractSectionHandler {
82 private List producers;
84 public RootSectionHandler(List aProducers) {
85 producers = aProducers;
88 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
89 if (aTag.equals("producers")) {
90 return new ProducersSectionHandler(producers);
93 throw new XMLReader.XMLReaderExc("Tag 'producers' expected, tag '"+aTag+"' found");
96 public void endElement(XMLReader.SectionHandler aHandler) {
99 public void finishSection() {
104 private final static String PRODUCER_NAME_ATTRIBUTE = "name";
105 private final static String[] PRODUCER_REQUIRED_ATTRIBUTES = { PRODUCER_NAME_ATTRIBUTE };
106 private final static String[] PRODUCER_OPTIONAL_ATTRIBUTES = { };
108 private final static String NODE_DEFINITION_NAME_ATTRIBUTE = "name";
109 private final static String[] NODE_DEFINITION_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_NAME_ATTRIBUTE };
110 private final static String[] NODE_DEFINITION_OPTIONAL_ATTRIBUTES = { };
112 public class ProducersSectionHandler extends XMLReader.AbstractSectionHandler {
113 private List producers;
114 private Set producerNames;
117 public ProducersSectionHandler(List aProducers) {
118 producers = aProducers;
119 producerNames = new HashSet();
122 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
123 if (aTag.equals("producer")) {
124 XMLReaderTool.checkAttributes(anAttributes,
125 PRODUCER_REQUIRED_ATTRIBUTES,
126 PRODUCER_OPTIONAL_ATTRIBUTES);
128 name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
129 XMLReaderTool.checkValidIdentifier(name);
131 if (producerNames.contains(name))
132 throw new XMLReader.XMLReaderExc("Duplicate producer name: '" +
135 name = (String) anAttributes.get(PRODUCER_NAME_ATTRIBUTE);
137 return new ProducerSectionHandler(name);
139 else if (aTag.equals("nodedefinition")) {
140 XMLReaderTool.checkAttributes(anAttributes,
141 NODE_DEFINITION_REQUIRED_ATTRIBUTES,
142 NODE_DEFINITION_OPTIONAL_ATTRIBUTES);
144 name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
145 XMLReaderTool.checkValidIdentifier(name);
147 name = (String) anAttributes.get(NODE_DEFINITION_NAME_ATTRIBUTE);
149 return new NodeDefinitionSectionHandler(name);
151 throw new XMLReader.XMLReaderExc("Unexpected tag: " + aTag);
154 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
155 if (aHandler instanceof ProducerSectionHandler) {
156 producers.add(((ProducerSectionHandler) aHandler).getProducerFactory());
157 producerNames.add(((ProducerSectionHandler) aHandler).getProducerFactory().getName());
159 else if (aHandler instanceof NodeDefinitionSectionHandler) {
160 scriptedNodeBuilderLibrary.registerFactory(name,
161 new DefaultProducerNodeBuilders.ScriptedProducerNodeBuilder.factory(
162 ((NodeDefinitionSectionHandler) aHandler).getDefinition()));
164 else throw new XMLReader.XMLReaderExc("ProducersSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
167 public void finishSection() {
171 public class ProducerSectionHandler extends XMLReader.AbstractSectionHandler {
172 private ProducerFactory producerFactory;
173 private String factoryName;
175 private ProducerNode body;
176 private Map verbNodes;
178 private String defaultVerb;
180 public ProducerSectionHandler(String aName) {
184 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
185 if (aTag.equals("verbs")) {
187 throw new XMLReader.XMLReaderExc("Verbs already processed");
189 throw new XMLReader.XMLReaderExc("Verbs should come before body");
191 return new ProducerVerbsSectionHandler();
193 else if (aTag.equals("body")) {
195 return new ProducerNodeSectionHandler();
197 throw new XMLReader.XMLReaderExc("Body already processed");
199 throw new XMLReader.XMLReaderExc("Unexpected tag: '"+aTag+"'");
202 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
203 if (aHandler instanceof ProducerNodeSectionHandler) {
204 body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
206 else if (aHandler instanceof ProducerVerbsSectionHandler)
208 verbs = ((ProducerVerbsSectionHandler) aHandler).getVerbs();
209 verbNodes = ((ProducerVerbsSectionHandler) aHandler).getVerbNodes();
210 defaultVerb = ((ProducerVerbsSectionHandler) aHandler).getDefaultVerb();
212 else throw new XMLReader.XMLReaderExc("ProducerSectionHandler.endElement Internal error: Unexpected handler: " + aHandler.getClass().getName());
215 public void finishSection() throws XMLReader.XMLReaderExc {
217 throw new XMLReader.XMLReaderExc("No verbs defined");
220 throw new XMLReader.XMLReaderExc("No body defined");
222 producerFactory = new ScriptedProducerFactory(factoryName, verbs, verbNodes, body, defaultVerb);
225 public ProducerFactory getProducerFactory() {
226 return producerFactory;
230 private final static String PRODUCER_VERB_NAME_ATTRIBUTE = "name";
231 private final static String PRODUCER_VERB_DESCRIPTION_ATTRIBUTE = "description";
232 private final static String PRODUCER_VERB_DEFAULT_ATTRIBUTE = "default";
233 private final static String[] PRODUCER_VERB_REQUIRED_ATTRIBUTES = { PRODUCER_VERB_NAME_ATTRIBUTE };
234 private final static String[] PRODUCER_VERB_OPTIONAL_ATTRIBUTES = { PRODUCER_VERB_DEFAULT_ATTRIBUTE, PRODUCER_VERB_DESCRIPTION_ATTRIBUTE };
236 public class ProducerVerbsSectionHandler extends XMLReader.AbstractSectionHandler {
237 private Map verbNodes;
239 private String defaultVerb;
240 private String currentVerb;
241 private String currentVerbDescription;
243 public ProducerVerbsSectionHandler() {
244 verbNodes = new HashMap();
245 verbs = new Vector();
249 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
250 if (aTag.equals("verb")) {
251 XMLReaderTool.checkAttributes(anAttributes,
252 PRODUCER_VERB_REQUIRED_ATTRIBUTES,
253 PRODUCER_VERB_OPTIONAL_ATTRIBUTES);
254 currentVerb = (String) anAttributes.get(PRODUCER_VERB_NAME_ATTRIBUTE);
256 XMLReaderTool.checkValidIdentifier(currentVerb);
258 if (verbNodes.containsKey(currentVerb))
259 throw new XMLReader.XMLReaderExc("Duplicate definition of verb '" +
262 if (anAttributes.containsKey(PRODUCER_VERB_DEFAULT_ATTRIBUTE)) {
263 if (defaultVerb != null)
264 throw new XMLReader.XMLReaderExc("Default verb already declared");
266 defaultVerb = currentVerb;
269 if (anAttributes.containsKey(PRODUCER_VERB_DESCRIPTION_ATTRIBUTE))
270 currentVerbDescription = (String) anAttributes.get(
271 PRODUCER_VERB_DESCRIPTION_ATTRIBUTE);
273 currentVerbDescription = "";
275 return new ProducerNodeSectionHandler();
278 throw new XMLReader.XMLReaderExc("Only 'verb' tags allowed here, '" + aTag + "' encountered.");
281 public void endElement(XMLReader.SectionHandler aHandler) {
282 verbNodes.put(currentVerb, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
283 verbs.add(new SimpleProducerVerb(currentVerb, currentVerbDescription));
286 public void finishSection() {
289 public String getDefaultVerb() {
293 public List getVerbs() {
297 public Map getVerbNodes() {
302 public class EmptySectionHandler extends XMLReader.AbstractSectionHandler {
303 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
304 throw new XMLReader.XMLReaderExc("No tags are allowed here");
307 public void endElement(XMLReader.SectionHandler aHandler) {
310 public void finishSection() {
314 public class MultiProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
315 private Map nodeParameters;
316 private Set validNodeParameters;
317 private String currentNodeParameter;
318 private String scriptedNodeName;
319 private Set allowedNodeParameterReferences;
321 public MultiProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences, Set aValidNodeParameters) {
322 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
323 scriptedNodeName = aScriptedNodeName;
324 validNodeParameters = aValidNodeParameters;
325 nodeParameters = new HashMap();
327 public MultiProducerNodeSectionHandler(Set aValidNodeParameters) {
328 this("", new HashSet(), aValidNodeParameters);
331 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
332 if (!validNodeParameters.contains(aTag))
333 throw new XMLReader.XMLReaderExc("Invalid node parameter: '" + aTag + "'");
334 else if (nodeParameters.containsKey(aTag))
335 throw new XMLReader.XMLReaderExc("Node parameter: '" + aTag + "' already specified");
336 else if (anAttributes.size()>0)
337 throw new XMLReader.XMLReaderExc("No parameters are allowed here");
339 currentNodeParameter = aTag;
341 return new ProducerNodeSectionHandler(scriptedNodeName, allowedNodeParameterReferences);
344 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
345 if (aHandler instanceof ProducerNodeSectionHandler) {
346 nodeParameters.put(currentNodeParameter, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
349 throw new XMLReader.XMLReaderExc("Internal error: unknown section handler '" + aHandler.getClass().getName() + "'" );
353 public Map getNodeParameters() {
354 return nodeParameters;
357 public void finishSection() {
361 public class ProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
362 private CompositeProducerNode producerNode;
363 private ProducerNodeBuilder currentBuilder;
364 private String scriptedNodeName;
365 private Set allowedNodeParameterReferences;
367 public ProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences) {
368 producerNode = new CompositeProducerNode();
369 scriptedNodeName = aScriptedNodeName;
370 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
373 public ProducerNodeSectionHandler() {
374 this("", new HashSet());
377 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
379 if (allowedNodeParameterReferences.contains( (aTag))) {
380 if (!anAttributes.isEmpty()) {
381 throw new XMLReader.XMLReaderExc("No attributes allowed");
384 currentBuilder = new DefaultProducerNodeBuilders.
385 ScriptedProducerParameterNodeBuilder(scriptedNodeName, aTag);
386 return new EmptySectionHandler();
388 else if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag) ||
389 builderLibrary.hasBuilderForName( (aTag))) {
391 if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag))
392 currentBuilder = scriptedNodeBuilderLibrary.constructBuilder(aTag);
394 currentBuilder = builderLibrary.constructBuilder(aTag);
396 currentBuilder.setAttributes(anAttributes);
397 if (currentBuilder.getAvailableSubNodes().isEmpty()) {
398 return new EmptySectionHandler();
400 if (currentBuilder.getAvailableSubNodes().size() > 1)
401 return new MultiProducerNodeSectionHandler(scriptedNodeName,
402 allowedNodeParameterReferences,
403 currentBuilder.getAvailableSubNodes());
404 else if (currentBuilder.getAvailableSubNodes().size() < 1)
405 return new EmptySectionHandler();
407 return new ProducerNodeSectionHandler(scriptedNodeName,
408 allowedNodeParameterReferences);
412 throw new XMLReader.XMLReaderExc("Unknown producer node tag: '" +
415 catch (Throwable t) {
416 throw new XMLReader.XMLReaderFailure(t);
420 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
422 if (aHandler instanceof ProducerNodeSectionHandler) {
423 currentBuilder.setSubNode(
424 (String) (currentBuilder.getAvailableSubNodes().iterator().next()),
425 ((ProducerNodeSectionHandler) aHandler).getProducerNode());
427 else if (aHandler instanceof MultiProducerNodeSectionHandler) {
432 nodeParameters = ( (MultiProducerNodeSectionHandler) aHandler).
434 i = nodeParameters.entrySet().iterator();
435 while (i.hasNext()) {
436 entry = (Map.Entry) i.next();
437 currentBuilder.setSubNode( (String) entry.getKey(),
438 (ProducerNode) entry.getValue());
441 else if (aHandler instanceof EmptySectionHandler) {
442 // deliberately empty: nothing expected, so nothing to process
445 throw new XMLReader.XMLReaderExc(
446 "Internal error: unknown section handler '" +
447 aHandler.getClass().getName() + "'");
450 producerNode.addSubNode(currentBuilder.constructNode());
451 currentBuilder = null;
453 catch (Throwable t) {
454 throw new XMLReader.XMLReaderFailure(t);
458 public ProducerNode getProducerNode() {
459 if (producerNode.getNrSubNodes()==1) {
460 return producerNode.getSubNode(0);
467 public void finishSection() {
471 public class NodeDefinitionSectionHandler extends XMLReader.AbstractSectionHandler {
472 private ScriptedProducerNodeDefinition nodeDefinition;
473 private ProducerNode body;
474 private Map stringParameters;
475 private Map integerParameters;
476 private Map nodeParameters;
479 public NodeDefinitionSectionHandler(String aName) {
481 nodeParameters = null;
482 stringParameters = null;
483 integerParameters = null;
487 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
488 if (aTag.equals("parameters")) {
489 if (!anAttributes.isEmpty()) {
490 throw new XMLReader.XMLReaderExc( "No attributes allowed for tag 'parameters'" );
492 if (nodeParameters!=null) {
493 throw new XMLReader.XMLReaderExc( "Parameters have already been declared" );
496 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
499 return new NodeDefinitionParametersSectionHandler();
501 else if (aTag.equals("definition")) {
502 if (nodeParameters==null)
503 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
505 return new ProducerNodeSectionHandler(name, nodeParameters.keySet());
507 else throw new XMLReader.XMLReaderExc("Only 'definition' or 'parameters' tags allowed here, '" + aTag + "' encountered.");
510 public void endElement(XMLReader.SectionHandler aHandler) {
511 if (aHandler instanceof NodeDefinitionParametersSectionHandler) {
512 stringParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getStringParameters();
513 integerParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getIntegerParameters();
514 nodeParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getNodeParameters();
516 else if (aHandler instanceof ProducerNodeSectionHandler) {
517 body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
521 public void finishSection() throws XMLReader.XMLReaderExc {
524 throw new XMLReader.XMLReaderExc( "Definition missing" );
526 nodeDefinition = new ScriptedProducerNodeDefinition(name);
528 nodeDefinition.setBody(body);
530 i = nodeParameters.keySet().iterator();
531 while (i.hasNext()) {
532 nodeDefinition.addNodeParameter((String) i.next());
535 i = stringParameters.entrySet().iterator();
536 while (i.hasNext()) {
537 Map.Entry entry = (Map.Entry) i.next();
538 nodeDefinition.addStringParameter((String) entry.getKey(), (String) entry.getValue());
541 i = integerParameters.entrySet().iterator();
542 while (i.hasNext()) {
543 Map.Entry entry = (Map.Entry) i.next();
544 nodeDefinition.addIntegerParameter((String) entry.getKey(), (String) entry.getValue());
548 public ScriptedProducerNodeDefinition getDefinition() {
549 return nodeDefinition;
553 private final static String NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE = "name";
554 private final static String NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE = "defaultvalue";
555 private final static String[] NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE };
556 private final static String[] NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE };
557 private final static String[] NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES = { };
559 public class NodeDefinitionParametersSectionHandler extends XMLReader.AbstractSectionHandler {
560 private Map nodeParameters;
561 private Map stringParameters;
562 private Map integerParameters;
564 public NodeDefinitionParametersSectionHandler() {
565 nodeParameters = new HashMap();
566 stringParameters = new HashMap();
567 integerParameters = new HashMap();
570 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
571 String parameterName;
574 if (aTag.equals("node")) {
575 XMLReaderTool.checkAttributes(anAttributes,
576 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
577 NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES);
578 parameterName = (String) anAttributes.get(
579 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
581 if (nodeParameters.containsKey(parameterName))
582 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
583 parameterName + "'");
585 XMLReaderTool.checkValidIdentifier(parameterName);
587 nodeParameters.put(parameterName, parameterName);
589 return new EmptySectionHandler();
591 else if (aTag.equals("string") || aTag.equals("integer")) {
592 XMLReaderTool.checkAttributes(anAttributes,
593 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
594 NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES);
595 parameterName = (String) anAttributes.get(
596 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
598 if (stringParameters.containsKey(parameterName) ||
599 integerParameters.containsKey(parameterName))
600 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
601 parameterName + "'");
603 XMLReaderTool.checkValidIdentifier(parameterName);
605 defaultValue = (String) anAttributes.get(
606 NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE);
608 if (aTag.equals("string"))
609 stringParameters.put(parameterName, defaultValue);
611 integerParameters.put(parameterName, defaultValue);
613 return new EmptySectionHandler();
616 throw new XMLReader.XMLReaderExc(
617 "Only 'string', 'integer' and 'node' tags allowed here, '" + aTag + "' encountered.");
620 public void endElement(XMLReader.SectionHandler aHandler) {
623 public void finishSection() {
626 public Map getNodeParameters() {
627 return nodeParameters;
630 public Map getStringParameters() {
631 return stringParameters;
634 public Map getIntegerParameters() {
635 return integerParameters;