/* * Copyright (c) 2015-2019. Developed by Hedgecode. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hedgecode.xml.xspf; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Properties; /** * Storage class represents a persistent set of typed properties. * * @author Dmitry Samoshin aka gotty */ public class TypedProperties extends Properties { public TypedProperties() { this(null); } public TypedProperties(TypedProperties defaults) { super(defaults); } public T getProperty(String key, Class type) { Object object = get(key); T val = type.isInstance(object) ? type.cast(object) : null; return val == null ? getDefProperty(key, type) : val; } public T getProperty(String key, Class type, T defaultValue) { T val = getProperty(key, type); return val == null ? defaultValue : val; } public synchronized Object setProperty(String key, Object value) { return put(key, value); } protected T getDefProperty(String key, Class type) { if (defaults != null) { Object object = defaults.get(key); return type.isInstance(object) ? type.cast(object) : null; } return null; } @Override public synchronized void load(Reader reader) throws IOException { super.load(reader); TypeSupport.cast(this); } @Override public synchronized void load(InputStream inStream) throws IOException { super.load(inStream); TypeSupport.cast(this); } public String getString(String key) { return getProperty(key, String.class); } public Byte getByte(String key) { return getProperty(key, Byte.class); } public Short getShort(String key) { return getProperty(key, Short.class); } public Integer getInteger(String key) { return getProperty(key, Integer.class); } public Long getLong(String key) { return getProperty(key, Long.class); } public Float getFloat(String key) { return getProperty(key, Float.class); } public Double getDouble(String key) { return getProperty(key, Double.class); } public Character getCharacter(String key) { return getProperty(key, Character.class); } public Boolean getBoolean(String key) { return getProperty(key, Boolean.class); } private enum TypeSupport { INT ( "^-?\\d+$" ) { @Override Object parse(String value) { return Integer.parseInt(value); } }, FLOAT ( "^-?[\\d.]+$" ) { @Override Object parse(String value) { return Float.parseFloat(value); } }, BOOLEAN ( "^(TRUE|FALSE|[Tt]rue|[Ff]alse)$" ) { @Override Object parse(String value) { return Boolean.parseBoolean(value); } }; private final String regex; TypeSupport(String regex) { this.regex = regex; } abstract Object parse(String value); static TypeSupport getType(String value) { if (value != null) { for (TypeSupport typeSupport : TypeSupport.values()) { if (value.matches(typeSupport.regex)) { return typeSupport; } } } return null; } static void cast(Properties props) { props.forEach((key, val) -> { if (String.class.isInstance(val)) { String value = (String) val; TypeSupport typeSupport = getType(value); if (typeSupport != null) { props.replace(key, typeSupport.parse(value)); } } }); } } }