1c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort/* 2c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Copyright (C) 2009 The Android Open Source Project 3c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 4c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Licensed under the Apache License, Version 2.0 (the "License"); 5c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * you may not use this file except in compliance with the License. 6c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * You may obtain a copy of the License at 7c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 8c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * http://www.apache.org/licenses/LICENSE-2.0 9c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 10c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Unless required by applicable law or agreed to in writing, software 11c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * distributed under the License is distributed on an "AS IS" BASIS, 12c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * See the License for the specific language governing permissions and 14c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * limitations under the License. 15c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 16c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 17c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortpackage com.android.internal.util; 18c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 19c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.io.IOException; 20c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.io.Reader; 21c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.io.StreamTokenizer; 22c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.util.HashMap; 23c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.util.Map; 24c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortimport java.util.regex.Pattern; 25c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 26c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort/** 27c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * A {@code Map} that publishes a set of typed properties, defined by 28c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * zero or more {@code Reader}s containing textual definitions and assignments. 29c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 30c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bortpublic class TypedProperties extends HashMap<String, Object> { 31c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 32c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Instantiates a {@link java.io.StreamTokenizer} and sets its syntax tables 33c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * appropriately for the {@code TypedProperties} file format. 34c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 35c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param r The {@code Reader} that the {@code StreamTokenizer} will read from 36c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return a newly-created and initialized {@code StreamTokenizer} 37c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 38c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static StreamTokenizer initTokenizer(Reader r) { 39c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort StreamTokenizer st = new StreamTokenizer(r); 40c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 41c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Treat everything we don't specify as "ordinary". 42c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.resetSyntax(); 43c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 44c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* The only non-quoted-string words we'll be reading are: 45c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * - property names: [._$a-zA-Z0-9] 465b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * - type names: [a-zS] 47c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * - number literals: [-0-9.eExXA-Za-z] ('x' for 0xNNN hex literals. "NaN", "Infinity") 48c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * - "true" or "false" (case insensitive): [a-zA-Z] 49c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 50c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('0', '9'); 51c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('A', 'Z'); 52c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('a', 'z'); 53c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('_', '_'); 54c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('$', '$'); 55c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('.', '.'); 56c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('-', '-'); 57c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.wordChars('+', '+'); 58c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 59c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Single-character tokens 60c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.ordinaryChar('='); 61c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 62c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Other special characters 63c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.whitespaceChars(' ', ' '); 64c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.whitespaceChars('\t', '\t'); 655b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort st.whitespaceChars('\n', '\n'); 665b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort st.whitespaceChars('\r', '\r'); 67c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.quoteChar('"'); 68c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 695b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort // Java-style comments 705b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort st.slashStarComments(true); 715b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort st.slashSlashComments(true); 72c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 73c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return st; 74c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 75c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 76c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 77c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 78c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * An unchecked exception that is thrown when encountering a syntax 79c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * or semantic error in the input. 80c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 81c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public static class ParseException extends IllegalArgumentException { 82c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort ParseException(StreamTokenizer state, String expected) { 83c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort super("expected " + expected + ", saw " + state.toString()); 84c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 85c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 86c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 87c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // A sentinel instance used to indicate a null string. 88c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final String NULL_STRING = new String("<TypedProperties:NULL_STRING>"); 89c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 90c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Constants used to represent the supported types. 91c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_UNSET = 'x'; 92c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_BOOLEAN = 'Z'; 93c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_BYTE = 'I' | 1 << 8; 94c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // TYPE_CHAR: character literal syntax not supported; use short. 95c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_SHORT = 'I' | 2 << 8; 96c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_INT = 'I' | 4 << 8; 97c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_LONG = 'I' | 8 << 8; 98c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_FLOAT = 'F' | 4 << 8; 99c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_DOUBLE = 'F' | 8 << 8; 100c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_STRING = 'L' | 's' << 8; 101c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static final int TYPE_ERROR = -1; 102c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 103c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 1045b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * Converts a string to an internal type constant. 105c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 106c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param typeName the type name to convert 107c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the type constant that corresponds to {@code typeName}, 108c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * or {@code TYPE_ERROR} if the type is unknown 109c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 110c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static int interpretType(String typeName) { 1115b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if ("unset".equals(typeName)) { 112c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_UNSET; 1135b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("boolean".equals(typeName)) { 114c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_BOOLEAN; 1155b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("byte".equals(typeName)) { 116c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_BYTE; 1175b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("short".equals(typeName)) { 118c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_SHORT; 1195b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("int".equals(typeName)) { 120c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_INT; 1215b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("long".equals(typeName)) { 122c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_LONG; 1235b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("float".equals(typeName)) { 124c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_FLOAT; 1255b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("double".equals(typeName)) { 126c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_DOUBLE; 1275b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("String".equals(typeName)) { 128c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_STRING; 129c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 130c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return TYPE_ERROR; 131c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 132c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 133c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 134c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Parses the data in the reader. 135c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 136c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param r The {@code Reader} containing input data to parse 137c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param map The {@code Map} to insert parameter values into 138c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws ParseException if the input data is malformed 139c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws IOException if there is a problem reading from the {@code Reader} 140c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 141c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static void parse(Reader r, Map<String, Object> map) throws ParseException, IOException { 142c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final StreamTokenizer st = initTokenizer(r); 143c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 144c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* A property name must be a valid fully-qualified class + package name. 145c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * We don't support Unicode, though. 146c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 147c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final String identifierPattern = "[a-zA-Z_$][0-9a-zA-Z_$]*"; 148c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final Pattern propertyNamePattern = 149c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Pattern.compile("(" + identifierPattern + "\\.)*" + identifierPattern); 150c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 151c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 152c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort while (true) { 153c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort int token; 154c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 1555b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort // Read the next token, which is either the type or EOF. 1565b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort token = st.nextToken(); 1575b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (token == StreamTokenizer.TT_EOF) { 158c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort break; 1595b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 1605b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (token != StreamTokenizer.TT_WORD) { 1615b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort throw new ParseException(st, "type name"); 1625b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 1635b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort final int type = interpretType(st.sval); 1645b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (type == TYPE_ERROR) { 1655b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort throw new ParseException(st, "valid type name"); 1665b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 1675b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort st.sval = null; 1685b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort 1695b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (type == TYPE_UNSET) { 1705b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort // Expect '('. 1715b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort token = st.nextToken(); 1725b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (token != '(') { 1735b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort throw new ParseException(st, "'('"); 1745b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 175c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 176c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 177c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Read the property name. 178c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort token = st.nextToken(); 179c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token != StreamTokenizer.TT_WORD) { 180c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "property name"); 181c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 182c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final String propertyName = st.sval; 183c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (!propertyNamePattern.matcher(propertyName).matches()) { 184c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "valid property name"); 185c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 186c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort st.sval = null; 187c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 188c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (type == TYPE_UNSET) { 1895b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort // Expect ')'. 1905b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort token = st.nextToken(); 1915b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (token != ')') { 1925b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort throw new ParseException(st, "')'"); 1935b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 194c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort map.remove(propertyName); 195c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else { 196c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Expect '='. 197c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort token = st.nextToken(); 198c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token != '=') { 199c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "'='"); 200c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 201c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 202c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Read a value of the appropriate type, and insert into the map. 203c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final Object value = parseValue(st, type); 204c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final Object oldValue = map.remove(propertyName); 205c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (oldValue != null) { 206c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // TODO: catch the case where a string is set to null and then 207c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // the same property is defined with a different type. 208c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value.getClass() != oldValue.getClass()) { 209c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, 210c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort "(property previously declared as a different type)"); 211c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 212c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 213c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort map.put(propertyName, value); 214c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 215c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 2165b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort // Expect ';'. 2175b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort token = st.nextToken(); 2185b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if (token != ';') { 2195b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort throw new ParseException(st, "';'"); 2205b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } 221c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 222c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 223c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 224c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 225c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Parses the next token in the StreamTokenizer as the specified type. 226c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 227c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param st The token source 228c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param type The type to interpret next token as 229c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return a Boolean, Number subclass, or String representing the value. 230c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Null strings are represented by the String instance NULL_STRING 231c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws IOException if there is a problem reading from the {@code StreamTokenizer} 232c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 233c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort static Object parseValue(StreamTokenizer st, final int type) throws IOException { 234c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort final int token = st.nextToken(); 235c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 236c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (type == TYPE_BOOLEAN) { 237c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token != StreamTokenizer.TT_WORD) { 238c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "boolean constant"); 239c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 240c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 2415b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort if ("true".equals(st.sval)) { 242c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return Boolean.TRUE; 2435b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if ("false".equals(st.sval)) { 244c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return Boolean.FALSE; 245c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 246c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 247c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "boolean constant"); 248c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else if ((type & 0xff) == 'I') { 249c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token != StreamTokenizer.TT_WORD) { 250c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "integer constant"); 251c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 252c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 253c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* Parse the string. Long.decode() handles C-style integer constants 254c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * ("0x" -> hex, "0" -> octal). It also treats numbers with a prefix of "#" as 255c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * hex, but our syntax intentionally does not list '#' as a word character. 256c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 257c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort long value; 258c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort try { 259c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort value = Long.decode(st.sval); 260c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } catch (NumberFormatException ex) { 261c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "integer constant"); 262c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 263c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 264c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Ensure that the type can hold this value, and return. 265c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort int width = (type >> 8) & 0xff; 266c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort switch (width) { 267c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort case 1: 268c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { 269c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "8-bit integer constant"); 270c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 271c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Byte((byte)value); 272c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort case 2: 273c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { 274c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "16-bit integer constant"); 275c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 276c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Short((short)value); 277c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort case 4: 278c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { 279c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "32-bit integer constant"); 280c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 281c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Integer((int)value); 282c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort case 8: 283c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) { 284c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "64-bit integer constant"); 285c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 286c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Long(value); 287c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort default: 288c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new IllegalStateException( 289c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort "Internal error; unexpected integer type width " + width); 290c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 291c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else if ((type & 0xff) == 'F') { 292c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token != StreamTokenizer.TT_WORD) { 293c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "float constant"); 294c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 295c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 296c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Parse the string. 297c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* TODO: Maybe just parse as float or double, losing precision if necessary. 298c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Parsing as double and converting to float can change the value 299c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * compared to just parsing as float. 300c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 301c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort double value; 302c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort try { 303c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* TODO: detect if the string representation loses precision 304c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * when being converted to a double. 305c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 306c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort value = Double.parseDouble(st.sval); 307c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } catch (NumberFormatException ex) { 308c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "float constant"); 309c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 310c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 311c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Ensure that the type can hold this value, and return. 312c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (((type >> 8) & 0xff) == 4) { 313c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // This property is a float; make sure the value fits. 314c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort double absValue = Math.abs(value); 315c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (absValue != 0.0 && !Double.isInfinite(value) && !Double.isNaN(value)) { 316c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (absValue < Float.MIN_VALUE || absValue > Float.MAX_VALUE) { 317c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "32-bit float constant"); 318c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 319c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 320c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Float((float)value); 321c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else { 322c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // This property is a double; no need to truncate. 323c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return new Double(value); 324c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 325c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else if (type == TYPE_STRING) { 326c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort // Expect a quoted string or the word "null". 327c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (token == '"') { 328c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return st.sval; 3295b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort } else if (token == StreamTokenizer.TT_WORD && "null".equals(st.sval)) { 330c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return NULL_STRING; 331c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 332c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new ParseException(st, "double-quoted string or 'null'"); 333c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 334c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 335c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new IllegalStateException("Internal error; unknown type " + type); 336c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 337c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 338c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 339c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 340c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Creates an empty TypedProperties instance. 341c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 342c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public TypedProperties() { 343c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort super(); 344c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 345c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 346c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 347c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Loads zero or more properties from the specified Reader. 348c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Properties that have already been loaded are preserved unless 349c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * the new Reader overrides or unsets earlier values for the 350c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * same properties. 3515b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 352c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * File syntax: 3535b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <blockquote> 3545b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <tt> 3555b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <type> <property-name> = <value> ; 3565b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <br /> 3575b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * unset ( <property-name> ) ; 3585b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * </tt> 3595b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 3605b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * "//" comments everything until the end of the line. 3615b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * "/a;" comments everything until the next appearance of "a;/". 3625b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 363c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Blank lines are ignored. 3645b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 3655b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * The only required whitespace is between the type and 3665b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * the property name. 3675b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 3685b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <type> is one of {boolean, byte, short, int, long, 3695b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * float, double, String}, and is case-sensitive. 3705b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 371c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * <property-name> is a valid fully-qualified class name 372c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * (one or more valid identifiers separated by dot characters). 3735b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 374c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * <value> depends on the type: 3755b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <ul> 3765b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <li> boolean: one of {true, false} (case-sensitive) 3775b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <li> byte, short, int, long: a valid Java integer constant 3785b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * (including non-base-10 constants like 0xabc and 074) 3795b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * whose value does not overflow the type. NOTE: these are 3805b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * interpreted as Java integer values, so they are all signed. 3815b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <li> float, double: a valid Java floating-point constant. 3825b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * If the type is float, the value must fit in 32 bits. 3835b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <li> String: a double-quoted string value, or the word {@code null}. 3845b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * NOTE: the contents of the string must be 7-bit clean ASCII; 3855b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * C-style octal escapes are recognized, but Unicode escapes are not. 3865b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * </ul> 3875b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * <p> 3885b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * Passing a property-name to {@code unset()} will unset the property, 3895b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * removing its value and type information, as if it had never been 3905b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * defined. 3915b6f8d865d03f37c8c3a9397ca693ac671f39df7Dave Bort * </blockquote> 392c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 393c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param r The Reader to load properties from 394c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws IOException if an error occurs when reading the data 395c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws IllegalArgumentException if the data is malformed 396c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 397c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public void load(Reader r) throws IOException { 398c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort parse(r, this); 399c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 400c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 401c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort @Override 402c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public Object get(Object key) { 403c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(key); 404c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == NULL_STRING) { 405c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return null; 406c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 407c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return value; 408c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 409c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 410c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* 411c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Getters with explicit defaults 412c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 413c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 414c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 4154e8620f868e2490782ebb960404140ea9482c91dBen Dodson * An unchecked exception that is thrown if a {@code get<TYPE>()} method 416c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * is used to retrieve a parameter whose type does not match the method name. 417c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 418c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public static class TypeException extends IllegalArgumentException { 419c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort TypeException(String property, Object value, String requestedType) { 420c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort super(property + " has type " + value.getClass().getName() + 421c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort ", not " + requestedType); 422c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 423c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 424c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 425c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 426c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a boolean property, or the default if the property 427c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 428c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 429c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 430c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 431c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 432c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a boolean 433c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 434c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public boolean getBoolean(String property, boolean def) { 435c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 436c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 437c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 438c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 439c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Boolean) { 440c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Boolean)value).booleanValue(); 441c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 442c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "boolean"); 443c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 444c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 445c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 446c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a byte property, or the default if the property 447c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 448c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 449c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 450c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 451c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 452c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a byte 453c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 454c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public byte getByte(String property, byte def) { 455c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 456c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 457c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 458c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 459c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Byte) { 460c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Byte)value).byteValue(); 461c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 462c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "byte"); 463c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 464c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 465c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 466c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a short property, or the default if the property 467c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 468c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 469c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 470c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 471c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 472c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a short 473c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 474c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public short getShort(String property, short def) { 475c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 476c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 477c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 478c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 479c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Short) { 480c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Short)value).shortValue(); 481c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 482c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "short"); 483c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 484c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 485c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 486c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of an integer property, or the default if the property 487c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 488c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 489c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 490c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 491c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 492c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not an integer 493c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 494c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public int getInt(String property, int def) { 495c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 496c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 497c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 498c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 499c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Integer) { 500c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Integer)value).intValue(); 501c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 502c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "int"); 503c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 504c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 505c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 506c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a long property, or the default if the property 507c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 508c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 509c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 510c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 511c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 512c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a long 513c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 514c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public long getLong(String property, long def) { 515c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 516c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 517c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 518c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 519c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Long) { 520c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Long)value).longValue(); 521c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 522c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "long"); 523c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 524c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 525c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 526c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a float property, or the default if the property 527c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 528c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 529c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 530c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 531c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 532c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a float 533c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 534c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public float getFloat(String property, float def) { 535c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 536c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 537c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 538c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 539c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Float) { 540c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Float)value).floatValue(); 541c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 542c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "float"); 543c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 544c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 545c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 546c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a double property, or the default if the property 547c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 548c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 549c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 550c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 551c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 552c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a double 553c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 554c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public double getDouble(String property, double def) { 555c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 556c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 557c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 558c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 559c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value instanceof Double) { 560c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return ((Double)value).doubleValue(); 561c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 562c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "double"); 563c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 564c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 565c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 566c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a string property, or the default if the property 567c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * has not been defined. 568c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 569c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 570c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param def The default value to return if the property is not set 571c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 572c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a string 573c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 574c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public String getString(String property, String def) { 575c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort Object value = super.get(property); 576c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == null) { 577c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return def; 578c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 579c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort if (value == NULL_STRING) { 580c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return null; 581c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } else if (value instanceof String) { 582c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return (String)value; 583c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 584c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort throw new TypeException(property, value, "string"); 585c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 586c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 587c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /* 588c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Getters with implicit defaults 589c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 590c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 591c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 592c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a boolean property, or false 593c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 594c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 595c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 596c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 597c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a boolean 598c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 599c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public boolean getBoolean(String property) { 600c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getBoolean(property, false); 601c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 602c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 603c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 604c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a byte property, or 0 605c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 606c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 607c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 608c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 609c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a byte 610c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 611c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public byte getByte(String property) { 612c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getByte(property, (byte)0); 613c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 614c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 615c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 616c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a short property, or 0 617c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 618c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 619c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 620c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 621c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a short 622c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 623c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public short getShort(String property) { 624c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getShort(property, (short)0); 625c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 626c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 627c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 628c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of an integer property, or 0 629c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 630c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 631c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 632c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 633c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not an integer 634c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 635c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public int getInt(String property) { 636c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getInt(property, 0); 637c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 638c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 639c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 640c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a long property, or 0 641c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 642c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 643c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 644c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 645c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a long 646c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 647c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public long getLong(String property) { 648c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getLong(property, 0L); 649c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 650c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 651c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 652c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a float property, or 0.0 653c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 654c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 655c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 656c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 657c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a float 658c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 659c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public float getFloat(String property) { 660c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getFloat(property, 0.0f); 661c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 662c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 663c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 664c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a double property, or 0.0 665c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 666c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 667c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 668c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 669c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a double 670c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 671c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public double getDouble(String property) { 672c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getDouble(property, 0.0); 673c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 674c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort 675c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort /** 676c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * Returns the value of a String property, or "" 677c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * if the property has not been defined. 678c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * 679c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @param property The name of the property to return 680c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @return the value of the property 681c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort * @throws TypeException if the property is set and is not a string 682c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort */ 683c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort public String getString(String property) { 684c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort return getString(property, ""); 685c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort } 6864b0ebef18defefe6850360cf11498f262a71847dDave Bort 6874b0ebef18defefe6850360cf11498f262a71847dDave Bort // Values returned by getStringInfo() 6884b0ebef18defefe6850360cf11498f262a71847dDave Bort public static final int STRING_TYPE_MISMATCH = -2; 6894b0ebef18defefe6850360cf11498f262a71847dDave Bort public static final int STRING_NOT_SET = -1; 6904b0ebef18defefe6850360cf11498f262a71847dDave Bort public static final int STRING_NULL = 0; 6914b0ebef18defefe6850360cf11498f262a71847dDave Bort public static final int STRING_SET = 1; 6924b0ebef18defefe6850360cf11498f262a71847dDave Bort 6934b0ebef18defefe6850360cf11498f262a71847dDave Bort /** 6944b0ebef18defefe6850360cf11498f262a71847dDave Bort * Provides string type information about a property. 6954b0ebef18defefe6850360cf11498f262a71847dDave Bort * 6964b0ebef18defefe6850360cf11498f262a71847dDave Bort * @param property the property to check 6974b0ebef18defefe6850360cf11498f262a71847dDave Bort * @return STRING_SET if the property is a string and is non-null. 6984b0ebef18defefe6850360cf11498f262a71847dDave Bort * STRING_NULL if the property is a string and is null. 6994b0ebef18defefe6850360cf11498f262a71847dDave Bort * STRING_NOT_SET if the property is not set (no type or value). 7004b0ebef18defefe6850360cf11498f262a71847dDave Bort * STRING_TYPE_MISMATCH if the property is set but is not a string. 7014b0ebef18defefe6850360cf11498f262a71847dDave Bort */ 7024b0ebef18defefe6850360cf11498f262a71847dDave Bort public int getStringInfo(String property) { 7034b0ebef18defefe6850360cf11498f262a71847dDave Bort Object value = super.get(property); 7044b0ebef18defefe6850360cf11498f262a71847dDave Bort if (value == null) { 7054b0ebef18defefe6850360cf11498f262a71847dDave Bort return STRING_NOT_SET; 7064b0ebef18defefe6850360cf11498f262a71847dDave Bort } 7074b0ebef18defefe6850360cf11498f262a71847dDave Bort if (value == NULL_STRING) { 7084b0ebef18defefe6850360cf11498f262a71847dDave Bort return STRING_NULL; 7094b0ebef18defefe6850360cf11498f262a71847dDave Bort } else if (value instanceof String) { 7104b0ebef18defefe6850360cf11498f262a71847dDave Bort return STRING_SET; 7114b0ebef18defefe6850360cf11498f262a71847dDave Bort } 7124b0ebef18defefe6850360cf11498f262a71847dDave Bort return STRING_TYPE_MISMATCH; 7134b0ebef18defefe6850360cf11498f262a71847dDave Bort } 714c4d6dd0bbce846c3b20e907d6a3016e4adc65e22Dave Bort} 715