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 the com.oreilly.servlet library, any library
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24 * the above that use the same license as the above), and distribute linked
25 * combinations including the two. You must obey the GNU General Public
26 * License in all respects for all of the code used other than the above
27 * mentioned libraries. If you modify this file, you may extend this exception
28 * to your version of the file, but you are not obligated to do so. If you do
29 * not wish to do so, delete this exception statement from your version.
32 package mir.producer.reader;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 import java.util.List;
41 import java.util.Vector;
43 import mir.producer.CompositeProducerNode;
44 import mir.producer.ProducerFactory;
45 import mir.producer.ProducerNode;
46 import mir.producer.SimpleProducerVerb;
47 import mir.util.XMLReader;
48 import mir.util.XMLReaderTool;
50 public class ProducerConfigReader {
51 private ProducerNodeBuilderLibrary builderLibrary;
52 private ProducerNodeBuilderLibrary scriptedNodeBuilderLibrary;
54 public ProducerConfigReader() {
58 public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories) throws ProducerConfigFailure {
59 parseFile(aFileName, aBuilderLibrary, aProducerFactories, new Vector());
62 public void parseFile(String aFileName, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories, List aUsedFiles) throws ProducerConfigFailure {
64 XMLReader reader = new XMLReader();
65 aUsedFiles.add(new File(aFileName));
67 builderLibrary = aBuilderLibrary;
68 scriptedNodeBuilderLibrary = new ProducerNodeBuilderLibrary();
70 reader.parseFile(aFileName, new RootSectionHandler(aProducerFactories));
74 if ((e instanceof XMLReader.XMLReaderExc) && ((XMLReader.XMLReaderExc) e).getHasLocation()) {
75 XMLReader.XMLReaderExc f = (XMLReader.XMLReaderExc) e;
76 throw new ProducerConfigFailure("'" + f.getMessage()+"' in " + f.getFilename()+"(line " + f.getLineNr()+", column " + f.getColumnNr() + ")", e);
78 throw new ProducerConfigFailure( e );
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, '" +
281 aTag + "' encountered.");
284 public void endElement(XMLReader.SectionHandler aHandler) {
285 verbNodes.put(currentVerb, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
286 verbs.add(new SimpleProducerVerb(currentVerb, currentVerbDescription));
289 public void finishSection() {
292 public String getDefaultVerb() {
296 public List getVerbs() {
300 public Map getVerbNodes() {
305 public class EmptySectionHandler extends XMLReader.AbstractSectionHandler {
306 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
307 throw new XMLReader.XMLReaderExc("No tags are allowed here");
310 public void endElement(XMLReader.SectionHandler aHandler) {
313 public void finishSection() {
317 public class MultiProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
318 private Map nodeParameters;
319 private Set validNodeParameters;
320 private String currentNodeParameter;
321 private String scriptedNodeName;
322 private Set allowedNodeParameterReferences;
324 public MultiProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences, Set aValidNodeParameters) {
325 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
326 scriptedNodeName = aScriptedNodeName;
327 validNodeParameters = aValidNodeParameters;
328 nodeParameters = new HashMap();
330 public MultiProducerNodeSectionHandler(Set aValidNodeParameters) {
331 this("", new HashSet(), aValidNodeParameters);
334 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
335 if (!validNodeParameters.contains(aTag))
336 throw new XMLReader.XMLReaderExc("Invalid node parameter: '" + aTag + "'");
337 else if (nodeParameters.containsKey(aTag))
338 throw new XMLReader.XMLReaderExc("Node parameter: '" + aTag + "' already specified");
339 else if (anAttributes.size()>0)
340 throw new XMLReader.XMLReaderExc("No parameters are allowed here");
342 currentNodeParameter = aTag;
344 return new ProducerNodeSectionHandler(scriptedNodeName, validNodeParameters);
347 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
348 if (aHandler instanceof ProducerNodeSectionHandler) {
349 nodeParameters.put(currentNodeParameter, ((ProducerNodeSectionHandler) aHandler).getProducerNode());
352 throw new XMLReader.XMLReaderExc("Internal error: unknown section handler '" + aHandler.getClass().getName() + "'" );
356 public Map getNodeParameters() {
357 return nodeParameters;
360 public void finishSection() {
364 public class ProducerNodeSectionHandler extends XMLReader.AbstractSectionHandler {
365 private CompositeProducerNode producerNode;
366 private ProducerNodeBuilder currentBuilder;
367 private String scriptedNodeName;
368 private Set allowedNodeParameterReferences;
370 public ProducerNodeSectionHandler(String aScriptedNodeName, Set anAllowedNodeParameterReferences) {
371 producerNode = new CompositeProducerNode();
372 scriptedNodeName = aScriptedNodeName;
373 allowedNodeParameterReferences = anAllowedNodeParameterReferences;
376 public ProducerNodeSectionHandler() {
377 this("", new HashSet());
380 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
382 if (allowedNodeParameterReferences.contains( (aTag))) {
383 if (!anAttributes.isEmpty()) {
384 throw new XMLReader.XMLReaderExc("No attributes allowed");
387 currentBuilder = new DefaultProducerNodeBuilders.
388 ScriptedProducerParameterNodeBuilder(scriptedNodeName, aTag);
389 return new EmptySectionHandler();
391 else if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag) ||
392 builderLibrary.hasBuilderForName( (aTag))) {
394 if (scriptedNodeBuilderLibrary.hasBuilderForName(aTag))
395 currentBuilder = scriptedNodeBuilderLibrary.constructBuilder(aTag);
397 currentBuilder = builderLibrary.constructBuilder(aTag);
399 currentBuilder.setAttributes(anAttributes);
400 if (currentBuilder.getAvailableSubNodes().isEmpty()) {
401 return new EmptySectionHandler();
403 if (currentBuilder.getAvailableSubNodes().size() > 1)
404 return new MultiProducerNodeSectionHandler(scriptedNodeName,
405 allowedNodeParameterReferences,
406 currentBuilder.getAvailableSubNodes());
407 else if (currentBuilder.getAvailableSubNodes().size() < 1)
408 return new EmptySectionHandler();
410 return new ProducerNodeSectionHandler(scriptedNodeName,
411 allowedNodeParameterReferences);
415 throw new XMLReader.XMLReaderExc("Unknown producer node tag: '" +
418 catch (Throwable t) {
419 throw new XMLReader.XMLReaderFailure(t);
423 public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {
425 if (aHandler instanceof ProducerNodeSectionHandler) {
426 currentBuilder.setSubNode(
427 (String) (currentBuilder.getAvailableSubNodes().iterator().next()),
428 ((ProducerNodeSectionHandler) aHandler).getProducerNode());
430 else if (aHandler instanceof MultiProducerNodeSectionHandler) {
435 nodeParameters = ( (MultiProducerNodeSectionHandler) aHandler).
437 i = nodeParameters.entrySet().iterator();
438 while (i.hasNext()) {
439 entry = (Map.Entry) i.next();
440 currentBuilder.setSubNode( (String) entry.getKey(),
441 (ProducerNode) entry.getValue());
444 else if (aHandler instanceof EmptySectionHandler) {
445 // deliberately empty: nothing expected, so nothing to process
448 throw new XMLReader.XMLReaderExc(
449 "Internal error: unknown section handler '" +
450 aHandler.getClass().getName() + "'");
453 producerNode.addSubNode(currentBuilder.constructNode());
454 currentBuilder = null;
456 catch (Throwable t) {
457 throw new XMLReader.XMLReaderFailure(t);
461 public ProducerNode getProducerNode() {
462 if (producerNode.getNrSubNodes()==1) {
463 return producerNode.getSubNode(0);
470 public void finishSection() {
474 public class NodeDefinitionSectionHandler extends XMLReader.AbstractSectionHandler {
475 private ScriptedProducerNodeDefinition nodeDefinition;
476 private ProducerNode body;
477 private Map stringParameters;
478 private Map integerParameters;
479 private Map nodeParameters;
482 public NodeDefinitionSectionHandler(String aName) {
484 nodeParameters = null;
485 stringParameters = null;
486 integerParameters = null;
490 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
491 if (aTag.equals("parameters")) {
492 if (!anAttributes.isEmpty()) {
493 throw new XMLReader.XMLReaderExc( "No attributes allowed for tag 'parameters'" );
495 if (nodeParameters!=null) {
496 throw new XMLReader.XMLReaderExc( "Parameters have already been declared" );
499 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
502 return new NodeDefinitionParametersSectionHandler();
504 else if (aTag.equals("definition")) {
505 if (nodeParameters==null)
506 throw new XMLReader.XMLReaderExc( "Parameters should come before definition in nodedefinition '" + name +"'" );
508 return new ProducerNodeSectionHandler(name, nodeParameters.keySet());
510 else throw new XMLReader.XMLReaderExc("Only 'definition' or 'parameters' tags allowed here, '" + aTag + "' encountered.");
513 public void endElement(XMLReader.SectionHandler aHandler) {
514 if (aHandler instanceof NodeDefinitionParametersSectionHandler) {
515 stringParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getStringParameters();
516 integerParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getIntegerParameters();
517 nodeParameters = ((NodeDefinitionParametersSectionHandler) aHandler).getNodeParameters();
519 else if (aHandler instanceof ProducerNodeSectionHandler) {
520 body = ((ProducerNodeSectionHandler) aHandler).getProducerNode();
524 public void finishSection() throws XMLReader.XMLReaderExc {
527 throw new XMLReader.XMLReaderExc( "Definition missing" );
529 nodeDefinition = new ScriptedProducerNodeDefinition(name);
531 nodeDefinition.setBody(body);
533 i = nodeParameters.keySet().iterator();
534 while (i.hasNext()) {
535 nodeDefinition.addNodeParameter((String) i.next());
538 i = stringParameters.entrySet().iterator();
539 while (i.hasNext()) {
540 Map.Entry entry = (Map.Entry) i.next();
541 nodeDefinition.addStringParameter((String) entry.getKey(), (String) entry.getValue());
544 i = integerParameters.entrySet().iterator();
545 while (i.hasNext()) {
546 Map.Entry entry = (Map.Entry) i.next();
547 nodeDefinition.addIntegerParameter((String) entry.getKey(), (String) entry.getValue());
551 public ScriptedProducerNodeDefinition getDefinition() {
552 return nodeDefinition;
556 private final static String NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE = "name";
557 private final static String NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE = "defaultvalue";
558 private final static String[] NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE };
559 private final static String[] NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES = { NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE };
560 private final static String[] NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES = { };
562 public class NodeDefinitionParametersSectionHandler extends XMLReader.AbstractSectionHandler {
563 private Map nodeParameters;
564 private Map stringParameters;
565 private Map integerParameters;
567 public NodeDefinitionParametersSectionHandler() {
568 nodeParameters = new HashMap();
569 stringParameters = new HashMap();
570 integerParameters = new HashMap();
573 public XMLReader.SectionHandler startElement(String aTag, Map anAttributes) throws XMLReader.XMLReaderExc {
574 String parameterName;
577 if (aTag.equals("node")) {
578 XMLReaderTool.checkAttributes(anAttributes,
579 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
580 NODE_DEFINITION_NODE_PARAMETER_OPTIONAL_ATTRIBUTES);
581 parameterName = (String) anAttributes.get(
582 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
584 if (nodeParameters.containsKey(parameterName))
585 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
586 parameterName + "'");
588 XMLReaderTool.checkValidIdentifier(parameterName);
590 nodeParameters.put(parameterName, parameterName);
592 return new EmptySectionHandler();
594 else if (aTag.equals("string") || aTag.equals("integer")) {
595 XMLReaderTool.checkAttributes(anAttributes,
596 NODE_DEFINITION_PARAMETER_REQUIRED_ATTRIBUTES,
597 NODE_DEFINITION_PARAMETER_OPTIONAL_ATTRIBUTES);
598 parameterName = (String) anAttributes.get(
599 NODE_DEFINITION_PARAMETER_NAME_ATTRIBUTE);
601 if (stringParameters.containsKey(parameterName) ||
602 integerParameters.containsKey(parameterName))
603 throw new XMLReader.XMLReaderExc("Duplicate parameter name: '" +
604 parameterName + "'");
606 XMLReaderTool.checkValidIdentifier(parameterName);
608 defaultValue = (String) anAttributes.get(
609 NODE_DEFINITION_PARAMETER_DEFAULTVALUE_ATTRIBUTE);
611 if (aTag.equals("string"))
612 stringParameters.put(parameterName, defaultValue);
614 integerParameters.put(parameterName, defaultValue);
616 return new EmptySectionHandler();
619 throw new XMLReader.XMLReaderExc(
620 "Only 'string', 'integer' and 'node' tags allowed here, '" + aTag + "' encountered.");
623 public void endElement(XMLReader.SectionHandler aHandler) {
626 public void finishSection() {
629 public Map getNodeParameters() {
630 return nodeParameters;
633 public Map getStringParameters() {
634 return stringParameters;
637 public Map getIntegerParameters() {
638 return integerParameters;