/* license-start
*
* Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 3.
*
* This program 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 General Public License for more details, at <http://www.gnu.org/licenses/>.
*
* Contributors:
* Crispico - Initial API and implementation
*
* license-end
*/
package org.flowerplatform.common;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Central repository for configuration related properties.
*
* <p>
* For doc, rules and conventions, please see the wiki page http://csp1/dokuwiki/proiecte/flower/general_instructions/properties_and_configuration
*
* <p>
* Note : all new {@link AddProperty} validators must be added also in the wiki.
*
* @author Cristi
* @author Sorin
*/
public class FlowerProperties extends Properties {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(FlowerProperties.class);
public static final long DB_VERSION = 8;
/* package */ FlowerProperties(InputStream inputStream) {
super();
defaults = new Properties();
try {
this.load(inputStream);
inputStream.close();
} catch (IOException e) {
throw new RuntimeException("Error while loading properties from local file.", e);
}
}
public void addProperty(AddProperty p) {
if (p.propertyName == null || p.propertyDefaultValue == null) {
throw new IllegalArgumentException("Property name and default value shouldn't be null.");
}
if (logger.isTraceEnabled()) {
logger.trace("Adding property with name = {}, default value = {}, user value = {}",
new Object[] { p.propertyName, p.propertyDefaultValue, get(p.propertyName) });
}
defaults.put(p.propertyName, p.propertyDefaultValue);
String userValue = (String) get(p.propertyName);
if (userValue != null) {
// if the user has given a value, validate it
String validationErrorMessage = p.validateProperty(userValue);
if (validationErrorMessage != null) {
// validation failed;
logger.error("Property Validation Error! Failed to set property = {} to value = {}; reverting to default = {}. Reason: {}",
new Object[] {p.propertyName, userValue, p.propertyDefaultValue, validationErrorMessage} );
remove(p.propertyName);
}
} else {
if (p.inputFromFileMandatory) {
// Mariana: if the user did not provide a value and the property is mandatory => validation error
logger.error("Property Validation Error! Failed to provide a value for mandatory property = {}; default value is set to = {}.",
new Object[] {p.propertyName, p.propertyDefaultValue});
}
}
}
public Properties getDefaults() {
return defaults;
}
/**
* @author Cristi
*/
public static abstract class AddProperty {
protected String propertyName;
protected String propertyDefaultValue;
protected boolean inputFromFileMandatory = false;
public AddProperty(String propertyName, String propertyDefaultValue) {
super();
this.propertyName = propertyName;
this.propertyDefaultValue = propertyDefaultValue;
}
protected abstract String validateProperty(String input);
/**
* Set to <code>true</code> if the user must provide a value for this property in the properties file.
* If the user fails to provide a value, a validation error will be logged at property validation.
* Default value is <code>false</code>, i.e. we allow <code>null</code> as a valid value for this property.
*
* @author Mariana
*/
public AddProperty setInputFromFileMandatory(boolean inputFromFileMandatory) {
this.inputFromFileMandatory = inputFromFileMandatory;
return this;
}
}
/**
* Accepts a boolean property; i.e. values can be 'true' or 'false'
* @author Cristi
*/
public static class AddBooleanProperty extends AddProperty {
public AddBooleanProperty(String propertyName,
String propertyDefaultValue) {
super(propertyName, propertyDefaultValue);
}
@Override
protected String validateProperty(String input) {
if ("true".equals(input) || "false".equals(input)) {
return null;
} else {
return "Value should be 'true' or 'false'";
}
}
}
/**
* @author Sorin
*/
public static class AddIntegerProperty extends AddProperty {
public AddIntegerProperty(String propertyName, String propertyDefaultValue) {
super(propertyName, propertyDefaultValue);
}
@Override
protected String validateProperty(String input) {
try {
Integer.valueOf(input);
return null;
} catch (Exception e) {
return "Value is not a valid integer";
}
}
}
/**
* @author Sorin
*/
public static class AddStringProperty extends AddProperty {
public AddStringProperty(String propertyName, String propertyDefaultValue) {
super(propertyName, propertyDefaultValue);
}
@Override
protected String validateProperty(String input) {
if (input == null || input.trim().length() == 0)
return "Value is null or empty";
return null;
}
}
}