/*
* Debellor
*
* Copyright (C) 2008-2009 by Marcin Wojnarski
*
* 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, either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package org.debellor.core;
import java.io.Serializable;
import java.util.ArrayList;
import org.debellor.core.exception.parameters.ParameterConversionException;
import org.debellor.core.exception.parameters.ParameterUndefinedException;
import org.debellor.core.util.DeepCopy;
/**
* Stores parameters that can be passed to a {@link Cell} object.
* Preserves their ordering.
*
* <p> Important: parameters should be accessed rarely
* during execution of a data processing algorithm,
* because this access may be slow.
* If you implement a parameterized algorithm,
* you should preferably read all parameters at the
* beginning of your algorithm and store them
* in your custom structures or variables for fast access.
*
* @see Cell
*
* @author Marcin Wojnarski
*/
public class Parameters implements Serializable {
private static final long serialVersionUID = 1L;
public static class Entry implements Serializable {
private static final long serialVersionUID = 1L;
public String name;
public String value;
public Entry(String name, String value) {
this.name = name;
this.value = value;
}
}
private ArrayList<Entry> entries = new ArrayList<Entry>();
/** Returns the number of defined parameters. */
public int size() {
return entries.size();
}
/** Clears the content of this Parameters instance,
* so that no parameters are defined afterwards. */
public void clear() {
entries.clear();
}
/** Returns deep copy of this object */
public Parameters copy() {
return (Parameters) DeepCopy.copy(this);
}
/** Sets value of the parameter <code>name</code> to a given string <code>value</code>.
* If {@code name} is null, does nothing.
* Note that String is a canonical representation of parameter values
* and all other types of values, passed to other variants of method <code>set</code>,
* are internally converted and stored as Strings. */
public void set(String name, String value) {
if(name == null) return;
int pos = indexOf(name);
if(pos < 0)
entries.add(new Entry(name, value));
else
entries.get(pos).value = value;
}
/** Sets value of the parameter to string representation of integer <code>k</code>. */
public void set(String name, int k) {
set(name, Integer.toString(k));
}
/** Sets value of the parameter to string representation of real number <code>x</code>.
* Caution: <code>x</code> is a real value and its conversion to String may
* introduce rounding errors, so the value decoded later on may slightly
* differ from the value passed to this method. */
public void set(String name, double x) {
set(name, Double.toString(x));
}
/** Sets value of the parameter to string representation of boolean <code>b</code>. */
public void set(String name, boolean b) {
set(name, Boolean.toString(b));
}
/** Returns index of the first occurrence of parameter {@code name}
* or -1 if does not exist. */
public int indexOf(String name) {
if(name == null) return -1;
for(int i = 0; i < entries.size(); i++)
if(entries.get(i).name.equals(name))
return i;
return -1;
}
/**
* Checks whether a given parameter is present.
* @param name Name of the parameter
* @return true if the parameter is present
*/
public boolean exists(String name) {
return indexOf(name) >= 0;
}
/** Returns value of the parameter.
* @throws ParameterUndefinedException if the parameter is not present */
public final String get(String name) throws ParameterUndefinedException {
return getAsString(name);
}
/** Returns {@link Entry} present at specified position in parameter list.
* @param index Index of the parameter in the list.
*/
public Entry getEntry(int index) {
return entries.get(index);
}
/** Returns name of the parameter at specified position in parameter list.
* @param index Index of the parameter in the list.
*/
public String getName(int index) {
return entries.get(index).name;
}
@Override
public String toString() {
if(size() == 0) return "empty set of parameters\n";
String s = "";
for(Entry e : entries) {
s += e.name + " = ";
s += (e.value == null) ? "null" : e.value;
s += "\n";
}
return s;
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
public String getAsString(String name) throws ParameterUndefinedException {
int pos = indexOf(name);
if(pos >= 0) return entries.get(pos).value;
throw new ParameterUndefinedException(name);
}
public int getAsInt(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Integer.parseInt(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "int", get(name));
}
}
public byte getAsByte(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Byte.parseByte(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "byte", get(name));
}
}
public short getAsShort(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Short.parseShort(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "short", get(name));
}
}
public long getAsLong(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Long.parseLong(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "long", get(name));
}
}
public double getAsDouble(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Double.parseDouble(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "double", get(name));
}
}
public float getAsFloat(String name) throws ParameterUndefinedException, ParameterConversionException
{
try {
return Float.parseFloat(get(name));
}
catch(NumberFormatException e) {
throw new ParameterConversionException(name, "float", get(name));
}
}
public boolean getAsBool(String name) throws ParameterUndefinedException, ParameterConversionException
{
String v = get(name).trim().toLowerCase();
if(v.equals("true") || v.equals("1")) return true;
if(v.equals("false") || v.equals("0")) return false;
throw new ParameterConversionException(name, "boolean", get(name));
}
}