/* * Copyright (C) 2006-2008 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.jlan.server.filesys; import java.io.IOException; import org.alfresco.jlan.locking.FileLock; import org.alfresco.jlan.locking.FileLockList; /** * <p> * The network file represents a file or directory on a filesystem. The server keeps track of the * open files on a per session basis. * * <p> * This class may be extended as required by your own disk driver class. * * @author gkspencer */ public abstract class NetworkFile { // Granted file access types public static final int READONLY = 0; public static final int WRITEONLY = 1; public static final int READWRITE = 2; // File status flags public static final int IOPending = 0x0001; public static final int DeleteOnClose = 0x0002; public static final int DelayedWriteError = 0x0004; public static final int Created = 0x0008; // File identifier and parent directory identifier protected int m_fid; protected int m_dirId; // Unique file identifier protected long m_uniqueId; // File/directory name protected String m_name; // Stream name and id protected String m_streamName; protected int m_streamId; // Full name, relative to the share protected String m_fullName; // File attributes protected int m_attrib; // File size protected long m_fileSize; // File creation/modify/last access date/time protected long m_createDate; protected long m_modifyDate; protected long m_accessDate; // Granted file access type protected int m_grantedAccess; // Flag to indicate that the file has been closed protected boolean m_closed = true; // Count of write requests to the file, used to determine if the file size may have changed protected int m_writeCount; // List of locks on this file by this session. The lock object will almost certainly be // referenced elsewhere depending upon the LockManager implementation used. If locking support is not // enabled for the DiskInterface implementation the lock list will not be allocated. // // This lock list is used to release locks on the file if the session abnormally terminates or // closes the file without releasing all locks. private FileLockList m_lockList; // File status flags private int m_flags; /** * Create a network file object with the specified file identifier. * * @param fid int */ public NetworkFile(int fid) { m_fid = fid; } /** * Create a network file with the specified file and parent directory ids * * @param fid int * @param did int */ public NetworkFile(int fid, int did) { m_fid = fid; m_dirId = did; } /** * Create a network file with the specified file id, stream id and parent directory id * * @param fid int * @param stid int * @param did int */ public NetworkFile(int fid, int stid, int did) { m_fid = fid; m_streamId = stid; m_dirId = did; } /** * Create a network file object with the specified file/directory name. * * @param name File name string. */ public NetworkFile(String name) { m_name = name; } /** * Return the parent directory identifier * * @return int */ public final int getDirectoryId() { return m_dirId; } /** * Return the file attributes. * * @return int */ public final int getFileAttributes() { return m_attrib; } /** * Return the file identifier. * * @return int */ public final int getFileId() { return m_fid; } /** * Get the file size, in bytes. * * @return long */ public final long getFileSize() { return m_fileSize; } /** * Get the file size, in bytes. * * @return int */ public final int getFileSizeInt() { return (int) (m_fileSize & 0x0FFFFFFFFL); } /** * Return the full name, relative to the share. * * @return java.lang.String */ public final String getFullName() { return m_fullName; } /** * Return the full name including the stream name, relative to the share. * * @return java.lang.String */ public final String getFullNameStream() { if ( isStream()) return m_fullName + m_streamName; else return m_fullName; } /** * Return the granted file access mode. */ public final int getGrantedAccess() { return m_grantedAccess; } /** * Return the file/directory name. * * @return java.lang.String */ public String getName() { return m_name; } /** * Return the stream id, zero indicates the main file stream * * @return int */ public final int getStreamId() { return m_streamId; } /** * Return the stream name, if this is a stream * * @return String */ public final String getStreamName() { return m_streamName; } /** * Return the unique file identifier * * @return long */ public final long getUniqueId() { return m_uniqueId; } /** * Determine if the file has been closed. * * @return boolean */ public final boolean isClosed() { return m_closed; } /** * Return the directory file attribute status. * * @return true if the file is a directory, else false. */ public final boolean isDirectory() { return (m_attrib & FileAttribute.Directory) != 0 ? true : false; } /** * Return the hidden file attribute status. * * @return true if the file is hidden, else false. */ public final boolean isHidden() { return (m_attrib & FileAttribute.Hidden) != 0 ? true : false; } /** * Return the read-only file attribute status. * * @return true if the file is read-only, else false. */ public final boolean isReadOnly() { return (m_attrib & FileAttribute.ReadOnly) != 0 ? true : false; } /** * Return the system file attribute status. * * @return true if the file is a system file, else false. */ public final boolean isSystem() { return (m_attrib & FileAttribute.System) != 0 ? true : false; } /** * Return the archived attribute status * * @return boolean */ public final boolean isArchived() { return (m_attrib & FileAttribute.Archive) != 0 ? true : false; } /** * Check if this is a stream file * * @return boolean */ public final boolean isStream() { return m_streamName != null ? true : false; } /** * Check if there are active locks on this file by this session * * @return boolean */ public final boolean hasLocks() { if ( m_lockList != null && m_lockList.numberOfLocks() > 0) return true; return false; } /** * Check for NT attributes * * @param attr int * @return boolean */ public final boolean hasNTAttribute(int attr) { return (m_attrib & attr) == attr ? true : false; } /** * Determine if the file access date/time is valid * * @return boolean */ public final boolean hasAccessDate() { return m_accessDate != 0L ? true : false; } /** * Return the file access date/time * * @return long */ public final long getAccessDate() { return m_accessDate; } /** * Determine if the file creation date/time is valid * * @return boolean */ public final boolean hasCreationDate() { return m_createDate != 0L ? true : false; } /** * Return the file creation date/time * * @return long */ public final long getCreationDate() { return m_createDate; } /** * Check if a delayed write error has occurred on this file * * @return boolean */ public final boolean hasDelayedWriteError() { return (m_flags & DelayedWriteError) != 0 ? true : false; } /** * Check if the delete on close flag has been set for this file * * @return boolean */ public final boolean hasDeleteOnClose() { return (m_flags & DeleteOnClose) != 0 ? true : false; } /** * Check if the file has an I/O request pending * * @return boolean */ public final boolean hasIOPending() { return (m_flags & IOPending) != 0 ? true : false; } /** * Check if the file was created during the open * * @return boolean */ public final boolean wasCreated() { return ( m_flags & Created) != 0 ? true : false; } /** * Determine if the file modification date/time is valid * * @return boolean */ public boolean hasModifyDate() { return m_modifyDate != 0L ? true : false; } /** * Return the file modify date/time * * @return long */ public final long getModifyDate() { return m_modifyDate; } /** * Get the write count for the file * * @return int */ public final int getWriteCount() { return m_writeCount; } /** * Increment the write count */ public final void incrementWriteCount() { m_writeCount++; } /** * Set the file attributes, as specified by the SMBFileAttribute class. * * @param attrib int */ public final void setAttributes(int attrib) { m_attrib = attrib; } /** * Set, or clear, the delete on close flag * * @param del boolean */ public final void setDeleteOnClose(boolean del) { setStatusFlag(DeleteOnClose, del); } /** * Set the parent directory identifier * * @param dirId int */ public final void setDirectoryId(int dirId) { m_dirId = dirId; } /** * Set the file identifier. * * @param fid int */ public final void setFileId(int fid) { m_fid = fid; } /** * Set the file size. * * @param siz long */ public final void setFileSize(long siz) { m_fileSize = siz; } /** * Set the file size. * * @param siz int */ public final void setFileSize(int siz) { m_fileSize = siz; } /** * Set the full file name, relative to the share. * * @param name java.lang.String */ public final void setFullName(String name) { m_fullName = name; } /** * Set the granted file access mode. * * @param mode int */ public final void setGrantedAccess(int mode) { m_grantedAccess = mode; } /** * Set the file name. * * @param name String */ public final void setName(String name) { m_name = name; } /** * set/clear the I/O pending flag * * @param pending boolean */ public final void setIOPending(boolean pending) { setStatusFlag(IOPending, pending); } /** * Set the stream id * * @param id int */ public final void setStreamId(int id) { m_streamId = id; } /** * Set the stream name * * @param name String */ public final void setStreamName(String name) { m_streamName = name; } /** * Set the file closed state. * * @param b boolean */ public final synchronized void setClosed(boolean b) { m_closed = b; } /** * Set the file access date/time * * @param dattim long */ public final void setAccessDate(long dattim) { m_accessDate = dattim; } /** * Set the file creation date/time * * @param dattim long */ public final void setCreationDate(long dattim) { m_createDate = dattim; } /** * Set or clear the delayed write error flag * * @param err boolean */ public final void setDelayedWriteError(boolean err) { setStatusFlag(DelayedWriteError, err); } /** * Set the file modification date/time * * @param dattim long */ public final void setModifyDate(long dattim) { m_modifyDate = dattim; } /** * Set/clear a file status flag * * @param flag int * @param sts boolean */ public final synchronized void setStatusFlag(int flag, boolean sts) { boolean state = (m_flags & flag) != 0; if ( sts == true && state == false) m_flags += flag; else if ( sts == false && state == true) m_flags -= flag; } /** * Add a lock to the active lock list * * @param lock FileLock */ public final synchronized void addLock(FileLock lock) { // Check if the lock list has been allocated if ( m_lockList == null) m_lockList = new FileLockList(); // Add the lock m_lockList.addLock(lock); } /** * Remove a lock from the active lock list * * @param lock FileLock */ public final synchronized void removeLock(FileLock lock) { // Check if the lock list is allocated if ( m_lockList == null) return; // Remove the lock m_lockList.removeLock(lock); } /** * Remove all locks from the lock list */ public final synchronized void removeAllLocks() { // Check if the lock list is valid if ( m_lockList != null) m_lockList.removeAllLocks(); } /** * Return the count of active locks * * @return int */ public final int numberOfLocks() { // Check if the lock list is allocated if ( m_lockList == null) return 0; return m_lockList.numberOfLocks(); } /** * Get the details of an active lock from the list * * @param idx int * @return FileLock */ public final FileLock getLockAt(int idx) { // Check if the lock list is allocated and the index is valid if ( m_lockList != null) return m_lockList.getLockAt(idx); // Invalid index or lock list not valid return null; } /** * Return the lock list * * @return FileLockList */ public final FileLockList getLockList() { return m_lockList; } /** * Set the unique file identifier * * @param id long */ protected final void setUniqueId(long id) { m_uniqueId = id; } /** * Set the unique id using the file and directory id * * @param fid int * @param did int */ protected final void setUniqueId(int fid, int did) { long ldid = did; long lfid = fid; m_uniqueId = (ldid << 32) + lfid; } /** * Set the unique id using the full path string * * @param path String */ protected final void setUniqueId(String path) { m_uniqueId = path.toUpperCase().hashCode(); } /** * Open the file * * @param createFlag boolean * @exception IOException */ public abstract void openFile(boolean createFlag) throws IOException; /** * Read from the file. * * @param buf byte[] * @param len int * @param pos int * @param fileOff long * @return Length of data read. * @exception IOException */ public abstract int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException; /** * Write a block of data to the file. * * @param buf byte[] * @param len int * @param pos int * @param fileOff long * @exception IOException */ public abstract void writeFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException; /** * Seek to the specified file position. * * @param pos long * @param typ int * @return int * @exception IOException */ public abstract long seekFile(long pos, int typ) throws IOException; /** * Flush any buffered output to the file * * @throws IOException */ public abstract void flushFile() throws IOException; /** * Truncate the file to the specified file size * * @param siz long * @exception IOException */ public abstract void truncateFile(long siz) throws IOException; /** * Close the database file */ public abstract void closeFile() throws IOException; /** * Temporary method */ public void close() throws IOException { closeFile(); } }