com.signalfx.shaded.apache.commons.io.monitor.FileEntry Maven / Gradle / Ivy
Show all versions of signalfx-codahale Show documentation
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 com.signalfx.shaded.apache.commons.io.monitor;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.util.Objects;
import com.signalfx.shaded.apache.commons.io.FileUtils;
import com.signalfx.shaded.apache.commons.io.file.attribute.FileTimes;
/**
* The state of a file or directory, capturing the following {@link File} attributes at a point in time.
*
* - File Name (see {@link File#getName()})
* - Exists - whether the file exists or not (see {@link File#exists()})
* - Directory - whether the file is a directory or not (see {@link File#isDirectory()})
* - Last Modified Date/Time (see {@link FileUtils#lastModifiedUnchecked(File)})
* - Length (see {@link File#length()}) - directories treated as zero
* - Children - contents of a directory (see {@link File#listFiles(java.io.FileFilter)})
*
*
* Custom Implementations
*
* If the state of additional {@link File} attributes is required then create a custom
* {@link FileEntry} with properties for those attributes. Override the
* {@link #newChildInstance(File)} to return a new instance of the appropriate type.
* You may also want to override the {@link #refresh(File)} method.
*
* Deprecating Serialization
*
* Serialization is deprecated and will be removed in 3.0.
*
* @see FileAlterationObserver
* @since 2.0
*/
public class FileEntry implements Serializable {
private static final long serialVersionUID = -2505664948818681153L;
static final FileEntry[] EMPTY_FILE_ENTRY_ARRAY = {};
/** The parent. */
private final FileEntry parent;
/** My children. */
private FileEntry[] children;
/** Monitored file. */
private final File file;
/** Monitored file name. */
private String name;
/** Whether the file exists. */
private boolean exists;
/** Whether the file is a directory or not. */
private boolean directory;
/** The file's last modified timestamp. */
private SerializableFileTime lastModified = SerializableFileTime.EPOCH;
/** The file's length. */
private long length;
/**
* Constructs a new monitor for a specified {@link File}.
*
* @param file The file being monitored
*/
public FileEntry(final File file) {
this(null, file);
}
/**
* Constructs a new monitor for a specified {@link File}.
*
* @param parent The parent.
* @param file The file being monitored.
*/
public FileEntry(final FileEntry parent, final File file) {
this.file = Objects.requireNonNull(file, "file");
this.parent = parent;
this.name = file.getName();
}
/**
* Gets the directory's files.
*
* @return This directory's files or an empty
* array if the file is not a directory or the
* directory is empty
*/
public FileEntry[] getChildren() {
return children != null ? children : EMPTY_FILE_ENTRY_ARRAY;
}
/**
* Gets the file being monitored.
*
* @return the file being monitored
*/
public File getFile() {
return file;
}
/**
* Gets the last modified time from the last time it
* was checked.
*
* @return the last modified time in milliseconds.
*/
public long getLastModified() {
return lastModified.toMillis();
}
/**
* Gets the last modified time from the last time it was checked.
*
* @return the last modified time.
* @since 2.12.0
*/
public FileTime getLastModifiedFileTime() {
return lastModified.unwrap();
}
/**
* Gets the length.
*
* @return the length
*/
public long getLength() {
return length;
}
/**
* Gets the level
*
* @return the level
*/
public int getLevel() {
return parent == null ? 0 : parent.getLevel() + 1;
}
/**
* Gets the file name.
*
* @return the file name
*/
public String getName() {
return name;
}
/**
* Gets the parent entry.
*
* @return the parent entry
*/
public FileEntry getParent() {
return parent;
}
/**
* Tests whether the file is a directory or not.
*
* @return whether the file is a directory or not
*/
public boolean isDirectory() {
return directory;
}
/**
* Tests whether the file existed the last time it
* was checked.
*
* @return whether the file existed
*/
public boolean isExists() {
return exists;
}
/**
* Constructs a new child instance.
*
* Custom implementations should override this method to return
* a new instance of the appropriate type.
*
*
* @param file The child file
* @return a new child instance
*/
public FileEntry newChildInstance(final File file) {
return new FileEntry(this, file);
}
/**
* Refreshes the attributes from the {@link File}, indicating
* whether the file has changed.
*
* This implementation refreshes the {@code name}, {@code exists},
* {@code directory}, {@code lastModified} and {@code length}
* properties.
*
*
* The {@code exists}, {@code directory}, {@code lastModified}
* and {@code length} properties are compared for changes
*
*
* @param file the file instance to compare to
* @return {@code true} if the file has changed, otherwise {@code false}
*/
public boolean refresh(final File file) {
// cache original values
final boolean origExists = exists;
final SerializableFileTime origLastModified = lastModified;
final boolean origDirectory = directory;
final long origLength = length;
// refresh the values
name = file.getName();
exists = Files.exists(file.toPath());
directory = exists && file.isDirectory();
try {
setLastModified(exists ? FileUtils.lastModifiedFileTime(file) : FileTimes.EPOCH);
} catch (final IOException e) {
setLastModified(SerializableFileTime.EPOCH);
}
length = exists && !directory ? file.length() : 0;
// Return if there are changes
return exists != origExists || !lastModified.equals(origLastModified) || directory != origDirectory
|| length != origLength;
}
/**
* Sets the directory's files.
*
* @param children This directory's files, may be null
*/
public void setChildren(final FileEntry... children) {
this.children = children;
}
/**
* Sets whether the file is a directory or not.
*
* @param directory whether the file is a directory or not
*/
public void setDirectory(final boolean directory) {
this.directory = directory;
}
/**
* Sets whether the file existed the last time it
* was checked.
*
* @param exists whether the file exists or not
*/
public void setExists(final boolean exists) {
this.exists = exists;
}
/**
* Sets the last modified time from the last time it was checked.
*
* @param lastModified The last modified time.
* @since 2.12.0
*/
public void setLastModified(final FileTime lastModified) {
setLastModified(new SerializableFileTime(lastModified));
}
/**
* Sets the last modified time from the last time it
* was checked.
*
* @param lastModified The last modified time in milliseconds.
*/
public void setLastModified(final long lastModified) {
setLastModified(FileTime.fromMillis(lastModified));
}
void setLastModified(final SerializableFileTime lastModified) {
this.lastModified = lastModified;
}
/**
* Sets the length.
*
* @param length the length
*/
public void setLength(final long length) {
this.length = length;
}
/**
* Sets the file name.
*
* @param name the file name
*/
public void setName(final String name) {
this.name = name;
}
}