initial checkin of the new xml-style configuration classes
authorzapata <zapata>
Sun, 17 Mar 2002 02:32:47 +0000 (02:32 +0000)
committerzapata <zapata>
Sun, 17 Mar 2002 02:32:47 +0000 (02:32 +0000)
source/mir/config/ConfigChecker.java [new file with mode: 0755]
source/mir/config/ConfigNode.java [new file with mode: 0755]
source/mir/config/ConfigNodeBuilder.java [new file with mode: 0755]
source/mir/config/ConfigReader.java [new file with mode: 0755]
source/mir/config/ConfigSimpleNode.java [new file with mode: 0755]
source/mir/config/MirConfiguration.java [new file with mode: 0755]
source/mir/config/exceptions/ConfigDefineNotKnownException.java [new file with mode: 0755]
source/mir/config/exceptions/ConfigException.java [new file with mode: 0755]
source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java [new file with mode: 0755]
source/mir/config/exceptions/ConfigMissingPropertyException.java [new file with mode: 0755]

diff --git a/source/mir/config/ConfigChecker.java b/source/mir/config/ConfigChecker.java
new file mode 100755 (executable)
index 0000000..7d52eb0
--- /dev/null
@@ -0,0 +1,130 @@
+package  mir.config;\r
+\r
+import java.util.*;\r
+\r
+public class ConfigChecker {\r
+  public final static int STRING = 0;\r
+  public final static int INTEGER = 1;\r
+  public final static int BOOLEAN = 2;\r
+  public final static int DOUBLE = 3;\r
+  public final static int PATH = 4;\r
+//  public final static int ABSOLUTEPATH = 5;\r
+//  public final static int ABSOLUTEURL = 6;\r
+\r
+  private Node rootNode;\r
+\r
+  public Node getRootNode() {\r
+    return rootNode;\r
+  }\r
+\r
+  public ConfigChecker() {\r
+    super();\r
+\r
+    rootNode = new Node();\r
+  }\r
+\r
+  public void check(ConfigNode aNode) throws ConfigException {\r
+    getRootNode().check(aNode);\r
+  }\r
+\r
+  public class Node {\r
+\r
+    private Map subNodes;\r
+    private Vector constraints;\r
+\r
+    public Node() {\r
+      subNodes = new HashMap();\r
+      constraints = new Vector();\r
+    }\r
+\r
+    public Node getSubNode(String aName) {\r
+      Node subNode = (Node) subNodes.get(aName);\r
+\r
+      if (subNode==null) {\r
+        subNode = new Node();\r
+        subNodes.put(aName, subNode);\r
+      }\r
+\r
+      return subNode;\r
+    }\r
+\r
+    public void addExistenceConstraint(String aPropertyName) {\r
+      constraints.add(new ExistenceConstraint(aPropertyName));\r
+    }\r
+\r
+    public void addTypeConstraint(String aPropertyName, int aType) {\r
+      constraints.add(new TypeConstraint(aPropertyName, aType));\r
+    }\r
+\r
+    public void addExistenceAndTypeConstraint(String aPropertyName, int aType) {\r
+      addExistenceConstraint(aPropertyName);\r
+      addTypeConstraint(aPropertyName, aType);\r
+    }\r
+\r
+    public void check(ConfigNode aNode) throws ConfigException {\r
+      Iterator iterator;\r
+\r
+      iterator=constraints.iterator();\r
+      while (iterator.hasNext()) {\r
+        ((Constraint) iterator.next()).check(aNode);\r
+      }\r
+\r
+      iterator=subNodes.keySet().iterator();\r
+      while (iterator.hasNext()) {\r
+        Map.Entry entry = (Map.Entry) iterator.next();\r
+        ((Node) entry.getValue()).check(aNode.getSubNode((String) entry.getKey()));\r
+      }\r
+\r
+    }\r
+\r
+    private class Constraint {\r
+      protected String propertyName;\r
+\r
+      Constraint(String aPropertyName) {\r
+        propertyName=aPropertyName;\r
+      }\r
+\r
+      public void check(ConfigNode aNode) throws ConfigException {\r
+      };\r
+    }\r
+\r
+    private class ExistenceConstraint extends Constraint {\r
+      ExistenceConstraint(String aPropertyName) {\r
+        super(aPropertyName);\r
+      }\r
+\r
+      public void check(ConfigNode aNode) throws ConfigException {\r
+        aNode.getRequiredStringProperty(propertyName);\r
+      };\r
+    }\r
+\r
+    private class TypeConstraint extends Constraint {\r
+      private int type;\r
+\r
+      TypeConstraint(String aPropertyName, int aType) {\r
+        super(aPropertyName);\r
+\r
+        type=aType;\r
+      }\r
+\r
+      public void check(ConfigNode aNode) throws ConfigException {\r
+        switch(type) {\r
+          case INTEGER:\r
+            aNode.getOptionalIntegerProperty(propertyName, new Integer(0));\r
+            break;\r
+          case STRING:\r
+            aNode.getOptionalStringProperty(propertyName, "");\r
+            break;\r
+          case DOUBLE:\r
+            aNode.getOptionalDoubleProperty(propertyName, new Double(0.0));\r
+            break;\r
+          case BOOLEAN:\r
+            aNode.getOptionalBooleanProperty(propertyName, Boolean.FALSE);\r
+            break;\r
+          default:\r
+            throw new ConfigException("Invalid value for type in type constraint: "+new Integer(type).toString());\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
diff --git a/source/mir/config/ConfigNode.java b/source/mir/config/ConfigNode.java
new file mode 100755 (executable)
index 0000000..a65ee90
--- /dev/null
@@ -0,0 +1,17 @@
+package  mir.config;\r
+\r
+import java.util.*;\r
+\r
+public interface ConfigNode {\r
+  public String getLocationDescription();\r
+\r
+  public ConfigNode getSubNode(String aSubNodeName);\r
+  public Boolean getRequiredBooleanProperty(String aPropertyName) throws ConfigException;\r
+  public Integer getRequiredIntegerProperty(String aPropertyName) throws ConfigException;\r
+  public String getRequiredStringProperty(String aPropertyName) throws ConfigException;\r
+  public Double getRequiredDoubleProperty(String aPropertyName) throws ConfigException;\r
+  public Boolean getOptionalBooleanProperty(String aPropertyName, Boolean aDefaultValue) throws ConfigException;\r
+  public Integer getOptionalIntegerProperty(String aPropertyName, Integer aDefaultValue) throws ConfigException;\r
+  public String getOptionalStringProperty(String aPropertyName, String aDefaultValue) throws ConfigException;\r
+  public Double getOptionalDoubleProperty(String aPropertyName, Double aDefaultValue) throws ConfigException;\r
+}\r
diff --git a/source/mir/config/ConfigNodeBuilder.java b/source/mir/config/ConfigNodeBuilder.java
new file mode 100755 (executable)
index 0000000..063dbe5
--- /dev/null
@@ -0,0 +1,8 @@
+package  mir.config;\r
+\r
+import java.util.*;\r
+\r
+public interface ConfigNodeBuilder {\r
+  public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription);\r
+  public void addProperty(String aName, String aValue, String aValueDescription, String aLocationDescription);\r
+}
\ No newline at end of file
diff --git a/source/mir/config/ConfigReader.java b/source/mir/config/ConfigReader.java
new file mode 100755 (executable)
index 0000000..bbcdeee
--- /dev/null
@@ -0,0 +1,260 @@
+package  mir.config;\r
+\r
+import java.io.*;\r
+import java.util.*;\r
+import java.lang.System;\r
+import org.xml.sax.helpers.DefaultHandler;\r
+import org.xml.sax.*;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
+\r
+import mir.misc.Location;\r
+\r
+\r
+public class ConfigReader {\r
+  final static String propertyTagName="property";\r
+  final static String propertyNameAttribute="name";\r
+  final static String propertyValueAttribute="value";\r
+  final static String defineTagName="define";\r
+  final static String defineNameAttribute="name";\r
+  final static String defineValueAttribute="value";\r
+  final static String includeTagName="include";\r
+  final static String includeFileAttribute="file";\r
+\r
+  public ConfigReader() {\r
+    super();\r
+  };\r
+\r
+  public void parseFile(String aFileName, ConfigNodeBuilder aRootNode) throws ConfigException {\r
+\r
+    try {\r
+      SAXParserFactory parserFactory = SAXParserFactory.newInstance();\r
+\r
+      parserFactory.setNamespaceAware(false);\r
+      parserFactory.setValidating(true);\r
+\r
+\r
+      ConfigReaderHandler handler = new ConfigReaderHandler(aRootNode, parserFactory);\r
+\r
+      handler.includeFile(aFileName);\r
+    }\r
+    catch (Throwable e) {\r
+      if (e instanceof SAXParseException && ((SAXParseException) e).getException() instanceof ConfigException) {\r
+        throw (ConfigException) ((SAXParseException) e).getException();\r
+      }\r
+      else {\r
+        e.printStackTrace();\r
+        throw new ConfigException( e.getMessage() );\r
+      }\r
+    }\r
+  }\r
+\r
+  private class ConfigReaderHandler extends DefaultHandler {\r
+    ConfigNodeBuilder builder;\r
+    Stack nodeStack;\r
+    Locator locator;\r
+    DefinesManager definesManager;\r
+    int level;\r
+    Stack includeFileStack;\r
+    SAXParserFactory parserFactory;\r
+\r
+    public ConfigReaderHandler(ConfigNodeBuilder aBuilder, SAXParserFactory aParserFactory) {\r
+      super();\r
+\r
+      builder=aBuilder;\r
+      nodeStack=new Stack();\r
+      includeFileStack=new Stack();\r
+      definesManager=new DefinesManager();\r
+      parserFactory=aParserFactory;\r
+      level=0;\r
+    }\r
+\r
+    public String getLocatorDescription(Locator aLocator) {\r
+      return aLocator.getPublicId()+" ("+aLocator.getLineNumber()+")";\r
+    }\r
+\r
+    public void setDocumentLocator(Locator aLocator) {\r
+      locator=aLocator;\r
+    }\r
+\r
+    private void includeFile(String aFileName) throws ConfigException, SAXParseException, SAXException {\r
+      File file;\r
+      SAXParser parser;\r
+      InputSource inputSource;\r
+      System.err.println("about to include "+aFileName);\r
+\r
+      try {\r
+        if (!includeFileStack.empty())\r
+          file = new File(new File((String) includeFileStack.peek()).getParent(), aFileName);\r
+        else\r
+          file = new File(aFileName);\r
+\r
+        System.err.println("about to include "+file.getCanonicalPath());\r
+\r
+        if (includeFileStack.contains(file.getCanonicalPath())) {\r
+          throw new ConfigException("recursive inclusion of file "+file.getCanonicalPath(), getLocatorDescription(locator));\r
+        }\r
+\r
+        parser=parserFactory.newSAXParser();\r
+\r
+        inputSource = new InputSource(new FileInputStream(file));\r
+        inputSource.setPublicId(file.getCanonicalPath());\r
+\r
+        includeFileStack.push(file.getCanonicalPath());\r
+        try {\r
+          parser.parse(inputSource, this);\r
+        }\r
+        finally {\r
+          includeFileStack.pop();\r
+        }\r
+      }\r
+      catch (ParserConfigurationException e) {\r
+        throw new ConfigException("Internal exception while including \""+aFileName+"\": "+e.getMessage(), e, getLocatorDescription(locator));\r
+      }\r
+      catch (SAXParseException e) {\r
+        throw e;\r
+      }\r
+      catch (ConfigException e) {\r
+        throw e;\r
+      }\r
+      catch (FileNotFoundException e) {\r
+        throw new ConfigException("Include file \""+aFileName+"\" not found: "+e.getMessage(), e, getLocatorDescription(locator));\r
+      }\r
+      catch (IOException e) {\r
+        throw new ConfigException("unable to open include file \""+aFileName+"\": "+e.getMessage(), e, getLocatorDescription(locator));\r
+      }\r
+\r
+    }\r
+\r
+    public void startElement(String aUri, String aTag, String aQualifiedName, Attributes anAttributes) throws SAXException {\r
+      nodeStack.push(builder);\r
+      level++;\r
+      try {\r
+        if (builder==null) {\r
+          throw new ConfigException("define, include and property tags cannot have content", getLocatorDescription(locator));\r
+        }\r
+        if (aQualifiedName.equals(propertyTagName)) {\r
+          String name=anAttributes.getValue(propertyNameAttribute);\r
+          String value=anAttributes.getValue(propertyValueAttribute);\r
+\r
+          if (name==null) {\r
+            throw new ConfigException("property has no name attribute", getLocatorDescription(locator));\r
+          }\r
+          else\r
+          if (value==null) {\r
+            throw new ConfigException("property \""+name+"\" has no value attribute", getLocatorDescription(locator));\r
+          }\r
+\r
+          builder.addProperty(name, definesManager.resolve(value, getLocatorDescription(locator)), value, getLocatorDescription(locator));\r
+          builder=null;\r
+\r
+        }\r
+        else if (aQualifiedName.equals(defineTagName)) {\r
+          String name=anAttributes.getValue(defineNameAttribute);\r
+          String value=anAttributes.getValue(defineValueAttribute);\r
+\r
+          if (name==null) {\r
+            throw new ConfigException("define has no name attribute", getLocatorDescription(locator));\r
+          }\r
+          else\r
+          if (value==null) {\r
+            throw new ConfigException("define \""+name+"\" has no value attribute", getLocatorDescription(locator));\r
+          }\r
+\r
+          definesManager.addDefine(name, definesManager.resolve(value, getLocatorDescription(locator)));\r
+          builder=null;\r
+        }\r
+        else if (aQualifiedName.equals(includeTagName)) {\r
+          String fileName=anAttributes.getValue(includeFileAttribute);\r
+\r
+          if (fileName==null) {\r
+            throw new ConfigException("include has no file attribute", getLocatorDescription(locator));\r
+          }\r
+\r
+          includeFile(definesManager.resolve(fileName, getLocatorDescription(locator)));\r
+          builder=null;\r
+        }\r
+        else\r
+        {\r
+          builder=builder.makeSubNode(aQualifiedName, getLocatorDescription(locator));\r
+        }\r
+      }\r
+      catch (ConfigException e) {\r
+        throw new SAXParseException(e.getMessage(), locator, e);\r
+      }\r
+    }\r
+\r
+    public void endElement(String aUri, String aTag, String aQualifiedName) throws SAXParseException {\r
+      builder=(ConfigNodeBuilder) nodeStack.pop();\r
+      level--;\r
+    }\r
+\r
+    public void characters(char[] aBuffer, int aStart, int anEnd) throws SAXParseException {\r
+      String text = new String(aBuffer, aStart, anEnd).trim();\r
+      if ( text.length() > 0) {\r
+        throw new SAXParseException("Text not allowed", locator, new ConfigException("text not allowed", getLocatorDescription(locator)));\r
+      }\r
+    }\r
+  }\r
+\r
+  private class DefinesManager {\r
+    Map defines;\r
+\r
+    public DefinesManager() {\r
+      defines = new HashMap();\r
+    }\r
+\r
+    public void addDefine(String aName, String anExpression) {\r
+      defines.put(aName, anExpression);\r
+    }\r
+\r
+    public String resolve(String anExpression, String aLocation) throws ConfigException {\r
+      int previousPosition = 0;\r
+      int position;\r
+      int endOfNamePosition;\r
+      String name;\r
+\r
+      StringBuffer result = new StringBuffer();\r
+\r
+      while ((position=anExpression.indexOf("$", previousPosition))>=0) {\r
+        result.append(anExpression.substring(previousPosition, position));\r
+\r
+        if (position>=anExpression.length()-1) {\r
+          result.append(anExpression.substring(position, anExpression.length()));\r
+          previousPosition=anExpression.length();\r
+        }\r
+        else\r
+        {\r
+          if (anExpression.charAt(position+1) == '{') {\r
+            endOfNamePosition=anExpression.indexOf('}', position);\r
+            if (endOfNamePosition>=0) {\r
+              name=anExpression.substring(position+2, endOfNamePosition);\r
+              if (defines.containsKey(name)) {\r
+                result.append((String) defines.get(name));\r
+                previousPosition=endOfNamePosition+1;\r
+              }\r
+              else {\r
+                throw new ConfigDefineNotKnownException("Variable \""+name+"\" not defined", aLocation);\r
+              }\r
+            }\r
+            else {\r
+                throw new ConfigException("Missing }", aLocation);\r
+            }\r
+\r
+          }\r
+          else\r
+          {\r
+            previousPosition=position+2;\r
+            result.append(anExpression.charAt(position+1));\r
+          }\r
+        }\r
+      }\r
+      result.append(anExpression.substring(previousPosition, anExpression.length()));\r
+\r
+      return result.toString();\r
+    }\r
+  }\r
+}\r
+\r
+\r
diff --git a/source/mir/config/ConfigSimpleNode.java b/source/mir/config/ConfigSimpleNode.java
new file mode 100755 (executable)
index 0000000..4a02a25
--- /dev/null
@@ -0,0 +1,229 @@
+package  mir.config;\r
+\r
+import java.util.*;\r
+\r
+public class ConfigSimpleNode implements ConfigNode, ConfigNodeBuilder {\r
+  private Map properties;\r
+  private Map subNodes;\r
+  private String locationDescription;\r
+  private String path;\r
+\r
+  public ConfigSimpleNode() {\r
+    this("", "");\r
+  }\r
+\r
+  public ConfigSimpleNode(String aLocationDescription) {\r
+    this("", aLocationDescription);\r
+  }\r
+\r
+  public ConfigSimpleNode(String aPath, String aLocationDescription) {\r
+    super ();\r
+\r
+    path = aPath;\r
+    locationDescription = aLocationDescription;\r
+    properties = new HashMap();\r
+    subNodes = new HashMap();\r
+  }\r
+\r
+// ConfigNodeBuilder helpers:\r
+\r
+  private String makeSubNodePath(String aSubNode) {\r
+    if (path!=null && path.length()>0)\r
+      return path+"/"+aSubNode;\r
+    else\r
+      return aSubNode;\r
+  }\r
+\r
+  private String makePropertyPath(String aProperty) {\r
+    if (path!=null && path.length()>0)\r
+      return path+"/"+aProperty;\r
+    else\r
+      return aProperty;\r
+  }\r
+\r
+  public ConfigNodeBuilder mimicSubNode(String aName, String aLocationDescription) {\r
+    ConfigNodeBuilder result = new ConfigSimpleNode(makeSubNodePath(aName), aLocationDescription);\r
+\r
+    return result;\r
+  }\r
+\r
+// ConfigNodeBuilder methods:\r
+\r
+  public ConfigNodeBuilder makeSubNode(String aName, String aLocationDescription) {\r
+    if (subNodes.containsKey(aName)) {\r
+      return (ConfigNodeBuilder) subNodes.get(aName);\r
+    }\r
+    else {\r
+      ConfigNodeBuilder result = mimicSubNode(aName, aLocationDescription);\r
+      subNodes.put(aName, result);\r
+\r
+      return result;\r
+    }\r
+  }\r
+\r
+  public void addProperty(String aName, String aValue, String anUnexpandedValue, String aLocationDescription) {\r
+    properties.put(aName, new property(aValue, anUnexpandedValue, aLocationDescription, makePropertyPath(aName)));\r
+  }\r
+\r
+// ConfigNode helpers\r
+\r
+  public boolean hasProperty(String aPropertyName) {\r
+    return properties.containsKey(aPropertyName);\r
+  }\r
+\r
+  public property getProperty(String aPropertyName) {\r
+    return (property) properties.get(aPropertyName);\r
+  }\r
+\r
+  private property getRequiredProperty(String aPropertyName) throws ConfigMissingPropertyException {\r
+    if (!hasProperty(aPropertyName)) {\r
+      throw new ConfigMissingPropertyException("required property \""+aPropertyName+"\" not found", getLocationDescription());\r
+    }\r
+\r
+    return getProperty(aPropertyName);\r
+  }\r
+\r
+\r
+// ConfigNode methods:\r
+\r
+  public String getLocationDescription() {\r
+    return getPath()+" ("+locationDescription+")";\r
+  };\r
+\r
+  public String getPath() {\r
+    return path;\r
+  };\r
+\r
+\r
+  public ConfigNode getSubNode(String aSubNodeName) {\r
+    if (subNodes.containsKey(aSubNodeName)) {\r
+      return (ConfigNode) subNodes.get(aSubNodeName);\r
+    }\r
+    else\r
+    {\r
+      return (ConfigNode) mimicSubNode(aSubNodeName, locationDescription);\r
+    }\r
+  }\r
+\r
+  public Boolean getRequiredBooleanProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException {\r
+    return getRequiredProperty(aPropertyName).interpretAsBoolean();\r
+  }\r
+\r
+  public Integer getRequiredIntegerProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException {\r
+    return getRequiredProperty(aPropertyName).interpretAsInteger();\r
+  }\r
+\r
+  public String getRequiredStringProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException {\r
+    return getRequiredProperty(aPropertyName).interpretAsString();\r
+  }\r
+\r
+  public Double getRequiredDoubleProperty(String aPropertyName) throws ConfigMissingPropertyException, ConfigInvalidPropertyTypeException {\r
+    return getRequiredProperty(aPropertyName).interpretAsDouble();\r
+  }\r
+\r
+\r
+  public Boolean getOptionalBooleanProperty(String aPropertyName, Boolean aDefaultValue) throws ConfigInvalidPropertyTypeException {\r
+    if (!hasProperty(aPropertyName)) {\r
+      return aDefaultValue;\r
+    }\r
+    else {\r
+      return getProperty(aPropertyName).interpretAsBoolean();\r
+    }\r
+  }\r
+\r
+  public Integer getOptionalIntegerProperty(String aPropertyName, Integer aDefaultValue) throws ConfigInvalidPropertyTypeException {\r
+    if (!hasProperty(aPropertyName)) {\r
+      return aDefaultValue;\r
+    }\r
+    else {\r
+      return getProperty(aPropertyName).interpretAsInteger();\r
+    }\r
+  }\r
+\r
+  public String getOptionalStringProperty(String aPropertyName, String aDefaultValue) throws ConfigInvalidPropertyTypeException {\r
+    if (!hasProperty(aPropertyName)) {\r
+      return aDefaultValue;\r
+    }\r
+    else {\r
+      return getProperty(aPropertyName).interpretAsString();\r
+    }\r
+  }\r
+\r
+  public Double getOptionalDoubleProperty(String aPropertyName, Double aDefaultValue) throws ConfigInvalidPropertyTypeException {\r
+    if (!hasProperty(aPropertyName)) {\r
+      return aDefaultValue;\r
+    }\r
+    else {\r
+      return getProperty(aPropertyName).interpretAsDouble();\r
+    }\r
+  }\r
+\r
+// property helper class\r
+\r
+  private class property {\r
+    private String value;\r
+    private String unexpandedValue;\r
+    private String path;\r
+    private String locationDescription;\r
+\r
+    public property( String aValue, String anUnexpandedValue, String aLocationDescription, String aPath ) {\r
+      value = aValue;\r
+      unexpandedValue = anUnexpandedValue;\r
+      locationDescription = aLocationDescription;\r
+      path = aPath;\r
+    }\r
+\r
+    public String getValue() {\r
+      return value;\r
+    }\r
+\r
+    public String getUnexpandedValue() {\r
+      return unexpandedValue;\r
+    }\r
+\r
+    public String getPath() {\r
+      return path;\r
+    }\r
+\r
+    public String getLocationDescription() {\r
+      return getPath()+" ("+locationDescription+")";\r
+    }\r
+\r
+    public String getValueDescription() {\r
+      return "\""+value+"\" (\""+unexpandedValue+"\")";\r
+    }\r
+\r
+    public Boolean interpretAsBoolean() throws ConfigInvalidPropertyTypeException {\r
+      if (value.equals("1"))\r
+        return Boolean.TRUE;\r
+      else if (value.equals("0"))\r
+        return Boolean.FALSE;\r
+      else\r
+        throw new ConfigInvalidPropertyTypeException(getValueDescription() + " is not a boolean", getLocationDescription());\r
+    }\r
+\r
+    public String interpretAsString() throws ConfigInvalidPropertyTypeException {\r
+      return value;\r
+    }\r
+\r
+    public Integer interpretAsInteger() throws ConfigInvalidPropertyTypeException {\r
+      try {\r
+        return Integer.valueOf(value);\r
+      }\r
+      catch (Throwable e) {\r
+        throw new ConfigInvalidPropertyTypeException("\""+value+"\" (\""+unexpandedValue+"\") is not an integer", getLocationDescription());\r
+      }\r
+    }\r
+\r
+    public Double interpretAsDouble() throws ConfigInvalidPropertyTypeException {\r
+      try {\r
+        return Double.valueOf(value);\r
+      }\r
+      catch (Throwable e) {\r
+        throw new ConfigInvalidPropertyTypeException("\""+value+"\" (\""+unexpandedValue+"\") is not a double", getLocationDescription());\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
diff --git a/source/mir/config/MirConfiguration.java b/source/mir/config/MirConfiguration.java
new file mode 100755 (executable)
index 0000000..e3730df
--- /dev/null
@@ -0,0 +1,27 @@
+package  mir.config;\r
+\r
+//import  java.net.*;\r
+//import  java.io.*;\r
+//import  java.util.*;\r
+//import  java.lang.*;\r
+\r
+public class MirConfiguration {\r
+  private ConfigNode rootNode;\r
+\r
+  public MirConfiguration(ConfigNode aRootNode) {\r
+    super();\r
+    rootNode = aRootNode;\r
+  }\r
+\r
+  public MirConfiguration(String aFileName) throws ConfigException {\r
+    super();\r
+    rootNode = new ConfigSimpleNode();\r
+\r
+    (new ConfigReader()).parseFile(aFileName,(ConfigNodeBuilder) rootNode);\r
+  }\r
+\r
+  public ConfigNode getRootNode() {\r
+    return rootNode;\r
+  }\r
+}\r
+\r
diff --git a/source/mir/config/exceptions/ConfigDefineNotKnownException.java b/source/mir/config/exceptions/ConfigDefineNotKnownException.java
new file mode 100755 (executable)
index 0000000..a527d34
--- /dev/null
@@ -0,0 +1,7 @@
+package mir.config;\r
+\r
+public class ConfigDefineNotKnownException extends ConfigException {\r
+  public ConfigDefineNotKnownException(String aMessage, String aLocation) {\r
+    super (aMessage, aLocation);\r
+  }\r
+}\r
diff --git a/source/mir/config/exceptions/ConfigException.java b/source/mir/config/exceptions/ConfigException.java
new file mode 100755 (executable)
index 0000000..5b3b572
--- /dev/null
@@ -0,0 +1,23 @@
+package mir.config;\r
+\r
+import java.io.*;\r
+\r
+public class ConfigException extends Exception {\r
+  private String locationDescription;\r
+  private Throwable cause;\r
+\r
+  public ConfigException (String aMessage, Throwable aCause, String aLocationDescription) {\r
+    super ("Configuration error at "+aLocationDescription+": "+aMessage);\r
+\r
+    locationDescription = aLocationDescription;\r
+    cause = aCause;\r
+  }\r
+\r
+  public ConfigException (String aMessage, String aLocationDescription) {\r
+    this (aMessage, (Throwable) null, aLocationDescription);\r
+  }\r
+\r
+  public ConfigException (String aMessage) {\r
+    this (aMessage, (Throwable) null, "?");\r
+  }\r
+}\r
diff --git a/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java b/source/mir/config/exceptions/ConfigInvalidPropertyTypeException.java
new file mode 100755 (executable)
index 0000000..6ea5a90
--- /dev/null
@@ -0,0 +1,7 @@
+package mir.config;\r
+\r
+public class ConfigInvalidPropertyTypeException extends ConfigException {\r
+  public ConfigInvalidPropertyTypeException(String aMessage, String aLocation) {\r
+    super (aMessage, aLocation);\r
+  }\r
+}\r
diff --git a/source/mir/config/exceptions/ConfigMissingPropertyException.java b/source/mir/config/exceptions/ConfigMissingPropertyException.java
new file mode 100755 (executable)
index 0000000..af059ef
--- /dev/null
@@ -0,0 +1,7 @@
+package mir.config;\r
+\r
+public class ConfigMissingPropertyException extends ConfigException {\r
+  public ConfigMissingPropertyException(String aMessage, String aLocation) {\r
+    super (aMessage, aLocation);\r
+  }\r
+}\r