package org.dcache.services.info.stateInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.StateGuide;
import org.dcache.services.info.base.StatePath;
import org.dcache.services.info.base.StateVisitor;
import org.dcache.services.info.base.StringStateValue;
import org.dcache.services.info.base.guides.SubtreeStateGuide;
/**
* A simple skeleton class that provides a StateVisitor that iterates over items in a list.
* The constructor should be called with the StatePath of the parent StateComposite. Each
* child of this StateComposite is considered a item within the list and newListItem() will be
* called for each such list. Subclasses may overload that method.
*
* The method getKey() will return the last item, as recorded by the subclass calling
* super.newListItem(key), typically done within an overloaded method newListitem.
*
* @author Paul Millar <paul.millar@desy.de>
*/
public class SkeletonListVisitor implements StateVisitor
{
private static final Logger LOGGER = LoggerFactory.getLogger(SkeletonListVisitor.class);
private final StatePath _pathToList;
/** The key of the current branch */
private String _thisKey;
private final StateGuide _guide;
/**
* Instantiate the list over the items underneath pathToList.
* @param pathToList the StatePath representing the parent object for this list.
*/
protected SkeletonListVisitor(StatePath pathToList)
{
LOGGER.trace("Searching on path {}", pathToList);
_pathToList = pathToList;
_guide = new SubtreeStateGuide(pathToList);
}
@Override
public boolean isVisitable(StatePath path)
{
return _guide.isVisitable(path);
}
/**
* The super-Class should override one of the following four methods
*/
@Override
public void visitBoolean(StatePath path, BooleanStateValue value)
{
}
@Override
public void visitFloatingPoint(StatePath path, FloatingPointStateValue value)
{
}
@Override
public void visitInteger(StatePath path, IntegerStateValue value)
{
}
@Override
public void visitString(StatePath path, StringStateValue value)
{
}
@Override
public void visitCompositePreDescend(StatePath path, Map<String, String> metadata)
{
if (_pathToList.isParentOf(path)) {
LOGGER.trace("Entering {}", path);
newListItem(path.getLastElement());
}
}
@Override
public void visitCompositePostDescend(StatePath path, Map<String, String> metadata)
{
if (_pathToList.isParentOf(path)) {
LOGGER.trace("Leaving {}", path);
exitingListItem(path.getLastElement());
}
}
/**
* Method called whenever a new list item is visited.
* @param listItemName the name of the list item to record.
* @see the getKey() method.
*/
protected void newListItem(String listItemName)
{
LOGGER.trace("Assigning _thisKey to {}", listItemName);
_thisKey = listItemName;
}
/**
* Method called whenever the visitor is leaving a list item.
* @param listItemName the name of the list item that is being left.
*/
protected void exitingListItem(String listItemName)
{
LOGGER.trace("Resetting _thisKey to null on leaving {}", listItemName);
_thisKey = null;
}
/**
* Obtain the StatePath to the parent object for all list items.
*/
protected StatePath getPathToList()
{
return _pathToList;
}
/**
* @return the name of the last item in the list, or null if not currently within a list item.
*/
protected String getKey()
{
return _thisKey;
}
/**
* Check whether the visitor is within (underneath) the list item. If so,
* then getKey() will return the valid key.
* @return true if visitor is within a list item, false otherwise.
*/
protected boolean isInListItem()
{
return _thisKey != null;
}
}