package org.dcache.vehicles;
import com.google.common.collect.BoundType;
import com.google.common.collect.Range;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import diskCacheV111.vehicles.Message;
import diskCacheV111.vehicles.PnfsMessage;
import org.dcache.namespace.FileAttribute;
import org.dcache.util.Glob;
import org.dcache.util.list.DirectoryEntry;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Requests a directory listing. Since the result set may be very
* large, a single request may result in multiple replies. The request
* is identified by a UUID and the replies will contain the same
* UUID. The last reply is flagged as final. It is assumed that
* point-to-point message ordering is guaranteed.
*/
public class PnfsListDirectoryMessage extends PnfsMessage
{
private static final long serialVersionUID = -5774904472984157638L;
private final Glob _pattern;
private final Integer _lower;
private final Integer _upper;
private final BoundType _lowerBoundType;
private final BoundType _upperBoundType;
private final UUID _uuid = UUID.randomUUID();
private final Set<FileAttribute> _requestedAttributes;
private Collection<DirectoryEntry> _entries = new ArrayList<>();
/**
* The last message has the following field set to true and a non-zero
* message count;
*/
private boolean _isFinal;
private int _messageCount;
/**
* Constructs a new message.
*
* @param path The full PNFS path of the directory to list
* @param pattern Optional glob pattern for filtering the result
* @param range Range for bracketing the result
* @param attr The file attributes to include for each entry
* @see diskCacheV111.namespace.NameSpaceProvider#list
*/
public PnfsListDirectoryMessage(String path, Glob pattern,
Range<Integer> range,
Set<FileAttribute> attr)
{
setPnfsPath(checkNotNull(path));
setReplyRequired(true);
_pattern = pattern;
_lower = range.hasLowerBound() ? range.lowerEndpoint() : null;
_upper = range.hasUpperBound() ? range.upperEndpoint() : null;
_lowerBoundType = range.hasLowerBound() ? range.lowerBoundType() : null;
_upperBoundType = range.hasUpperBound() ? range.upperBoundType() : null;
_requestedAttributes = attr;
}
/** Returns the UUID identifying this request. */
public UUID getUUID()
{
return _uuid;
}
/** Returns the pattern used to filter the result. */
public Glob getPattern()
{
return _pattern;
}
/** Returns the optional range bracketing the result. */
public Range<Integer> getRange()
{
if (_lower == null && _upper == null) {
return Range.all();
} else if (_lower == null) {
return Range.upTo(_upper, _upperBoundType);
} else if (_upper == null) {
return Range.downTo(_lower, _lowerBoundType);
} else {
return Range.range(_lower, _lowerBoundType,
_upper, _upperBoundType);
}
}
/** True if and only if the reply should include file meta data. */
public Set<FileAttribute> getRequestedAttributes()
{
return _requestedAttributes;
}
/** Adds an entry to the entry list. */
public void addEntry(String name, FileAttributes attr)
{
_entries.add(new DirectoryEntry(name, attr));
}
/** Sets a new entry list. */
public void setEntries(Collection<DirectoryEntry> entries)
{
_entries = entries;
}
/** Returns the entry list. */
public Collection<DirectoryEntry> getEntries()
{
return _entries;
}
/** Clears the entry list. */
public void clear()
{
_entries.clear();
}
@Override
public void setSucceeded()
{
super.setSucceeded();
_isFinal = true;
}
public void setSucceeded(int messageCount)
{
setSucceeded();
_messageCount = messageCount;
}
public boolean isFinal()
{
return _isFinal;
}
public int getMessageCount()
{
return _messageCount;
}
@Override
public boolean invalidates(Message message)
{
return false;
}
}