/*
* 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 2 of the License, or (at your option) any later
* version. You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.aitools.programd.predicates;
import java.util.ArrayList;
import org.apache.log4j.Logger;
/**
* A <code>PredicateValue</code> is, naturally, the value of a predicate. It can either have a single String value, or a
* list of values.
*
* @author <a href="mailto:noel@aitools.org">Noel Bush</a>
*/
public class PredicateValue {
/** The single value (if assigned). */
private String singleValue;
/** The list of values (if assigned). */
private ArrayList<String> valueList;
/** Whether this PredicateValue has multiple values. */
private boolean multiValued;
private static Logger LOGGER = Logger.getLogger("programd");
/**
* Creates a new <code>PredicateValue</code> with the given list of values.
*
* @param values the list of values to assign
*/
public PredicateValue(ArrayList<String> values) {
this.valueList = values;
this.multiValued = true;
}
/**
* Creates a new <code>PredicateValue</code> with the given single value.
*
* @param value the single value to assign
*/
public PredicateValue(String value) {
this.singleValue = value;
this.multiValued = false;
}
/**
* Adds the given value into the value list at the given index.
*
* @param index the index at which to add a value
* @param value the new value
*/
public void add(int index, String value) {
if (!this.multiValued) {
this.becomeMultiValued();
}
try {
this.valueList.add(index - 1, value);
}
catch (IndexOutOfBoundsException e) {
this.valueList.add(0, value);
}
}
/**
* Adds the given value. In all cases, this means the <code>PredicateValue</code> becomes multi-valued.
*
* @param value the value to add
*/
public void add(String value) {
this.multiValued = true;
this.singleValue = null;
if (this.valueList == null) {
this.valueList = new ArrayList<String>(PredicateManager.MAX_INDEX);
}
this.valueList.add(value);
}
/**
* If this <code>PredicateValue</code> is multi-valued, returns itself. If it is single-valued, converts itself to
* multivalued and then returns itself.
*
* @return the list of values (or only value)
*/
public PredicateValue becomeMultiValued() {
if (this.multiValued) {
return this;
}
// otherwise...
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Converting predicate value to multi-valued.");
}
this.multiValued = true;
this.valueList = new ArrayList<String>(1);
this.valueList.add(this.singleValue);
this.singleValue = null;
return this;
}
/**
* @param index the index whose value is wanted
* @return the value at the given index
*/
public String get(int index) {
if (!this.multiValued) {
if (index == 1) {
return this.singleValue;
}
throw new IndexOutOfBoundsException();
}
return this.valueList.get(index - 1);
}
/**
* If this <code>PredicateValue</code> is single-valued, simply returns the value. If it is multi-valued, returns the
* first in the list.
*
* @return the first or only value
*/
public String getFirstValue() {
if (this.multiValued) {
return this.valueList.get(0);
}
// otherwise...
return this.singleValue;
}
/**
* @return whether this <code>PredicateValue</code> is multi-valued
*/
public boolean isMultiValued() {
return this.multiValued;
}
/**
* Pushes a value onto the front of a list, and pops off any values at the end of the list so that the list size is no
* more than {@link PredicateManager#MAX_INDEX}.
*
* @param value the value to push
*/
public void push(String value) {
if (!this.multiValued) {
this.becomeMultiValued();
}
this.valueList.add(0, value);
while (this.valueList.size() > PredicateManager.MAX_INDEX) {
this.valueList.remove(this.valueList.size() - 1);
}
}
/**
* @return the number of values stored
*/
public int size() {
if (!this.multiValued) {
return 1;
}
// otherwise...
return this.valueList.size();
}
}