/*******************************************************************************
* Copyright (c) 2004, 2006
* Thomas Hallgren, Kenneth Olwing, Mitch Sonies
* Pontus Rydin, Nils Unden, Peer Torngren
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the individual
* copyright holders listed above, as Initial Contributors under such license.
* The text of such license is available at www.eclipse.org.
*******************************************************************************/
package org.eclipse.buckminster.core.common.model;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.buckminster.sax.AbstractSaxableElement;
/**
* Abstract class for holder of values. The holder will produce either exactly
* one value (holders such as {@link Format} , {@link Replace}, or
* {@link PropertyRef}) or it may produce multiple values (currently true only
* for {@link Split}.<br/>
* If the {@link #getValue(Map<String,String>} method is called on a holder that
* produces multiple values and if the result is exactly one value, that value
* is returned. If the result is zero values, the empty string is returned. If
* the result is more then one value, the result of concatenating those values
* is returned.<br/>
* Calling {@link #getValues(Map<String,String>)} on a holder that produces a
* single value will result in a one element array.
*
* @author Thomas Hallgren
*/
public abstract class ValueHolder<T> extends AbstractSaxableElement {
public static final String NO_VALUE = ""; //$NON-NLS-1$
private boolean mutable;
protected ValueHolder() {
mutable = false;
}
@Override
public boolean equals(Object o) {
return o == this || (o != null && o.getClass() == getClass() && mutable == ((ValueHolder<?>) o).mutable);
}
/**
* Returns the resolved value of this holder using <code>properties</code>
* as the scope.
*
* @param properties
* The scope used when resolving the value.
* @return A string representing the resolved value.
* @throws CircularExpansionException
* if the <code>recursionGuard</code> reaches its threshold.
*/
public final T getValue(Map<String, ? extends Object> properties) {
return checkedGetValue(properties, 0);
}
/**
* Returns resolved value array of this holder using <code>properties</code>
* as the scope.
*
* @param properties
* The scope used when resolving the values.
* @return A string array representing the resolved values.
* @throws CircularExpansionException
* if the <code>recursionGuard</code> reaches its threshold.
*/
public final List<T> getValues(Map<String, ? extends Object> properties) {
return checkedGetValues(properties, 0);
}
@Override
public int hashCode() {
return mutable ? 17 : 61;
}
/**
* This method will return <code>false</code> for all holders that produces
* exactly one value and <code>true</code> if the holder may produce zero or
* many values.
*
* @return <code>true</code> if the producer may produce zero or many
* values.
*/
public boolean isMultiValueProducer() {
return false;
}
/**
* Returns <code>true</code> if this value is considered mutable
*
* @return <code>true</code> if the value is mutable
*/
public boolean isMutable() {
return mutable;
}
/**
* Set the mutable status for the contained value
*/
public void setMutable(boolean flag) {
mutable = flag;
}
/**
* Returns the resolved value of this holder using <code>properties</code>
* as the scope.
*
* @param properties
* The scope used when resolving the value.
* @param recursionGuard
* A guard that is increased for each recursive expansion that is
* made.
* @return A string representing the resolved value.
* @throws CircularExpansionException
* if the <code>recursionGuard</code> reaches its threshold.
*/
protected abstract T checkedGetValue(Map<String, ? extends Object> properties, int recursionGuard);
/**
* Returns resolved value array of this holder using <code>properties</code>
* as the scope.
*
* @param properties
* The scope used when resolving the values
* @param recursionGuard
* A guard that is increased for each recursive expansion that is
* made.
* @return A string array representing the resolved values
* @throws CircularExpansionException
* if the <code>recursionGuard</code> reaches its threshold.
*/
protected List<T> checkedGetValues(Map<String, ? extends Object> properties, int recursionGuard) {
return Collections.singletonList(checkedGetValue(properties, recursionGuard));
}
}