/** * Retrieves the specified value. Throws an error if value cannot be read. * * @param key key * @param c expected type * @return result */ private Object get(final Object[] key, final Class<?> c) { final Object entry = props.get(key[0].toString()); if (entry == null) Util.notexpected("Property " + key[0] + " not defined."); final Class<?> cc = entry.getClass(); if (c != cc) Util.notexpected("Property '" + key[0] + "' is a " + Util.name(cc)); return entry; }
/** * Sets the specified value after casting it to the correct type. * * @param key key * @param val value * @return final value, or {@code null} if the key has not been found */ public final synchronized String set(final String key, final String val) { final Object type = get(key); if (type == null) return null; String v = val; if (type instanceof Boolean) { final boolean b = val == null || val.isEmpty() ? !((Boolean) type) : Util.yes(val); setObject(key, b); v = Util.flag(b); } else if (type instanceof Integer) { setObject(key, Integer.parseInt(val)); v = String.valueOf(get(key)); } else if (type instanceof String) { setObject(key, val); } else { Util.notexpected("Unknown property type: " + type.getClass().getSimpleName()); } return v; }
/** Constructor, initializing the default options. */ protected AProp() { try { for (final Field f : getClass().getFields()) { final Object obj = f.get(null); if (!(obj instanceof Object[])) continue; final Object[] arr = (Object[]) obj; props.put(arr[0].toString(), arr[1]); } } catch (final Exception ex) { Util.notexpected(ex); } }
/** * Reads the configuration file and initializes the project properties. The file is located in the * project home directory. * * @param prop property file extension */ protected synchronized void read(final String prop) { file = new IOFile(HOME + IO.BASEXSUFFIX + prop); final StringList read = new StringList(); final TokenBuilder err = new TokenBuilder(); if (!file.exists()) { err.addExt("Saving properties in \"%\"..." + NL, file); } else { BufferedReader br = null; try { br = new BufferedReader(new FileReader(file.file())); for (String line; (line = br.readLine()) != null; ) { line = line.trim(); if (line.isEmpty() || line.charAt(0) == '#') continue; final int d = line.indexOf('='); if (d < 0) { err.addExt("%: \"%\" ignored. " + NL, file, line); continue; } final String val = line.substring(d + 1).trim(); String key = line.substring(0, d).trim(); // extract numeric value in key int num = 0; final int ss = key.length(); for (int s = 0; s < ss; ++s) { if (Character.isDigit(key.charAt(s))) { num = Integer.parseInt(key.substring(s)); key = key.substring(0, s); break; } } read.add(key); final Object entry = props.get(key); if (entry == null) { err.addExt("%: \"%\" not found. " + NL, file, key); } else if (entry instanceof String) { props.put(key, val); } else if (entry instanceof Integer) { props.put(key, Integer.parseInt(val)); } else if (entry instanceof Boolean) { props.put(key, Boolean.parseBoolean(val)); } else if (entry instanceof String[]) { if (num == 0) { props.put(key, new String[Integer.parseInt(val)]); } else { ((String[]) entry)[num - 1] = val; } } else if (entry instanceof int[]) { ((int[]) entry)[num] = Integer.parseInt(val); } } } catch (final Exception ex) { err.addExt("% could not be parsed." + NL, file); Util.debug(ex); } finally { if (br != null) try { br.close(); } catch (final IOException ex) { } } } // check if all mandatory files have been read try { if (err.isEmpty()) { boolean ok = true; for (final Field f : getClass().getFields()) { final Object obj = f.get(null); if (!(obj instanceof Object[])) continue; final String key = ((Object[]) obj)[0].toString(); ok &= read.contains(key); } if (!ok) err.addExt("Saving properties in \"%\"..." + NL, file); } } catch (final IllegalAccessException ex) { Util.notexpected(ex); } if (!err.isEmpty()) { Util.err(err.toString()); write(); } }
/** * Returns an error string for an unknown key. * * @param key key * @return error string */ public final synchronized String unknown(final String key) { final String sim = similar(key); return Util.info(sim != null ? Text.UNKNOWN_OPT_SIMILAR_X_X : Text.UNKNOWN_OPTION_X, key, sim); }
/** Writes the properties to disk. */ public final synchronized void write() { final StringBuilder user = new StringBuilder(); BufferedReader br = null; try { // caches options specified by the user if (file.exists()) { br = new BufferedReader(new FileReader(file.file())); for (String line; (line = br.readLine()) != null; ) { if (line.equals(PROPUSER)) break; } for (String line; (line = br.readLine()) != null; ) { user.append(line).append(NL); } } } catch (final Exception ex) { Util.debug(ex); } finally { if (br != null) try { br.close(); } catch (final IOException e) { } } BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(file.file())); bw.write(PROPHEADER + NL); for (final Field f : getClass().getFields()) { final Object obj = f.get(null); if (!(obj instanceof Object[])) continue; final String key = ((Object[]) obj)[0].toString(); final Object val = props.get(key); if (val instanceof String[]) { final String[] str = (String[]) val; bw.write(key + " = " + str.length + NL); final int is = str.length; for (int i = 0; i < is; ++i) { if (str[i] != null) bw.write(key + (i + 1) + " = " + str[i] + NL); } } else if (val instanceof int[]) { final int[] num = (int[]) val; final int ns = num.length; for (int i = 0; i < ns; ++i) { bw.write(key + i + " = " + num[i] + NL); } } else { bw.write(key + " = " + val + NL); } } bw.write(NL + PROPUSER + NL); bw.write(user.toString()); } catch (final Exception ex) { Util.errln("% could not be written.", file); Util.debug(ex); } finally { if (bw != null) try { bw.close(); } catch (final IOException e) { } } }