1
//////////////////////////////////////////////////////////////////////
3
// JCSP ("CSP for Java") Libraries //
4
// Copyright (C) 1996-2008 Peter Welch and Paul Austin. //
5
// 2001-2004 Quickstone Technologies Limited. //
7
// This library is free software; you can redistribute it and/or //
8
// modify it under the terms of the GNU Lesser General Public //
9
// License as published by the Free Software Foundation; either //
10
// version 2.1 of the License, or (at your option) any later //
13
// This library is distributed in the hope that it will be //
14
// useful, but WITHOUT ANY WARRANTY; without even the implied //
15
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
16
// PURPOSE. See the GNU Lesser General Public License for more //
19
// You should have received a copy of the GNU Lesser General //
20
// Public License along with this library; if not, write to the //
21
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, //
22
// Boston, MA 02111-1307, USA. //
24
// Author contact: P.H.Welch@kent.ac.uk //
27
//////////////////////////////////////////////////////////////////////
29
package org.jcsp.net.settings;
34
* <p>Used internally by the JCSP network infrastructure to load a configuration from an XML file.</p>
36
* <p>This is not a full XML reader, and is capable of reading only a subset of XML.</p>
38
* @author Quickstone Technologies Limited
40
public class ConfigReader implements XMLConfigConstants
43
* Diagnostic routine. This can load an XML configuration file and then display the configuration
44
* structure constructed. Specify the name of the file as the first command line parameter.
46
static public void main(String[] args)
50
System.err.println("Usage: XMLReader <filename>");
53
String filename = args[0];
56
ConfigReader cr = new ConfigReader(new FileInputStream(filename));
57
JCSPConfig config = cr.getConfig();
58
System.out.println(config);
62
System.err.println("Error while reading config.");
68
/** The config built up. */
69
private JCSPConfig config = new JCSPConfig();
72
* Constructs a new configuration from the given source stream. This will attempt to parse the file
73
* using recursive-descent approach.
75
* @param instream source of the XML configuration.
76
* @throws IOException if there is a problem with the stream or the file is improperly formatted.
77
* @throws XMLValidationException if there is a symantic problem with the configuration.
79
public ConfigReader(InputStream instream) throws IOException
81
BufferedReader in = new BufferedReader(new InputStreamReader(instream));
83
while ((t = nextTag(in)) != null)
85
if (t.name.equals("JCSP-CONFIG"))
90
if (t.name.equals("?xml"))
96
private void do_template(Reader in) throws IOException
99
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + "")))
104
private void doJCSP_Config(Reader in) throws IOException
107
while (((t = nextTag(in)) != null) && (!t.name.equals("/JCSP-CONFIG")))
109
if (t.name.equals(ELEMENT_SETTINGS))
115
if (t.name.equals(ELEMENT_SERVICES))
121
if (t.name.equals(ELEMENT_PLUGINS))
127
if (t.name.equals(ELEMENT_PROTOCOLS))
133
if (t.name.equals(ELEMENT_ADDRESSES))
139
if (t.name.equals(ELEMENT_NODE_SPECS))
145
if (t.name.equals(ELEMENT_LINK_PROFILES))
151
if (t.name.equals(ELEMENT_NODE_PROFILES))
161
private void doSettings(Reader in) throws IOException
164
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_SETTINGS)))
166
if (t.name.equals(ELEMENT_SETTING))
168
String name = t.getAttrib("name");
169
String value = t.getAttrib("value");
170
Setting setting = config.getSettings().getSetting(name);
173
setting = new Setting(name, value);
174
config.getSettings().addSetting(setting);
177
throw new XMLValidationException("Setting \"" + name + "\" already exists with value " + setting.getValue());
184
private int servicePos = 0;
185
private int protocolPos = 0;
187
private void doServices(Reader in) throws IOException
190
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_SERVICES)))
192
if (t.name.equals(ELEMENT_SERVICE))
194
String name = t.getAttrib("name");
195
String className = t.getAttrib("class");
196
boolean run = Tag.getBooleanValue(t.getAttrib("run"));
199
Class serviceClass = Class.forName(className);
200
config.getServices().addService(new Service(name, serviceClass, run, servicePos++));
202
catch (ClassNotFoundException e)
204
throw new XMLValidationException("Unable to load class " + className);
214
private void doService(Reader in) throws IOException
217
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_SERVICE)))
219
if (t.name.equals(ELEMENT_ADDRESS_SETTING))
221
String name = t.getAttrib("name");
222
String value = t.getAttrib("value");
223
String pID = t.getAttrib("protocolid");
224
Service current = config.getServices().getLastService();
225
AddressSetting addrSetting = (AddressSetting) current.getAddressSetting(name);
226
if (addrSetting == null)
228
addrSetting = new AddressSetting(name, value, pID);
229
current.addAddressSetting(addrSetting);
232
addrSetting.addAlternate(new AddressSetting(name, value, pID));
235
if (t.name.equals(ELEMENT_SETTING))
237
String name = t.getAttrib("name");
238
String value = t.getAttrib("value");
239
Setting setting = config.getServices().getLastService().getSetting(name);
242
setting = new Setting(name, value);
243
config.getServices().getLastService().addSetting(setting);
246
throw new XMLValidationException("Setting \"" + name + "\" already exists with value " + setting.getValue());
253
private void doPlugins(Reader in) throws IOException
256
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_PLUGINS)))
258
if (t.name.equals(ELEMENT_PLUGIN))
260
String name = t.getAttrib("name");
261
String className = t.getAttrib("classname");
264
Class classToUse = Class.forName(className);
265
Plugin plugin = new Plugin(name, classToUse);
266
config.getPlugins().addPlugin(plugin);
270
throw new XMLValidationException("Unable to load class " + className);
280
private void doPlugin(Reader in) throws IOException
283
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_PLUGIN)))
288
private void doProtocols(Reader in) throws IOException
291
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_PROTOCOLS)))
293
if (t.name.equals(ELEMENT_PROTOCOL))
295
String id = t.getAttrib("id");
296
String name = t.getAttrib("name");
297
String idClass = t.getAttrib("idclass");
300
Class classToUse = Class.forName(idClass);
301
Protocol protocol = new Protocol(id, name, classToUse, protocolPos++);
302
config.getProtocols().addProtocol(protocol);
304
catch (ClassNotFoundException e)
306
throw new XMLValidationException("Unable to load class " + idClass);
316
private void doProtocol(Reader in) throws IOException
319
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_PROTOCOL)))
321
if (t.name.equals(ELEMENT_SPECS))
327
if (t.name.equals(ELEMENT_PROTOCOL_SETTINGS))
330
doProtocolSettings(in);
337
private void doProtocolSpecs(Reader in) throws IOException
340
while (((t = nextTag(in)) != null)
341
&& (!t.name.equals("/" + ELEMENT_SPECS)))
343
if (t.name.equals(ELEMENT_MAXSPEED))
345
int value = Tag.getIntValue(t.getAttrib("value"));
346
MaxSpeed m = new MaxSpeed(value);
347
Protocol p = config.getProtocols().getLastProtocol();
351
if (t.name.equals(ELEMENT_WIRELESS))
353
String value = t.getAttrib("value");
356
if (value.equals(XML_TRISTATE_TRUE))
357
w = new Wireless(1, false);
358
else if (value.equals(XML_TRISTATE_FALSE))
359
w = new Wireless(-1, false);
360
else if (value.equals(XML_TRISTATE_CANBE))
361
w = new Wireless(0, false);
363
//this validation should be done by the DTD
364
throw new XMLValidationException("Invalid Wireless value " + "\"" + value + "\"" + "\nUse either \"" +
365
XML_TRISTATE_TRUE + "\", \"" + XML_TRISTATE_FALSE + "\" or \"" +
366
XML_TRISTATE_CANBE + "\".");
367
Protocol p = config.getProtocols().getLastProtocol();
371
if (t.name.equals(ELEMENT_RELIABLE))
373
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
374
Reliable r = new Reliable(value, false);
375
Protocol p = config.getProtocols().getLastProtocol();
379
if (t.name.equals(ELEMENT_CONNECTION_ORIENTED))
381
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
382
ConnectionOriented co = new ConnectionOriented(value, false);
383
Protocol p = config.getProtocols().getLastProtocol();
387
if (t.name.equals(ELEMENT_OTHERSPEC))
389
String name = t.getAttrib("name");
390
String value = t.getAttrib("value");
391
String type = t.getAttrib("type");
393
if (type.equals(DATA_TYPE_INDICATOR_INT))
395
int intVal = Tag.getIntValue(value);
396
os = new OtherSpec(name, intVal, false);
398
else if (type.equals(DATA_TYPE_INDICATOR_DOUBLE))
400
double dblVal = Tag.getDoubleValue(value);
401
os = new OtherSpec(name, dblVal, false);
403
else if (type.equals(DATA_TYPE_INDICATOR_STRING))
404
os = new OtherSpec(name, value, false);
405
else if (type.equals(DATA_TYPE_INDICATOR_BOOLEAN))
407
boolean booVal = Tag.getBooleanValue(value);
408
os = new OtherSpec(name, booVal, false);
410
Protocol p = config.getProtocols().getLastProtocol();
418
private void doProtocolSettings(Reader in) throws IOException
421
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_PROTOCOL_SETTINGS)))
423
if (t.name.equals(ELEMENT_PROTOCOL_SETTING))
425
Protocol p = config.getProtocols().getLastProtocol();
426
String name = t.getAttrib("name");
427
String value = t.getAttrib("value");
428
Setting setting = p.getSetting(name);
431
setting = new Setting(name, value);
432
p.addSetting(setting);
435
throw new XMLValidationException("Protocol Setting \"" + name + "\" already exists with value " +
443
private void doAddresses(Reader in) throws IOException
446
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_ADDRESSES)))
448
if (t.name.equals(ELEMENT_ADDRESS))
450
String protocolid = t.getAttrib("protocolid");
451
String value = t.getAttrib("value");
452
boolean unique = Tag.getBooleanValue(t.getAttrib("unique"));
453
Address add = new Address(protocolid, value, unique);
454
config.getAddresses().addAddress(add);
463
private void doAddress(Reader in) throws IOException
466
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_ADDRESS)))
468
if (t.name.equals(ELEMENT_SPECS))
470
if (!t.terminated) doAddressSpecs(in);
477
private void doAddressSpecs(Reader in) throws IOException
480
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_SPECS)))
482
if (t.name.equals(ELEMENT_MAXSPEED))
484
int value = Tag.getIntValue(t.getAttrib("value"));
485
MaxSpeed m = new MaxSpeed(value);
486
Address a = config.getAddresses().getLastAddress();
490
if (t.name.equals(ELEMENT_WIRELESS))
492
String value = t.getAttrib("value");
494
if (value.equals(XML_TRISTATE_TRUE))
495
w = new Wireless(1, false);
496
else if (value.equals(XML_TRISTATE_FALSE))
497
w = new Wireless(-1, false);
498
else if (value.equals(XML_TRISTATE_CANBE))
499
w = new Wireless(0, false);
501
//this validation should be done by the DTD
502
throw new XMLValidationException("Invalid Wireless value \"" + value + "\"" + "\nUse either \"" +
503
XML_TRISTATE_TRUE + "\", \"" + XML_TRISTATE_FALSE + "\" or \"" +
504
XML_TRISTATE_CANBE + "\".");
505
Address a = config.getAddresses().getLastAddress();
509
if (t.name.equals(ELEMENT_RELIABLE))
511
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
512
Reliable r = new Reliable(value, false);
513
Address a = config.getAddresses().getLastAddress();
517
if (t.name.equals(ELEMENT_CONNECTION_ORIENTED))
519
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
520
ConnectionOriented co = new ConnectionOriented(value, false);
521
Address a = config.getAddresses().getLastAddress();
525
if (t.name.equals(ELEMENT_OTHERSPEC))
527
String name = t.getAttrib("name");
528
String value = t.getAttrib("value");
529
String type = t.getAttrib("type");
531
if (type.equals(DATA_TYPE_INDICATOR_INT))
533
int intVal = Tag.getIntValue(value);
534
os = new OtherSpec(name, intVal, false);
536
else if (type.equals(DATA_TYPE_INDICATOR_DOUBLE))
538
double dblVal = Tag.getDoubleValue(value);
539
os = new OtherSpec(name, dblVal, false);
541
else if (type.equals(DATA_TYPE_INDICATOR_STRING))
542
os = new OtherSpec(name, value, false);
543
else if (type.equals(DATA_TYPE_INDICATOR_BOOLEAN))
545
boolean booVal = Tag.getBooleanValue(value);
546
os = new OtherSpec(name, booVal, false);
548
Address a = config.getAddresses().getLastAddress();
556
private void doNodeSpecs(Reader in) throws IOException
559
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_NODE_SPECS)))
561
if (t.name.equals(ELEMENT_MAXSPEED))
563
int value = Tag.getIntValue(t.getAttrib("value"));
564
MaxSpeed m = new MaxSpeed(value);
565
config.getNodeSpecs().addSpec(m);
568
if (t.name.equals(ELEMENT_MEMORY))
570
int value = Tag.getIntValue(t.getAttrib("value"));
571
Memory m = new Memory(value);
572
config.getNodeSpecs().addSpec(m);
575
if (t.name.equals(ELEMENT_OTHERSPEC))
577
String name = t.getAttrib("name");
578
String value = t.getAttrib("value");
579
String type = t.getAttrib("type");
581
if (type.equals(DATA_TYPE_INDICATOR_INT))
583
int intVal = Tag.getIntValue(value);
584
os = new OtherSpec(name, intVal, false);
586
else if (type.equals(DATA_TYPE_INDICATOR_DOUBLE))
588
double dblVal = Tag.getDoubleValue(value);
589
os = new OtherSpec(name, dblVal, false);
591
else if (type.equals(DATA_TYPE_INDICATOR_STRING))
592
os = new OtherSpec(name, value, false);
593
else if (type.equals(DATA_TYPE_INDICATOR_BOOLEAN))
595
boolean booVal = Tag.getBooleanValue(value);
596
os = new OtherSpec(name, booVal, false);
598
config.getNodeSpecs().addSpec(os);
605
private void doLinkProfiles(Reader in) throws IOException
608
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_LINK_PROFILES)))
610
if (t.name.equals(ELEMENT_LINK_PROFILE))
612
String name = t.getAttrib("name");
613
boolean exactMatchRequired = Tag.getBooleanValue(t.getAttrib("requireExactMatch"));
614
LinkProfile lp = new LinkProfile(name, exactMatchRequired);
615
config.getLinkProfiles().addProfile(lp);
624
private void doLinkProfile(Reader in) throws IOException
627
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_LINK_PROFILE)))
629
if (t.name.equals(ELEMENT_LINK_REQS))
639
private void doLinkReqs(Reader in) throws IOException
642
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_LINK_REQS)))
644
if (t.name.equals(ELEMENT_LINK_REQ_MINSPEED))
646
int value = Tag.getIntValue(t.getAttrib("value"));
647
MinSpeed ms = new MinSpeed(value);
648
config.getLinkProfiles().getLastProfile().addReq(ms);
651
if (t.name.equals(ELEMENT_LINK_REQ_PROTOCOL))
653
String protocolid = t.getAttrib("protocolid");
654
ReqProtocol rp = new ReqProtocol(protocolid);
655
config.getLinkProfiles().getLastProfile().addReq(rp);
658
if (t.name.equals(ELEMENT_WIRELESS))
660
String value = t.getAttrib("value");
662
if (value.equals(XML_TRISTATE_TRUE))
663
w = new Wireless(1, true);
664
else if (value.equals(XML_TRISTATE_FALSE))
665
w = new Wireless(-1, true);
666
else if (value.equals(XML_TRISTATE_CANBE))
667
w = new Wireless(0, true);
669
//this validation should be done by the DTD
670
throw new XMLValidationException("Invalid Wireless value \"" + value + "\"\nUse either \"" + XML_TRISTATE_TRUE +
671
"\", \"" + XML_TRISTATE_FALSE + "\" or \"" + XML_TRISTATE_CANBE + "\".");
672
config.getLinkProfiles().getLastProfile().addReq(w);
675
if (t.name.equals(ELEMENT_RELIABLE))
677
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
678
Reliable r = new Reliable(value, true);
679
config.getLinkProfiles().getLastProfile().addReq(r);
682
if (t.name.equals(ELEMENT_CONNECTION_ORIENTED))
684
boolean value = Tag.getBooleanValue(t.getAttrib("value"));
685
ConnectionOriented co = new ConnectionOriented(value, true);
686
config.getLinkProfiles().getLastProfile().addReq(co);
689
if (t.name.equals(ELEMENT_LINK_REQ_MAXPING))
691
int value = Tag.getIntValue(t.getAttrib("value"));
692
MaxPing mp = new MaxPing(value);
693
config.getLinkProfiles().getLastProfile().addReq(mp);
696
if (t.name.equals(ELEMENT_LINK_REQ_OTHER))
698
String name = t.getAttrib("name");
699
String comparator = t.getAttrib("comparator");
700
String type = t.getAttrib("type");
701
String value = t.getAttrib("value");
703
if (type.equals(DATA_TYPE_INDICATOR_INT))
705
int intVal = Tag.getIntValue(value);
706
or = new OtherReq(name, intVal, comparator);
708
else if (type.equals(DATA_TYPE_INDICATOR_DOUBLE))
710
double dblVal = Tag.getDoubleValue(value);
711
or = new OtherReq(name, dblVal, comparator);
713
else if (type.equals(DATA_TYPE_INDICATOR_STRING))
714
or = new OtherReq(name, value, comparator);
715
else if (type.equals(DATA_TYPE_INDICATOR_BOOLEAN))
717
boolean booVal = Tag.getBooleanValue(value);
718
or = new OtherReq(name, booVal, comparator);
720
config.getLinkProfiles().getLastProfile().addReq(or);
727
private void doNodeProfiles(Reader in) throws IOException
730
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_NODE_PROFILES)))
732
if (t.name.equals(ELEMENT_NODE_PROFILE))
734
String name = t.getAttrib("name");
735
boolean exactMatchRequired = Tag.getBooleanValue(t.getAttrib("requireExactMatch"));
736
NodeProfile np = new NodeProfile(name, exactMatchRequired);
737
config.getNodeProfiles().addProfile(np);
738
if (!t.terminated) doNodeProfile(in);
745
private void doNodeProfile(Reader in) throws IOException
748
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_NODE_PROFILE)))
750
if (t.name.equals(ELEMENT_NODE_REQS))
760
private void doNodeReqs(Reader in) throws IOException
763
while (((t = nextTag(in)) != null) && (!t.name.equals("/" + ELEMENT_NODE_REQS)))
765
if (t.name.equals(ELEMENT_NODE_REQ_MINSPEED))
767
int value = Tag.getIntValue(t.getAttrib("value"));
768
MinSpeed ms = new MinSpeed(value);
769
config.getNodeProfiles().getLastProfile().addReq(ms);
772
if (t.name.equals(ELEMENT_NODE_REQ_MINMEMORY))
774
int value = Tag.getIntValue(t.getAttrib("value"));
775
MinMemory mm = new MinMemory(value);
776
config.getNodeProfiles().getLastProfile().addReq(mm);
779
if (t.name.equals(ELEMENT_NODE_REQ_OTHER))
781
String name = t.getAttrib("name");
782
String comparator = t.getAttrib("comparator");
783
String type = t.getAttrib("type");
784
String value = t.getAttrib("value");
786
if(type.equals(DATA_TYPE_INDICATOR_INT))
788
int intVal = Tag.getIntValue(value);
789
or = new OtherReq(name, intVal, comparator);
791
else if(type.equals(DATA_TYPE_INDICATOR_DOUBLE))
793
double dblVal = Tag.getDoubleValue(value);
794
or = new OtherReq(name, dblVal, comparator);
796
else if(type.equals(DATA_TYPE_INDICATOR_STRING))
797
or = new OtherReq(name, value, comparator);
798
else if(type.equals(DATA_TYPE_INDICATOR_BOOLEAN))
800
boolean booVal = Tag.getBooleanValue(value);
801
or = new OtherReq(name, booVal, comparator);
803
config.getNodeProfiles().getLastProfile().addReq(or);
810
public JCSPConfig getConfig()
815
private static final int MAX_ATTRIBS = 20;
816
private final String[] attribs = new String[MAX_ATTRIBS];
817
private final String[] values = new String[MAX_ATTRIBS];
819
private Tag nextTag(Reader in) throws IOException
824
boolean terminated = false; //put in for J# compat - is always set
834
} while (isSpace(c));
835
// expect to find a '<' character
837
throw new IOException("Expected '<'");
838
// get the tag name (up to a space)
842
// comment - skip until '>'
853
} while ((!isSpace(c)) && (c != '/') && (c != '>'));
873
// read the attribute name
875
while ((c != '=') && (!isSpace(c)) && (c != '>') && (c != '/'))
877
attribs[i] = attribs[i] + c;
880
// read the attribute value
881
c = nextChar(in); // a quote
884
c = nextChar(in); // skip the quote
888
values[i] = values[i] + c;
896
// skip to the '>' or '/' characters
897
while ((c != '>') && (c != '/'))
902
String[] a = new String[i], v = new String[i];
903
for (int j = 0; j < i; j++)
908
return new Tag(name, a, v, terminated);
911
private boolean isSpace(char c)
913
return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n');
916
private char nextChar(Reader in) throws IOException
920
throw new IOException("Unexpected end of file");
924
private static class Tag
926
public final String name;
927
public final String[] attrib;
928
public final String[] value;
929
public final boolean terminated;
930
public Tag(String name, String[] attrib, String[] value, boolean terminated)
933
this.attrib = attrib;
935
this.terminated = terminated;
937
public String getAttrib(String attr, String def)
939
for (int i = 0; i < attrib.length; i++)
941
if (attr.equals(attrib[i]))
946
public String getAttrib(String attr)
948
return getAttrib(attr, null);
950
public void bad() throws IOException
952
throw new IOException("Unexpected tag - " + name);
954
public static boolean getBooleanValue(String val)
956
if (val.equals(XML_BOOLEAN_TRUE))
958
if (val.equals(XML_BOOLEAN_FALSE))
960
throw new XMLValidationException("expected boolean tag");
962
public static int getIntValue(String val)
964
return Integer.parseInt(val);
966
public static double getDoubleValue(String val)
968
return Double.parseDouble(val);
973
* Thrown in the event of a semantic error in the parsed XML file.
975
* @author Quickstone Technologies Limited
977
public static class XMLValidationException extends RuntimeException
980
* Creates a new exception without a detail message.
982
public XMLValidationException()
988
* Creates a new exception with a detail message.
990
* @param msg the detail message.
992
public XMLValidationException(String msg)
b'\\ No newline at end of file'