All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.it.unimi.dsi.util.Properties Maven / Gradle / Ivy

package it.unimi.dsi.util;

/*
 * DSI utilities
 *
 * Copyright (C) 2005-2017 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 3 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, see .
 *
 */

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;

import com.google.common.base.Charsets;

/** 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.
 *
 * 

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()} * and {@link java.lang.String#toLowerCase()} 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.) * *

Additionally, instances of this class can be serialised. */ public class Properties extends PropertiesConfiguration implements Serializable { private static final long serialVersionUID = 1L; public Properties() { getLayout().setGlobalSeparator("="); } public Properties(final String filename) throws ConfigurationException { super(filename); getLayout().setGlobalSeparator("="); } public Properties(final File file) throws ConfigurationException { super(file); getLayout().setGlobalSeparator("="); } public Properties(final URL url) throws ConfigurationException { super(url); getLayout().setGlobalSeparator("="); } /** 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()), Charsets.UTF_8); super.save(w); w.close(); } /** Adds all properties from the given configuration. * *

Properties from the new configuration will clear properties from the first one. * * @param configuration a configuration. * */ 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()); } @Override public String toString() { return ConfigurationUtils.toString(this); } @Override 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. * *

Equality between set of properties happens when the keys are the same, * and the list of strings associated with each key is the same. Note that the order * in which different keys appear in a property file is irrelevant, but the order * between properties with the same key is significant. * *

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. */ @Override 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); } } }