--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+package mir.config;\r
+\r
+public class ConfigDefineNotKnownException extends ConfigException {\r
+ public ConfigDefineNotKnownException(String aMessage, String aLocation) {\r
+ super (aMessage, aLocation);\r
+ }\r
+}\r
--- /dev/null
+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
--- /dev/null
+package mir.config;\r
+\r
+public class ConfigInvalidPropertyTypeException extends ConfigException {\r
+ public ConfigInvalidPropertyTypeException(String aMessage, String aLocation) {\r
+ super (aMessage, aLocation);\r
+ }\r
+}\r
--- /dev/null
+package mir.config;\r
+\r
+public class ConfigMissingPropertyException extends ConfigException {\r
+ public ConfigMissingPropertyException(String aMessage, String aLocation) {\r
+ super (aMessage, aLocation);\r
+ }\r
+}\r