blob: 21cf87b977fe99c96139718f65e8c17266bcf3e8 [file] [log] [blame] [raw]
/* Copyright 2015-2020 Rivoreo
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package rivoreo.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class JavaPropertiesConfiguration implements Configuration {
private JavaPropertiesConfiguration(Properties properties) {
this.properties = properties;
}
public static JavaPropertiesConfiguration create_from_stream(InputStream stream) throws IOException {
Properties properties = new Properties();
properties.load(stream);
return new JavaPropertiesConfiguration(properties);
}
public static JavaPropertiesConfiguration create_from_file(File file) throws IOException {
file.createNewFile();
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
JavaPropertiesConfiguration config = create_from_stream(stream);
config.file = file;
return config;
} finally {
if(stream != null) stream.close();
}
}
private Properties properties;
private File file;
private boolean is_modified = false;
public boolean get_boolean(String key, boolean default_value) {
String s = properties.getProperty(key);
if(s != null) {
if(s.equalsIgnoreCase("false") || s.equalsIgnoreCase("off") || s.equalsIgnoreCase("no")) return false;
if(s.equalsIgnoreCase("true") || s.equalsIgnoreCase("on") || s.equalsIgnoreCase("yes")) return true;
}
set(key, default_value);
return default_value;
}
public int get_int(String key, int default_value) {
String s = properties.getProperty(key);
if(s != null) try {
return Integer.parseInt(s);
} catch(NumberFormatException e) {
}
set(key, default_value);
return default_value;
}
public long get_long(String key, long default_value) {
String s = properties.getProperty(key);
if(s != null) try {
return Long.parseLong(s);
} catch(NumberFormatException e) {
}
set(key, default_value);
return default_value;
}
public float get_float(String key, float default_value) {
String s = properties.getProperty(key);
if(s != null) try {
return Float.parseFloat(s);
} catch(NumberFormatException e) {
}
set(key, default_value);
return default_value;
}
public double get_double(String key, double default_value) {
String s = properties.getProperty(key);
if(s != null) try {
return Double.parseDouble(s);
} catch(NumberFormatException e) {
}
set(key, default_value);
return default_value;
}
public String get_string(String key, String default_value) {
String s = properties.getProperty(key);
if(s != null) return s;
set(key, default_value);
return default_value;
}
public Configuration get_child(String key, boolean create_if_nonexist) {
throw new UnsupportedOperationException("Java perperties doesn't support hierarchies");
}
public boolean[] get_boolean_list(String key, boolean[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
public int[] get_int_list(String key, int[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
public long[] get_long_list(String key, long[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
public float[] get_float_list(String key, float[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
public double[] get_double_list(String key, double[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
public String[] get_string_list(String key, String[] default_value) {
throw new UnsupportedOperationException("Java perperties doesn't support list");
}
private static Object guess_type(String s, Class<?> hint) {
if(s.equalsIgnoreCase("false") || s.equalsIgnoreCase("off") || s.equalsIgnoreCase("no")) return Boolean.valueOf(false);
if(s.equalsIgnoreCase("true") || s.equalsIgnoreCase("on") || s.equalsIgnoreCase("yes")) return Boolean.valueOf(true);
if(hint != Long.class) try {
return Integer.valueOf(s);
} catch(NumberFormatException e) {
}
try {
return Long.valueOf(s);
} catch(NumberFormatException e) {
}
if(s.matches("^[0-9]+(\\.[0-9]+)?[Dd]$")) try {
return Double.valueOf(s);
} catch(NumberFormatException e) {
} else if(s.matches("^[0-9]+(\\.[0-9]+)?[Ff]$")) try {
return Float.valueOf(s);
} catch(NumberFormatException e) {
} else try {
return hint == Float.class ? Float.valueOf(s) : Double.valueOf(s);
} catch(NumberFormatException e) {
}
return s;
}
public <T> Map<String, T> get_all(Class<T> type, boolean should_guess_types) {
if(type != Object.class && type != Configuration.class && type != String.class && type != Double.class && type != Float.class && type != Long.class && type != Integer.class && type != Boolean.class) {
throw new IllegalArgumentException("Type not supported");
}
Map<String, T> map = new HashMap<String, T>();
for(Map.Entry<Object, Object> e : properties.entrySet()) {
if(should_guess_types) {
Object value = guess_type((String)e.getValue(), type);
if(type == Object.class || type == value.getClass()) {
map.put((String)e.getKey(), (T)value);
}
} else if(type == Object.class || type == String.class) {
map.put((String)e.getKey(), (T)e.getValue());
}
}
return map;
}
public <T> Map<String, T> get_all(Class<T> type) {
return get_all(type, false);
}
public void set(String key, boolean value) {
properties.setProperty(key, String.valueOf(value));
is_modified = true;
}
public void set(String key, int value) {
properties.setProperty(key, String.valueOf(value));
is_modified = true;
}
public void set(String key, long value) {
properties.setProperty(key, String.valueOf(value));
is_modified = true;
}
public void set(String key, float value) {
String s = String.valueOf(value);
if(s.endsWith(".0")) s = s.substring(0, s.length() - 2);
properties.setProperty(key, s);
is_modified = true;
}
public void set(String key, double value) {
String s = String.valueOf(value);
if(s.endsWith(".0")) s = s.substring(0, s.length() - 2);
properties.setProperty(key, s);
is_modified = true;
}
public void set(String key, String value) {
properties.setProperty(key, value);
is_modified = true;
}
public void set(String key, Configuration value) {
throw new UnsupportedOperationException("Java perperties doesn't support hierarchies");
}
public void save() throws IOException {
if(!is_modified) return;
if(file == null) throw new IOException("Configuration file path not known");
FileOutputStream stream = null;
try {
stream = new FileOutputStream(file);
properties.store(stream, null);
} finally {
if(stream != null) stream.close();
}
is_modified = false;
}
}