uk.ac.rdg.resc.jstyx.server
Class StyxFile

java.lang.Object
  extended by uk.ac.rdg.resc.jstyx.server.StyxFile
Direct Known Subclasses:
AsyncStyxFile, ExitCodeFile, FileOnDisk, InMemoryFile, SGSInputFile, SGSOutputFile, StyxDirectory, URLFile, WhoAmIFile

public class StyxFile
extends java.lang.Object

Class representing a file (or directory) on a Styx server. There may be different types of file; a file might map directly to a file on disk, or it may be a synthetic file representing a program interface. This class creates a StyxFile that does nothing useful, returning errors when reading from or writing to it. Subclasses should override the read(), write() and getLength() methods to implement the desired behaviour. Currently each StyxFile has exactly one parent. Therefore symbolic links on the host filesystem cannot currently be handled.

Author:
Jon Blower $Revision: 602 $ $Date: 2006-03-21 09:06:15 +0000 (Tue, 21 Mar 2006) $ $Log$ Revision 1.25 2006/03/21 09:06:15 jonblower Still implementing authentication Revision 1.24 2006/03/20 17:51:50 jonblower Adding authentication to base JStyx system Revision 1.23 2006/02/17 09:22:32 jonblower Added rename() method Revision 1.22 2006/01/04 16:47:29 jonblower Reworked getName() and getFullPath() Revision 1.21 2005/12/01 08:21:56 jonblower Fixed javadoc comments Revision 1.20 2005/11/04 19:33:41 jonblower Changed contentsChanged() to fileContentsChanged() in StyxFileChangeListener Revision 1.19 2005/11/03 21:50:04 jonblower Added clarification to comments Revision 1.18 2005/09/08 07:08:59 jonblower Removed "String user" from list of parameters to StyxFile.write() Revision 1.17 2005/08/30 16:29:00 jonblower Added processAndReplyRead() helper functions to StyxFile Revision 1.16 2005/07/06 17:42:47 jonblower Changed getUniqueID() to be based on creation time in addition to file name Revision 1.15 2005/05/10 08:02:18 jonblower Changes related to implementing MonitoredFileOnDisk Revision 1.14 2005/05/09 07:12:52 jonblower Clarified some comments Revision 1.13 2005/04/28 08:11:15 jonblower Modified permissions handling in documentation directory of SGS Revision 1.12 2005/04/27 16:11:43 jonblower Added capability to add documentation files to SGS namespace Revision 1.11 2005/03/24 14:47:47 jonblower Provided default read() and write() methods for StyxFile so it is no longer abstract Revision 1.10 2005/03/24 09:48:32 jonblower Changed 'count' from long to int throughout for reading and writing Revision 1.9 2005/03/24 07:57:41 jonblower Improved code for reading SSL info from SGSconfig file and included parameter information for the Grid Services in the config file Revision 1.8 2005/03/19 21:47:02 jonblower Further fixes relating to releasing ByteBuffers Revision 1.7 2005/03/18 16:45:18 jonblower Released ByteBuffers after use Revision 1.6 2005/03/18 13:56:00 jonblower Improved freeing of ByteBuffers, and bug fixes Revision 1.5 2005/03/16 22:16:43 jonblower Added Styx Grid Service classes to core module Revision 1.4 2005/03/16 17:56:24 jonblower Replaced use of java.nio.ByteBuffer with MINA's ByteBuffer to minimise copying of buffers Revision 1.3 2005/03/11 14:02:16 jonblower Merged MINA-Test_20059309 into main line of development Revision 1.2.2.2 2005/03/10 11:53:54 jonblower Modified for MINA framework Revision 1.2.2.1 2005/03/09 19:44:18 jonblower Changes concerned with migration to MINA Revision 1.2 2005/03/01 13:47:43 jonblower Changed default user and group to 'user' and 'group' Revision 1.1.1.1 2005/02/16 18:58:32 jonblower Initial import

Field Summary
protected  boolean auth
           
protected  boolean directory
           
protected  long lastModifiedTime
           
protected  java.lang.String name
           
protected  StyxDirectory parent
           
 
Constructor Summary
StyxFile(java.lang.String name)
          Creates a StyxFile with the default permissions (0666, rw-rw-rw-)
StyxFile(java.lang.String name, int permissions)
           
StyxFile(java.lang.String name, int permissions, boolean isAppendOnly, boolean isExclusive)
          Creates a StyxFile with the default username and group
StyxFile(java.lang.String name, java.lang.String owner, java.lang.String group, int permissions, boolean isAppendOnly, boolean isExclusive)
           
 
Method Summary
 void addChangeListener(StyxFileChangeListener listener)
          Registers a StyxFileChangeListener.
 void addClient(StyxFileClient client)
          Adds the given client to the file's list of connected clients.
 void checkSetLastModifiedTime(long lastModifiedTime)
           
 void checkSetLength(ULong newLength)
          Check to see if the length of this file can be changed to the given value.
 void checkSetMode(long newMode)
          Checks to see if this file allows the mode (permissions plus flags) of the file to be changed.
 void checkSetName(java.lang.String newName)
           
protected  void clientConnected(StyxFileClient client)
          Called after a client connects to this file (i.e.
protected  void clientDisconnected(StyxFileClient client)
          Called after a client disconnects from this file (i.e.
 void contentsChanged()
          Call this to indicate that the file's data have changed.
protected  void delete()
          Called when the file is removed from the server.
protected  void fireContentsChanged()
          This method is called when the contents of the file change.
 StyxFileClient getClient(org.apache.mina.protocol.ProtocolSession session, long fid)
          Gets the StyxFileClient associated with the given Session and fid, or null if client does not exist
 DirEntry getDirEntry()
           
 java.lang.String getFullPath()
          Gets the full path relative to the root of this file system.
 java.lang.String getGroup()
           
 ULong getLength()
           
 java.lang.String getName()
           
 int getNumClients()
           
 java.lang.String getOwner()
           
 StyxDirectory getParent()
          Returns the parent of this file.
 int getPermissions()
           
 Qid getQid()
           
 long getVersion()
           
protected  void incrementVersion()
          Increments the file's version number and ensures that the version number never exceeds the maximum value of an unsigned 4-byte integer (it wraps back to zero if the version number gets this large)
 boolean isAppendOnly()
           
 boolean isAuth()
           
 boolean isDirectory()
           
 boolean isExclusive()
           
 void processAndReplyRead(byte[] fileContents, StyxFileClient client, long offset, int count, int tag)
          Method for processing a read request and replying appropriately to the client, based on the contents of the file.
 void processAndReplyRead(org.apache.mina.common.ByteBuffer fileContents, StyxFileClient client, long offset, int count, int tag)
          Method for processing a read request and replying appropriately to the client, based on the contents of the file.
 void processAndReplyRead(java.lang.String fileContents, StyxFileClient client, long offset, int count, int tag)
          Method for processing a read request and replying appropriately to the client, based on the contents of the file.
 void read(StyxFileClient client, long offset, int count, int tag)
          Reads data from this file.
 void refresh()
          Refreshes this file (if it represents another entity, such as a file on disk, this method is used to make sure that the file metadata (length, access time etc) are up to date.
 void remove()
          Removes this file from the Styx server
 void removeChangeListener(StyxFileChangeListener listener)
          Removes a change listener.
 void removeClient(StyxFileClient client)
          Removes the client that is connected on the given session.
 void rename(java.lang.String newName)
          Renames this file to the given name.
protected  void replyRead(StyxFileClient client, byte[] bytes, int tag)
          Method to reply to a Read message.
protected  void replyRead(StyxFileClient client, byte[] bytes, int pos, int count, int tag)
          Method to reply to a Read message.
protected  void replyRead(StyxFileClient client, java.nio.ByteBuffer buf, int tag)
          Method to reply to a Read message.
protected  void replyRead(StyxFileClient client, org.apache.mina.common.ByteBuffer buf, int tag)
          Method to reply to a Read message.
protected  void replyRead(StyxFileClient client, RreadMessage rReadMsg)
          Method to reply to a Read message.
protected  void replyWrite(StyxFileClient client, int count, int tag)
          Method to reply to a Write message.
 void setLastAccessTime(long lastAccessTime)
           
 void setLastModified(long lastModifiedTime, User user)
          Sets the last modified time of the file.
 void setLength(ULong newLength)
          Sets the length of the file.
 void setMode(long newMode)
          Sets the mode of the file (permissions plus other flags).
 void setName(java.lang.String name)
          Changes the name of the file.
 void setPermissions(int permissions)
          Sets the permissions of the file
 void setReadOnly()
          Makes the file read-only (e.g.
 void write(StyxFileClient client, long offset, int count, org.apache.mina.common.ByteBuffer data, boolean truncate, int tag)
          Writes data to this file.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

name

protected java.lang.String name

parent

protected StyxDirectory parent

directory

protected boolean directory

auth

protected boolean auth

lastModifiedTime

protected long lastModifiedTime
Constructor Detail

StyxFile

public StyxFile(java.lang.String name,
                java.lang.String owner,
                java.lang.String group,
                int permissions,
                boolean isAppendOnly,
                boolean isExclusive)
         throws StyxException
Throws:
StyxException - if an attempt is made to create a file with the name "", "." or ".."

StyxFile

public StyxFile(java.lang.String name,
                int permissions,
                boolean isAppendOnly,
                boolean isExclusive)
         throws StyxException
Creates a StyxFile with the default username and group

Throws:
StyxException

StyxFile

public StyxFile(java.lang.String name,
                int permissions)
         throws StyxException
Throws:
StyxException

StyxFile

public StyxFile(java.lang.String name)
         throws StyxException
Creates a StyxFile with the default permissions (0666, rw-rw-rw-)

Throws:
StyxException
Method Detail

getName

public java.lang.String getName()
Returns:
the name of the file, or the empty string if this is the root directory

checkSetName

public void checkSetName(java.lang.String newName)
                  throws StyxException
Throws:
StyxException - if the name of this file cannot be changed

setName

public void setName(java.lang.String name)
Changes the name of the file. Must have checked for correct permissions before doing this. Also must call checkSetName() to check if this method will succeed.


isDirectory

public boolean isDirectory()
Returns:
true if this StyxFile is a directory (should always return the same result as "instanceof StyxDirectory")

isAppendOnly

public boolean isAppendOnly()

isExclusive

public boolean isExclusive()
Returns:
true if this file is marked for exclusive use

isAuth

public boolean isAuth()

getFullPath

public java.lang.String getFullPath()
Gets the full path relative to the root of this file system.


getLength

public ULong getLength()
Returns:
the length of the file. This default implementation returns zero; subclasses should override this method

getParent

public StyxDirectory getParent()
Returns the parent of this file. The parent of the root directory is the root itself (according to the Inferno manual)


getOwner

public java.lang.String getOwner()

getGroup

public java.lang.String getGroup()

getDirEntry

public DirEntry getDirEntry()

getQid

public Qid getQid()

getPermissions

public int getPermissions()
Returns:
the permissions of the file as an integer (e.g. 0755). Does not include the DMDIR, DMAPPEND, DMEXCL, DMAUTH flags (check these with the accessor methods isDirectory(), isAppendOnly(), isExclusive(), isAuth()

setPermissions

public void setPermissions(int permissions)
Sets the permissions of the file

Parameters:
permissions - the permissions of the file as an integer (e.g. 0755).

setReadOnly

public void setReadOnly()
Makes the file read-only (e.g. rwxrwxr-x gets turned to r-xrr-xr-x).


checkSetMode

public void checkSetMode(long newMode)
                  throws StyxException
Checks to see if this file allows the mode (permissions plus flags) of the file to be changed. This is called when the server receives a Twstat message. This default implementation does nothing.

Parameters:
newMode - the new mode of the file (permissions plus any other flags such as DMDIR, DMAPPEND, DMEXCL, DMAUTH)
Throws:
StyxException - if the mode of this file cannot be changed

setMode

public void setMode(long newMode)
Sets the mode of the file (permissions plus other flags). Must check all relevant permissions and call checkSetMode() before calling this method as the system will assume that this method will always succeed.


checkSetLength

public void checkSetLength(ULong newLength)
                    throws StyxException
Check to see if the length of this file can be changed to the given value. If this does not throw an exception then the setLength() method will be assumed to be guaranteed to succeed. Subclasses should make sure that this method throws an exception if this StyxFile is a directory. This default implementation always throws an exception; subclasses should override this method if they wish to allow the length of this file to be changed.

Throws:
StyxException

setLength

public void setLength(ULong newLength)
Sets the length of the file. Should check for all relevant permissions and call checkSetLength() before calling this. The system will assume that this method is guaranteed to succeed (it throws no exceptions and returns no value). This default implementation does nothing; subclasses should override it.


checkSetLastModifiedTime

public void checkSetLastModifiedTime(long lastModifiedTime)
                              throws StyxException
Throws:
StyxException - if the last modified time cannot be changed directly (i.e. with a Twstat message)

setLastModified

public void setLastModified(long lastModifiedTime,
                            User user)
Sets the last modified time of the file. Should check for all relevant permissions and, for a Twstat message, call checkSetLastModifiedTime() before calling this. The system will assume that this method is guaranteed to succeed (it throws no exceptions and returns no value). This method also always sets the last access time to the same value.

Parameters:
lastModifiedTime - time as represented in a stat entry (e.g. in a TwstatMessage), i.e. the number of seconds (not milliseconds) since the epoch (Jan 1 00:00 1970 GMT)
user - The user who is modifying the file

setLastAccessTime

public void setLastAccessTime(long lastAccessTime)

rename

public void rename(java.lang.String newName)
            throws StyxException
Renames this file to the given name. If a file with the given name already exists in the parent directory this method will throw a StyxException. Also throws a StyxException if this is the root directory.

Throws:
StyxException

read

public void read(StyxFileClient client,
                 long offset,
                 int count,
                 int tag)
          throws StyxException
Reads data from this file. This method could be synchronized in subclasses, but watch out for blocks if the read is expected to take some time to complete. Subclasses must make sure they reply to the read request by creating a java.nio.ByteBuffer or byte array of data, then calling the appropriate readReply() (this can be done at any time; it does not have to be done within the read() method). This default implementation simply throws a StyxException, which will result in an Rerror message being sent back to the client. Subclasses should override this to provide the desired behaviour when the file is read.

Parameters:
client - The client that is performing the read
offset - The point in the file at which to start reading
count - The maximum number of bytes to read
tag - The tag of the incoming Tread message (this is needed when calling readReply())
Throws:
StyxException

write

public void write(StyxFileClient client,
                  long offset,
                  int count,
                  org.apache.mina.common.ByteBuffer data,
                  boolean truncate,
                  int tag)
           throws StyxException
Writes data to this file. Must check that the file is open for writing before this. We have already dealt with the possibility that this is an append-only file before calling this method so subclasses do not need to check this. Subclasses must make sure they reply to the write request by calling writeReply() (although this can be done at any time; it does not have to be done within the write() method). After this method is called, ByteBuffer containing the data will be returned to the pool. If subclasses wish to keep the ByteBuffer after this method is complete, they should call data.acquire() to increase the reference count to the buffer. This default implementation simply throws a StyxException, which will result in an Rerror message being sent back to the client. Subclasses should override this to provide the desired behaviour when the file is written to.

Parameters:
client - The client that is performing the write operation
offset - The place in the file where the new data will be added
count - The number of bytes to write
data - The data to write. The position and limit of this ByteBuffer will be set correctly, but subclasses should note that the position might not be zero.
truncate - If this is true the file will be truncated at the end of the new data
tag - The tag of the incoming Twrite message (this is needed when calling writeReply())
Throws:
StyxException

refresh

public void refresh()
Refreshes this file (if it represents another entity, such as a file on disk, this method is used to make sure that the file metadata (length, access time etc) are up to date. This default implementation does nothing; subclasses must override this to provide the correct functionality


remove

public void remove()
            throws StyxException
Removes this file from the Styx server

Throws:
StyxException

delete

protected void delete()
Called when the file is removed from the server. Aborts all outstanding i/o and frees any resources associated with the file. This default implementation does nothing; subclasses should implement appropriate methods if necessary.


addClient

public void addClient(StyxFileClient client)
Adds the given client to the file's list of connected clients. Records the mode with which the client has the file open. Fires the clientConnected() event


clientConnected

protected void clientConnected(StyxFileClient client)
Called after a client connects to this file (i.e. opens it). This default implementation does nothing, but subclasses might want to catch this event and do something, e.g. open file handles when the first client has connected (i.e. when getNumClients() == 0)


getClient

public StyxFileClient getClient(org.apache.mina.protocol.ProtocolSession session,
                                long fid)
Gets the StyxFileClient associated with the given Session and fid, or null if client does not exist


getNumClients

public int getNumClients()
Returns:
The number of clients that have this file open (rememember that several open handles to this file might exist on the same connection. This essentially counts the number of unique client/fid pairs)

removeClient

public void removeClient(StyxFileClient client)
Removes the client that is connected on the given session. Fires the clientDisconnected event. If client is null, this will do nothing


clientDisconnected

protected void clientDisconnected(StyxFileClient client)
Called after a client disconnects from this file (i.e. clunks the fid). This default implementation does nothing, but subclasses might want to catch this event and do something, e.g. close file handles when the last client has disconnected (i.e. when getNumClients() == 0).

Parameters:
client - The client that has just disconnected from the file. This will not be null.

processAndReplyRead

public void processAndReplyRead(java.lang.String fileContents,
                                StyxFileClient client,
                                long offset,
                                int count,
                                int tag)
Method for processing a read request and replying appropriately to the client, based on the contents of the file. This method is used for StyxFiles whose contents can be represented as a String (i.e. fairly short files).

Parameters:
fileContents - String representing the entire contents of the file.
client - the StyxFileClient making the request
offset - the index of the first byte in the file to return to the client
count - the maximum number of bytes to return to the client
tag - the tag of the incoming read message

processAndReplyRead

public void processAndReplyRead(byte[] fileContents,
                                StyxFileClient client,
                                long offset,
                                int count,
                                int tag)
Method for processing a read request and replying appropriately to the client, based on the contents of the file. This method is used for StyxFiles whose contents can be represented as a byte array.

Parameters:
fileContents - Byte array representing the entire contents of the file.
client - the StyxFileClient making the request
offset - the index of the first byte in the file to return to the client
count - the maximum number of bytes to return to the client
tag - the tag of the incoming read message

processAndReplyRead

public void processAndReplyRead(org.apache.mina.common.ByteBuffer fileContents,
                                StyxFileClient client,
                                long offset,
                                int count,
                                int tag)
Method for processing a read request and replying appropriately to the client, based on the contents of the file. This method is used for StyxFiles whose contents can be represented as a ByteBuffer.

Parameters:
fileContents - ByteBuffer representing the entire contents of the file. The position and limit of this buffer will be unchanged by this method. This can be null: in this case all read requests will return zero bytes.
client - the StyxFileClient making the request
offset - the index of the first byte in the file to return to the client
count - the maximum number of bytes to return to the client
tag - the tag of the incoming read message

replyRead

protected void replyRead(StyxFileClient client,
                         byte[] bytes,
                         int tag)
Method to reply to a Read message. One of the replyRead() methods must be called by all subclasses when sending data back to the client in response to a read request.

Parameters:
client - The connection on which the reply will be sent
bytes - The data to include in the message. All the data in this array will be written
tag - The tag to be attached to the message

replyRead

protected void replyRead(StyxFileClient client,
                         java.nio.ByteBuffer buf,
                         int tag)
Method to reply to a Read message. One of the replyRead() methods must be called by all subclasses when sending data back to the client in response to a read request. Leaves the position of the input ByteBuffer unchanged.

Parameters:
client - The connection on which the reply will be sent
buf - a java.nio.ByteBuffer containing the data to write to the file. All the remaining data in the buffer will be sent back to the client.
tag - The tag to be attached to the message

replyRead

protected void replyRead(StyxFileClient client,
                         org.apache.mina.common.ByteBuffer buf,
                         int tag)
Method to reply to a Read message. One of the replyRead() methods must be called by all subclasses when sending data back to the client in response to a read request. Leaves the position of the input ByteBuffer unchanged. The buffer that is provided to this method will be released automatically so users of this method should not release the buffer themselves.

Parameters:
client - The connection on which the reply will be sent
buf - a org.apache.mina.common.ByteBuffer containing the data to write to the file. All the remaining data in the buffer will be sent back to the client.
tag - The tag to be attached to the message

replyRead

protected void replyRead(StyxFileClient client,
                         byte[] bytes,
                         int pos,
                         int count,
                         int tag)
Method to reply to a Read message. One of the replyRead() methods must be called by all subclasses when sending data back to the client in response to a read request.

Parameters:
client - The connection on which the reply will be sent
bytes - The data to include in the message.
pos - The index of the first byte in the array to be written
count - The number of bytes in the array to write
tag - The tag to be attached to the message

replyRead

protected void replyRead(StyxFileClient client,
                         RreadMessage rReadMsg)
Method to reply to a Read message. One of the replyRead() methods must be called by all subclasses when sending data back to the client in response to a read request.

Parameters:
client - The connection on which the reply will be sent
rReadMsg - The RreadMessage to send back to the client. The tag of this message must be set correctly.

replyWrite

protected void replyWrite(StyxFileClient client,
                          int count,
                          int tag)
Method to reply to a Write message. This must be called by all subclasses when sending data back to the client in response to a write request.

Parameters:
client - The connection on which the reply will be sent
count - The number of bytes actually written to the file in question.
tag - The tag to be attached to the message

getVersion

public long getVersion()

contentsChanged

public void contentsChanged()
Call this to indicate that the file's data have changed. This is called automatically when the file is written to with a TwriteMessage. This default implementation simply increments the version number with a call to this.incrementVersion(). Subclasses may override this method, for example to notify waiting clients that the data have changed. This will fire the contentsChanged() event on any registered StyxFileChangeListeners.


incrementVersion

protected final void incrementVersion()
Increments the file's version number and ensures that the version number never exceeds the maximum value of an unsigned 4-byte integer (it wraps back to zero if the version number gets this large)


addChangeListener

public void addChangeListener(StyxFileChangeListener listener)
Registers a StyxFileChangeListener. If it is already registered, this method does nothing.


removeChangeListener

public void removeChangeListener(StyxFileChangeListener listener)
Removes a change listener. If the given change listener is not registered, this method does nothing.


fireContentsChanged

protected void fireContentsChanged()
This method is called when the contents of the file change. This can be due to two things: (1) When a client writes to the file using a TwriteMessage. In this case this method is called just before the Rwrite message is sent to the client. (2) It is also called when this.contentsChanged() is called.



Copyright © 2004-2006 Reading e-Science Centre. All Rights Reserved.