/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.chimera.posix;
import diskCacheV111.util.AccessLatency;
import diskCacheV111.util.RetentionPolicy;
import java.sql.Date;
import java.sql.Time;
import java.util.EnumSet;
import java.util.Formatter;
import org.dcache.chimera.UnixPermission;
/**
*
* Unix file stat structure abstraction
*
*/
public class Stat {
public enum StatAttributes {
DEV,
INO,
MODE,
NLINK,
UID,
GID,
RDEV,
SIZE,
FILEID,
GENERATION,
ATIME,
MTIME,
CTIME,
CRTIME,
BLK_SIZE,
ACCESS_LATENCY,
RETENTION_POLICY
}
/**
* Set of attributes defined in this {@code stat} object.
*/
private final EnumSet<StatAttributes> _definedAttrs = EnumSet.noneOf(StatAttributes.class);
private int _dev; //
private long _ino; //
private String _id;
private int _mode; //
private int _nlink; //
private int _uid; //
private int _gid; //
private int _rdev; //
private long _size; //
private long _generation; //
private int _accessLatency;
private int _retentionPolicy;
/*
* Opposite to classic Unix, all times in milliseconds
*/
/**
* Last access time.
*/
private long _atime;
/**
* Last modification time
*/
private long _mtime;
/**
* Last attribute change time.
*/
private long _ctime;
/**
* Creation time.
*/
private long _crtime;
public Stat()
{
}
public Stat(Stat stat)
{
_definedAttrs.addAll(stat._definedAttrs);
_dev = stat._dev;
_ino = stat._ino;
_id = stat._id;
_mode = stat._mode;
_nlink = stat._nlink;
_uid = stat._uid;
_gid = stat._gid;
_rdev = stat._rdev;
_size = stat._size;
_generation = stat._generation;
_accessLatency = stat._accessLatency;
_retentionPolicy = stat._retentionPolicy;
_atime = stat._atime;
_mtime = stat._mtime;
_ctime = stat._ctime;
_crtime = stat._crtime;
}
public int getDev() {
guard(StatAttributes.DEV);
return _dev;
}
public void setDev(int dev) {
define(StatAttributes.DEV);
_dev = dev;
}
public long getIno() {
guard(StatAttributes.INO);
return _ino;
}
public void setIno(long ino) {
define(StatAttributes.INO);
_ino = ino;
}
public String getId() {
guard(StatAttributes.FILEID);
return _id;
}
public void setId(String id) {
define(StatAttributes.FILEID);
_id = id;
}
public int getMode() {
guard(StatAttributes.MODE);
return _mode;
}
public void setMode(int mode) {
define(StatAttributes.MODE);
_mode = mode;
}
public int getNlink() {
guard(StatAttributes.NLINK);
return _nlink;
}
public void setNlink(int nlink) {
define(StatAttributes.NLINK);
_nlink = nlink;
}
public int getUid() {
guard(StatAttributes.UID);
return _uid;
}
public void setUid(int uid) {
define(StatAttributes.UID);
_uid = uid;
}
public int getGid() {
guard(StatAttributes.GID);
return _gid;
}
public void setGid(int gid) {
define(StatAttributes.GID);
_gid = gid;
}
public int getRdev() {
guard(StatAttributes.RDEV);
return _rdev;
}
public void setRdev(int rdev) {
define(StatAttributes.RDEV);
_rdev = rdev;
}
public long getSize() {
guard(StatAttributes.SIZE);
return _size;
}
public void setSize(long size) {
define(StatAttributes.SIZE);
_size = size;
}
public long getATime() {
guard(StatAttributes.ATIME);
return _atime;
}
public void setATime(long atime) {
define(StatAttributes.ATIME);
_atime = atime;
}
public long getMTime() {
guard(StatAttributes.MTIME);
return _mtime;
}
public void setMTime(long mtime) {
define(StatAttributes.MTIME);
_mtime = mtime;
}
public long getCTime() {
guard(StatAttributes.CTIME);
return _ctime;
}
public void setCTime(long ctime) {
define(StatAttributes.CTIME);
_ctime = ctime;
}
public long getGeneration() {
guard(StatAttributes.GENERATION);
return _generation;
}
public void setGeneration(long generation) {
define(StatAttributes.GENERATION);
_generation = generation;
}
/**
* Set creation time in milliseconds
*
* @param newCrTime
*/
public void setCrTime(long newCrTime) {
define(StatAttributes.CRTIME);
_crtime = newCrTime;
}
/**
*
* @return creation time in milliseconds
*/
public long getCrTime() {
guard(StatAttributes.CRTIME);
return _crtime;
}
public AccessLatency getAccessLatency() {
guard(StatAttributes.ACCESS_LATENCY);
return AccessLatency.getAccessLatency(_accessLatency);
}
public void setAccessLatency(AccessLatency accessLatency) {
define(StatAttributes.ACCESS_LATENCY);
_accessLatency = accessLatency.getId();
}
public RetentionPolicy getRetentionPolicy() {
guard(StatAttributes.RETENTION_POLICY);
return RetentionPolicy.getRetentionPolicy(_retentionPolicy);
}
public void setRetentionPolicy(RetentionPolicy retentionPolicy) {
define(StatAttributes.RETENTION_POLICY);
_retentionPolicy = retentionPolicy.getId();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
try (Formatter formatter = new Formatter(sb)) {
formatter.format(
"%s %8d %6d %6d %6d %6d %s %s",
new UnixPermission(this.getMode()),
this.getNlink(),
this.getUid(),
this.getGid(),
this.getSize(),
this.getGeneration(),
new Date(this.getMTime()),
new Time(this.getMTime()));
formatter.flush();
}
return sb.toString();
}
@Override
public int hashCode() {
int hash = 5;
hash = 79 * hash + this._dev;
hash = 79 * hash + (int) (this._ino ^ (this._ino >>> 32));
hash = 79 * hash + this._mode;
hash = 79 * hash + this._nlink;
hash = 79 * hash + this._uid;
hash = 79 * hash + this._gid;
hash = 79 * hash + this._rdev;
hash = 79 * hash + (int) (this._size ^ (this._size >>> 32));
hash = 79 * hash + (int) (this._atime ^ (this._atime >>> 32));
hash = 79 * hash + (int) (this._mtime ^ (this._mtime >>> 32));
hash = 79 * hash + (int) (this._ctime ^ (this._ctime >>> 32));
hash = 79 * hash + (int) (this._crtime ^ (this._crtime >>> 32));
hash = 79 * hash + (int) (this._generation ^ (this._generation >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Stat other = (Stat) obj;
if (this._dev != other._dev) {
return false;
}
if (this._ino != other._ino) {
return false;
}
if (this._mode != other._mode) {
return false;
}
if (this._nlink != other._nlink) {
return false;
}
if (this._uid != other._uid) {
return false;
}
if (this._gid != other._gid) {
return false;
}
if (this._rdev != other._rdev) {
return false;
}
if (this._size != other._size) {
return false;
}
if (this._atime != other._atime) {
return false;
}
if (this._mtime != other._mtime) {
return false;
}
if (this._ctime != other._ctime) {
return false;
}
if (this._crtime != other._crtime) {
return false;
}
return true;
}
/**
* Check is attribute defined in this {@code stat} object;
*
* @param attr attribute to check
* @return true iff specified attribute is defined in this stat object.
*/
public boolean isDefined(StatAttributes attr) {
return _definedAttrs.contains(attr);
}
/**
* Throws IllegalStateException if attribute is not defined.
*/
private void guard(StatAttributes attr) throws IllegalStateException {
if (!isDefined(attr)) {
throw new IllegalStateException("Attribute is not defined: " + attr);
}
}
private void define(StatAttributes attr) throws IllegalStateException {
_definedAttrs.add(attr);
}
/**
* Returns <tt>true</tt> iff at least one attribute is set.
* @return <tt>true</tt> iff at least one attribute is set.
*/
public boolean isDefinedAny() {
return !_definedAttrs.isEmpty();
}
public EnumSet<StatAttributes> getDefinedAttributeses() {
return EnumSet.copyOf(_definedAttrs);
}
/**
* Update stat with values provided by <tt>other</tt> Stat.
* @param other to get values from.
*/
public void update(Stat other) {
for (Stat.StatAttributes attr : other.getDefinedAttributeses()) {
switch (attr) {
case DEV:
this.setDev(other.getDev());
break;
case MODE:
this.setMode(other.getMode() & UnixPermission.S_PERMS | getMode() & ~UnixPermission.S_PERMS);
break;
case NLINK:
this.setNlink(other.getNlink());
break;
case UID:
this.setUid(other.getUid());
break;
case GID:
this.setGid(other.getGid());
break;
case RDEV:
this.setRdev(other.getRdev());
break;
case SIZE:
this.setSize(other.getSize());
break;
case FILEID:
case INO:
break;
case GENERATION:
this.setGeneration(other.getGeneration());
break;
case ATIME:
this.setATime(other.getATime());
break;
case MTIME:
this.setMTime(other.getMTime());
break;
case CTIME:
this.setCTime(other.getCTime());
break;
case CRTIME:
this.setCrTime(other.getCrTime());
break;
case BLK_SIZE:
break;
}
}
}
}