package org.dcache.services.info.serialisation;
import java.util.Map;
import org.dcache.services.info.base.BooleanStateValue;
import org.dcache.services.info.base.FloatingPointStateValue;
import org.dcache.services.info.base.IntegerStateValue;
import org.dcache.services.info.base.State;
import org.dcache.services.info.base.StateExhibitor;
import org.dcache.services.info.base.StatePath;
import org.dcache.services.info.base.StringStateValue;
/**
* The SimpleTextSerialiser converts the dCache State tree into a simple String
* representation. This representation contains multiple lines, each containing
* the path to the metric followed by a colon, then a space, the value, then
* finally the metric type (in square brackets).
* <p>
* NB, instances of this Class are not thread-safe: the caller is responsible for
* ensuring no concurrent calls to serialise().
*
* @see PrettyPrintTextSerialiser
*
* @author Paul Millar <paul.millar@desy.de>
*/
public class SimpleTextSerialiser extends SubtreeVisitor implements StateSerialiser
{
public static final String NAME = "simple";
private static final String LIST_TYPE = "List item";
private StringBuilder _result = new StringBuilder();
private StatePath _lastStateComponentPath;
private StatePath _startPath;
private StateExhibitor _exhibitor;
public void setStateExhibitor(StateExhibitor exhibitor)
{
_exhibitor = exhibitor;
}
@Override
public String serialise(StatePath start)
{
_result = new StringBuilder();
_startPath = start;
if (start != null) {
setVisitScopeToSubtree(start);
} else {
setVisitScopeToEverything();
}
if (start != null) {
_result.append(start.toString());
_result.append(">\n");
}
_exhibitor.visitState(this);
return _result.toString();
}
@Override
public String serialise()
{
return serialise(null);
}
@Override
public String getName()
{
return NAME;
}
@Override
public void visitBoolean(StatePath path, BooleanStateValue value)
{
outputMetric(path, value.toString(), value.getTypeName());
_lastStateComponentPath = path;
}
@Override
public void visitFloatingPoint(StatePath path, FloatingPointStateValue value)
{
outputMetric(path, value.toString(), value.getTypeName());
_lastStateComponentPath = path;
}
@Override
public void visitInteger(StatePath path, IntegerStateValue value)
{
outputMetric(path, value.toString(), value.getTypeName());
_lastStateComponentPath = path;
}
@Override
public void visitString(StatePath path, StringStateValue value)
{
outputMetric(path, "\""+value+"\"", value.getTypeName());
_lastStateComponentPath = path;
}
@Override
public void visitCompositePreDescend(StatePath path, Map<String, String> metadata)
{
if (!isInsideScope(path)) {
return;
}
_lastStateComponentPath = path;
}
@Override
public void visitCompositePostDescend(StatePath path, Map<String, String> metadata)
{
if (!isInsideScope(path)) {
return;
}
// If we just traversed a path without it containing any elements, treat it as a list.
if (path != null && path.equals(_lastStateComponentPath) && !path.isSimplePath()) {
String type = LIST_TYPE;
if (metadata != null) {
String className = metadata.get(State.METADATA_BRANCH_CLASS_KEY);
if (className != null) {
type = className;
}
}
outputMetric(path, "", type);
}
}
/**
* Output a single line, corresponding to a metric value.
* @param path The StatePath for this metric
* @param metricValue the String representing this metric's current value.
* @param metricType the type of metric.
*/
private void outputMetric(StatePath path, String metricValue, String metricType)
{
if (_startPath != null) {
_result.append(" ");
}
if (path != null) {
_result.append(path.toString(_startPath));
}
_result.append(": ");
_result.append(metricValue);
_result.append(" [");
_result.append(metricType);
_result.append("]\n");
}
}