Java tutorial
package it.unimi.dsi.util; /* * DSI utilities * * Copyright (C) 2005-2009 Sebastiano Vigna * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStreamWriter; import java.io.Serializable; import java.io.Writer; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConfigurationMap; import org.apache.commons.configuration.ConfigurationUtils; import org.apache.commons.configuration.PropertiesConfiguration; /** An extension of {@link org.apache.commons.configuration.PropertiesConfiguration} * providing setters for primitive types, a simpler {@linkplain #save(CharSequence) way to save preferences} * and transparent handling of {@link java.lang.Enum} lowercased keys. * * <p>All accessors defined in {@link org.apache.commons.configuration.PropertiesConfiguration} have a * polymorphic counterpart taking an {@link java.lang.Enum} instead of a string: {@link java.lang.Enum#name()} * <strong>and {@link java.lang.String#toLowerCase()}</strong> are applied before * delegating to the corresponding string-based method. (This apparently wierd choice is due to the need to * accommodate the upper-case standard for {@link java.lang.Enum} elements and the lower-case standard * for property keys.) * * <p>Additionally, instances of this class can be serialised. */ public class Properties extends PropertiesConfiguration implements Serializable { private static final long serialVersionUID = 1L; public Properties() { } public Properties(final String filename) throws ConfigurationException { super(filename); } public Properties(final File file) throws ConfigurationException { super(file); } public Properties(final URL url) throws ConfigurationException { super(url); } /** Saves the configuration to the specified file. * * @param filename a file name. */ public void save(final CharSequence filename) throws ConfigurationException, IOException { final Writer w = new OutputStreamWriter(new FileOutputStream(filename.toString()), "UTF-8"); super.save(w); w.close(); } /** Adds all properties from the given configuration. * * <p>Properties from the new configuration will clear properties from the first one. * * @param configuration a configuration. * */ @SuppressWarnings("unchecked") public void addAll(final Configuration configuration) { new ConfigurationMap(this).putAll(new ConfigurationMap(configuration)); } // Methods to add properties represented by primitive types easily public void addProperties(final String key, final String[] s) { for (int i = 0; i < s.length; i++) super.addProperty(key, s[i]); } public void addProperty(final String key, final boolean b) { super.addProperty(key, Boolean.valueOf(b)); } public void setProperty(final String key, final boolean b) { super.setProperty(key, Boolean.valueOf(b)); } public void addProperty(final String key, final byte b) { super.addProperty(key, Byte.valueOf(b)); } public void setProperty(final String key, final byte b) { super.setProperty(key, Byte.valueOf(b)); } public void addProperty(final String key, final short s) { super.addProperty(key, Short.valueOf(s)); } public void setProperty(final String key, final short s) { super.setProperty(key, Short.valueOf(s)); } public void addProperty(final String key, final char c) { super.addProperty(key, Character.valueOf(c)); } public void setProperty(final String key, final char b) { super.setProperty(key, Character.valueOf(b)); } public void addProperty(final String key, final int i) { super.addProperty(key, Integer.valueOf(i)); } public void setProperty(final String key, final int i) { super.setProperty(key, Integer.valueOf(i)); } public void addProperty(final String key, final long l) { super.addProperty(key, Long.valueOf(l)); } public void setProperty(final String key, final long l) { super.setProperty(key, Long.valueOf(l)); } public void addProperty(final String key, final float f) { super.addProperty(key, Float.valueOf(f)); } public void setProperty(final String key, final float f) { super.setProperty(key, Float.valueOf(f)); } public void addProperty(final String key, final double d) { super.addProperty(key, Double.valueOf(d)); } public void setProperty(final String key, final double d) { super.setProperty(key, Double.valueOf(d)); } // Same methods, but with Enum keys public void addProperties(final Enum<?> key, final String[] s) { for (int i = 0; i < s.length; i++) super.addProperty(key.name().toLowerCase(), s[i]); } public void addProperty(final Enum<?> key, final boolean b) { super.addProperty(key.name().toLowerCase(), Boolean.valueOf(b)); } public void setProperty(final Enum<?> key, final boolean b) { super.setProperty(key.name().toLowerCase(), Boolean.valueOf(b)); } public void addProperty(final Enum<?> key, final byte b) { super.addProperty(key.name().toLowerCase(), Byte.valueOf(b)); } public void setProperty(final Enum<?> key, final byte b) { super.setProperty(key.name().toLowerCase(), Byte.valueOf(b)); } public void addProperty(final Enum<?> key, final short s) { super.addProperty(key.name().toLowerCase(), Short.valueOf(s)); } public void setProperty(final Enum<?> key, final short s) { super.setProperty(key.name().toLowerCase(), Short.valueOf(s)); } public void addProperty(final Enum<?> key, final char c) { super.addProperty(key.name().toLowerCase(), Character.valueOf(c)); } public void setProperty(final Enum<?> key, final char b) { super.setProperty(key.name().toLowerCase(), Character.valueOf(b)); } public void addProperty(final Enum<?> key, final int i) { super.addProperty(key.name().toLowerCase(), Integer.valueOf(i)); } public void setProperty(final Enum<?> key, final int i) { super.setProperty(key.name().toLowerCase(), Integer.valueOf(i)); } public void addProperty(final Enum<?> key, final long l) { super.addProperty(key.name().toLowerCase(), Long.valueOf(l)); } public void setProperty(final Enum<?> key, final long l) { super.setProperty(key.name().toLowerCase(), Long.valueOf(l)); } public void addProperty(final Enum<?> key, final float f) { super.addProperty(key.name().toLowerCase(), Float.valueOf(f)); } public void setProperty(final Enum<?> key, final float f) { super.setProperty(key.name().toLowerCase(), Float.valueOf(f)); } public void addProperty(final Enum<?> key, final double d) { super.addProperty(key.name().toLowerCase(), Double.valueOf(d)); } public void setProperty(final Enum<?> key, final double d) { super.setProperty(key.name().toLowerCase(), Double.valueOf(d)); } // Polimorphic Enum version of superclass string-based methods public boolean containsKey(final Enum<?> key) { return containsKey(key.name().toLowerCase()); } public Object getProperty(final Enum<?> key) { return getProperty(key.name().toLowerCase()); } public void addProperty(final Enum<?> key, Object arg) { addProperty(key.name().toLowerCase(), arg); } public BigDecimal getBigDecimal(final Enum<?> key, BigDecimal arg) { return getBigDecimal(key.name().toLowerCase(), arg); } public BigDecimal getBigDecimal(final Enum<?> key) { return getBigDecimal(key.name().toLowerCase()); } public BigInteger getBigInteger(final Enum<?> key, BigInteger arg) { return getBigInteger(key.name().toLowerCase(), arg); } public BigInteger getBigInteger(final Enum<?> key) { return getBigInteger(key.name().toLowerCase()); } public boolean getBoolean(final Enum<?> key, boolean arg) { return getBoolean(key.name().toLowerCase(), arg); } public Boolean getBoolean(final Enum<?> key, Boolean arg) { return getBoolean(key.name().toLowerCase(), arg); } public boolean getBoolean(final Enum<?> key) { return getBoolean(key.name().toLowerCase()); } public byte getByte(final Enum<?> key, byte arg) { return getByte(key.name().toLowerCase(), arg); } public Byte getByte(final Enum<?> key, Byte arg) { return getByte(key.name().toLowerCase(), arg); } public byte getByte(final Enum<?> key) { return getByte(key.name().toLowerCase()); } public double getDouble(final Enum<?> key, double arg) { return getDouble(key.name().toLowerCase(), arg); } public Double getDouble(final Enum<?> key, Double arg) { return getDouble(key.name().toLowerCase(), arg); } public double getDouble(final Enum<?> key) { return getDouble(key.name().toLowerCase()); } public float getFloat(final Enum<?> key, float arg) { return getFloat(key.name().toLowerCase(), arg); } public Float getFloat(final Enum<?> key, Float arg) { return getFloat(key.name().toLowerCase(), arg); } public float getFloat(final Enum<?> key) { return getFloat(key.name().toLowerCase()); } public int getInt(final Enum<?> key, int arg) { return getInt(key.name().toLowerCase(), arg); } public int getInt(final Enum<?> key) { return getInt(key.name().toLowerCase()); } public Integer getInteger(final Enum<?> key, Integer arg) { return getInteger(key.name().toLowerCase(), arg); } public Iterator<?> getKeys(final Enum<?> key) { return getKeys(key.name().toLowerCase()); } public List<?> getList(final Enum<?> key, List<?> arg) { return getList(key.name().toLowerCase(), arg); } public List<?> getList(final Enum<?> key) { return getList(key.name().toLowerCase()); } public long getLong(final Enum<?> key, long arg) { return getLong(key.name().toLowerCase(), arg); } public Long getLong(final Enum<?> key, Long arg) { return getLong(key.name().toLowerCase(), arg); } public long getLong(final Enum<?> key) { return getLong(key.name().toLowerCase()); } public java.util.Properties getProperties(final Enum<?> key, java.util.Properties arg) { return getProperties(key.name().toLowerCase(), arg); } public java.util.Properties getProperties(final Enum<?> key) { return getProperties(key.name().toLowerCase()); } public short getShort(final Enum<?> key, short arg) { return getShort(key.name().toLowerCase(), arg); } public Short getShort(final Enum<?> key, Short arg) { return getShort(key.name().toLowerCase(), arg); } public short getShort(final Enum<?> key) { return getShort(key.name().toLowerCase()); } public String getString(final Enum<?> key, String arg) { return getString(key.name().toLowerCase(), arg); } public String getString(final Enum<?> key) { return getString(key.name().toLowerCase()); } public String[] getStringArray(final Enum<?> key) { return getStringArray(key.name().toLowerCase()); } public void setProperty(final Enum<?> key, Object arg) { setProperty(key.name().toLowerCase(), arg); } public Configuration subset(final Enum<?> key) { return subset(key.name().toLowerCase()); } public String toString() { return ConfigurationUtils.toString(this); } public int hashCode() { int h = 0; for (Iterator<?> i = getKeys(); i.hasNext();) h = h * 31 + Arrays.hashCode(getStringArray((String) i.next())); return h; } /** Returns true if the provided object is equal to this set of properties. * * <p>Equality between set of properties happens when the keys are the same, * and the list of strings associated to each key is the same. Note that the order * in which different keys appear in a property file is irrelevant, but <em>the order * between properties with the same key is significant</em>. * * <p>Due to the strictness of the check (e.g., no number conversion is performed) * this method is mainly useful when writing tests. * * @return true if the argument is equal to this set of properties. */ public boolean equals(final Object o) { if (!(o instanceof Properties)) return false; final Properties p = (Properties) o; for (Iterator<?> i = getKeys(); i.hasNext();) { String key = (String) i.next(); String[] value = p.getStringArray(key); if (value == null || !Arrays.equals(getStringArray(key), value)) return false; } for (Iterator<?> i = p.getKeys(); i.hasNext();) if (getStringArray((String) i.next()) == null) return false; return true; } private void writeObject(final ObjectOutputStream s) throws IOException { s.defaultWriteObject(); try { save(s); } catch (ConfigurationException e) { throw new RuntimeException(e); } } private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); try { load(s); } catch (ConfigurationException e) { throw new RuntimeException(e); } } }