sigar/bindings/java/src/org/hyperic/sigar/FileInfo.java

490 lines
12 KiB
Java

/*
* Copyright (c) 2006-2007 Hyperic, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hyperic.sigar;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class FileInfo extends FileAttrs implements java.io.Serializable {
private static final long serialVersionUID = 02242007L;
private static final SimpleDateFormat DATE_FORMAT =
new SimpleDateFormat("MMM dd HH:mm");
String name;
private transient Sigar sigar;
private boolean dirStatEnabled = false;
private DirStat stat = null;
private boolean lstat;
private FileInfo oldInfo = null;
/**
* No file type determined.
*/
public static final int TYPE_NOFILE = 0;
/**
* A regular file.
*/
public static final int TYPE_REG = 1;
/**
* A directory.
*/
public static final int TYPE_DIR = 2;
/**
* A character device.
*/
public static final int TYPE_CHR = 3;
/**
* A block device.
*/
public static final int TYPE_BLK = 4;
/**
* A FIFO / pipe.
*/
public static final int TYPE_PIPE = 5;
/**
* A symbolic link.
*/
public static final int TYPE_LNK = 6;
/**
* A [unix domain] socket.
*/
public static final int TYPE_SOCK = 7;
/**
* A file of unknown type.
*/
public static final int TYPE_UNKFILE = 8;
/**
* Readable by user.
*/
public static final int MODE_UREAD = 0x0400;
/**
* Writable by user.
*/
public static final int MODE_UWRITE = 0x0200;
/**
* Executable by user.
*/
public static final int MODE_UEXECUTE = 0x0100;
/**
* Readable by group.
*/
public static final int MODE_GREAD = 0x0040;
/**
* Writable by group.
*/
public static final int MODE_GWRITE = 0x0020;
/**
* Executable by group.
*/
public static final int MODE_GEXECUTE = 0x0010;
/**
* Readable by others.
*/
public static final int MODE_WREAD = 0x0004;
/**
* Writable by others.
*/
public static final int MODE_WWRITE = 0x0002;
/**
* Executable by others.
*/
public static final int MODE_WEXECUTE = 0x0001;
private static native String getTypeString(int type);
native void gatherLink(Sigar sigar, String name)
throws SigarException;
public String getTypeString() {
return FileInfo.getTypeString(this.type);
}
public char getTypeChar() {
switch (this.type) {
case TYPE_DIR:
return 'd';
case TYPE_CHR:
return 'c';
case TYPE_BLK:
return 'b';
case TYPE_PIPE:
return 'p';
case TYPE_LNK:
return 'l';
case TYPE_SOCK:
return 's';
default:
return '-';
}
}
public String getName() {
return this.name;
}
public int hashCode() {
return this.name.hashCode();
}
public boolean equals(Object o) {
return o.equals(this.name);
}
private static native String getPermissionsString(long type);
public String getPermissionsString() {
return FileInfo.getPermissionsString(this.permissions);
}
private static native int getMode(long permissions);
/**
* Convert permissions bit mask to human readable number.
* Example:
* <code>MODE_UREAD|MODE_UWRITE|MODE_GREAD|MODE_WREAD</code>
* converts to <code>644</code>.
* @return The file permissions mode.
*/
public int getMode() {
return FileInfo.getMode(this.permissions);
}
public void enableDirStat(boolean value) {
this.dirStatEnabled = value;
if (value) {
if (this.type != TYPE_DIR) {
throw new IllegalArgumentException(this.name + " is not a directory");
}
try {
if (this.stat == null) {
this.stat = this.sigar.getDirStat(this.name);
}
else {
this.stat.gather(this.sigar, this.name);
}
} catch (SigarException e) {
//ok for now
}
}
}
private class Diff {
private String attr, old, cur;
Diff(String attr, String old, String cur) {
this.attr = attr;
this.old = old;
this.cur = cur;
}
Diff(String attr, int old, int cur) {
this(attr,
String.valueOf(old),
String.valueOf(cur));
}
Diff(String attr, long old, long cur) {
this(attr,
String.valueOf(old),
String.valueOf(cur));
}
public String toString() {
return this.attr + ": " +
this.old + "|" + this.cur;
}
}
private StringBuffer format(ArrayList changes) {
StringBuffer sb = new StringBuffer();
if (changes.size() == 0) {
return sb;
}
int size = changes.size();
for (int i=0; i<size; i++) {
sb.append('{').append(changes.get(i)).append('}');
}
return sb;
}
private static String formatDate(long time) {
return DATE_FORMAT.format(new Date(time));
}
public String diff() {
if (this.oldInfo == null) {
return "";
}
return diff(this.oldInfo);
}
public String diff(DirStat stat) {
DirStat thisStat = this.stat;
ArrayList changes = new ArrayList();
if (thisStat.files != stat.files) {
changes.add(new Diff("Files",
stat.getFiles(),
thisStat.getFiles()));
}
if (thisStat.subdirs != stat.subdirs) {
changes.add(new Diff("Subdirs",
stat.getSubdirs(),
thisStat.getSubdirs()));
}
if (thisStat.symlinks != stat.symlinks) {
changes.add(new Diff("Symlinks",
stat.getSymlinks(),
thisStat.getSymlinks()));
}
if (thisStat.chrdevs != stat.chrdevs) {
changes.add(new Diff("Chrdevs",
stat.getChrdevs(),
thisStat.getChrdevs()));
}
if (thisStat.blkdevs != stat.blkdevs) {
changes.add(new Diff("Blkdevs",
stat.getBlkdevs(),
thisStat.getBlkdevs()));
}
if (thisStat.sockets != stat.sockets) {
changes.add(new Diff("Sockets",
stat.getSockets(),
thisStat.getSockets()));
}
if (thisStat.total != stat.total) {
changes.add(new Diff("Total",
stat.getTotal(),
thisStat.getTotal()));
}
return format(changes).toString();
}
public String diff(FileInfo info) {
ArrayList changes = new ArrayList();
if (this.getMtime() != info.getMtime()) {
changes.add(new Diff("Mtime", formatDate(info.getMtime()),
formatDate(this.getMtime())));
} else if (this.getCtime() != info.getCtime()) {
changes.add(new Diff("Ctime", formatDate(info.getCtime()),
formatDate(this.getCtime())));
}
if (this.getPermissions() != info.getPermissions()) {
changes.add(new Diff("Perms", info.getPermissionsString(), this
.getPermissionsString()));
}
if (this.getType() != info.getType()) {
changes.add(new Diff("Type", info.getTypeString(), this
.getTypeString()));
}
if (this.getUid() != info.getUid()) {
changes.add(new Diff("Uid", info.getUid(), this.getUid()));
}
if (this.getGid() != info.getGid()) {
changes.add(new Diff("Gid", info.getGid(), this.getGid()));
}
if (this.getSize() != info.getSize()) {
changes.add(new Diff("Size", info.getSize(), this.getSize()));
}
if (!OperatingSystem.IS_WIN32) {
if (this.getInode() != info.getInode()) {
changes.add(new Diff("Inode", info.getInode(), this.getInode()));
}
if (this.getDevice() != info.getDevice()) {
changes.add(new Diff("Device", info.getDevice(), this
.getDevice()));
}
if (this.getNlink() != info.getNlink()) {
changes.add(new Diff("Nlink", info.getNlink(), this.getNlink()));
}
}
/* if changes were not detected then return empty String */
if (changes.isEmpty()){
return "";
}
StringBuffer sb = format(changes);
if (this.dirStatEnabled) {
sb.append(diff(info.stat));
}
return sb.toString();
}
public FileInfo getPreviousInfo() {
return this.oldInfo;
}
public boolean modified()
throws SigarException,
SigarFileNotFoundException {
if (this.oldInfo == null) {
this.oldInfo = new FileInfo();
if (this.dirStatEnabled) {
this.oldInfo.stat = new DirStat();
}
}
copyTo(this.oldInfo);
if (this.dirStatEnabled) {
this.stat.copyTo(this.oldInfo.stat);
}
stat();
boolean isModified = isModified(this.oldInfo);
return isModified;
}
public boolean changed()
throws SigarException,
SigarFileNotFoundException {
return modified() || (this.ctime != oldInfo.ctime);
}
public void stat()
throws SigarException,
SigarFileNotFoundException {
long mtime = this.mtime;
if (this.lstat) {
this.gatherLink(this.sigar, this.name);
}
else {
this.gather(this.sigar, this.name);
}
if (this.dirStatEnabled &&
(mtime != this.mtime)) //no need to fetch stat if unmodified.
{
this.stat.gather(this.sigar, this.name);
}
}
private static FileInfo fetchInfo(Sigar sigar, String name,
boolean followSymlinks)
throws SigarException {
FileInfo info = new FileInfo();
try {
if (followSymlinks) {
info.gather(sigar, name);
info.lstat = false;
}
else {
info.gatherLink(sigar, name);
info.lstat = true;
}
} catch (SigarException e) {
e.setMessage(name + ": " + e.getMessage());
throw e;
}
info.sigar = sigar;
info.name = name;
return info;
}
static FileInfo fetchFileInfo(Sigar sigar, String name)
throws SigarException {
return fetchInfo(sigar, name, true);
}
static FileInfo fetchLinkInfo(Sigar sigar, String name)
throws SigarException {
return fetchInfo(sigar, name, false);
}
private boolean isModified(FileInfo info){
/* Check modified time */
if (this.getMtime() != info.getMtime()) {
return true;
} else if (this.getCtime() != info.getCtime()) {
return true;
}
if (this.getPermissions() != info.getPermissions()) {
return true;
}
if (this.getType() != info.getType()) {
return true;
}
if (this.getUid() != info.getUid()) {
return true;
}
if (this.getGid() != info.getGid()) {
return true;
}
if (this.getSize() != info.getSize()) {
return true;
}
if (!OperatingSystem.IS_WIN32) {
if (this.getInode() != info.getInode()) {
return true;
}
if (this.getDevice() != info.getDevice()) {
return true;
}
if (this.getNlink() != info.getNlink()) {
return true;
}
}
return false;
}
}