2005-12-08 07:13:07 +00:00

367 lines
9.0 KiB
Java

/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.filesys.server.filesys;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.core.DeviceContext;
import org.alfresco.filesys.server.core.DeviceInterface;
import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException;
import org.alfresco.filesys.server.core.SharedDevice;
/**
* The tree connection class holds the details of a single SMB tree connection. A tree connection is
* a connection to a shared device.
*/
public class TreeConnection
{
// Maximum number of open files allowed per connection.
public static final int MAXFILES = 8192;
// Number of initial file slots to allocate. Number of allocated slots will be doubled
// when required until MAXFILES is reached.
public static final int INITIALFILES = 32;
// Shared device that the connection is associated with
private SharedDevice m_shareDev;
// List of open files on this connection. Count of open file slots used.
private NetworkFile[] m_files;
private int m_fileCount;
// Access permission that the user has been granted
private int m_permission;
/**
* Construct a tree connection using the specified shared device.
*
* @param shrDev SharedDevice
*/
public TreeConnection(SharedDevice shrDev)
{
m_shareDev = shrDev;
m_shareDev.incrementConnectionCount();
}
/**
* Add a network file to the list of open files for this connection.
*
* @param file NetworkFile
* @param sess SrvSession
* @return int
*/
public final int addFile(NetworkFile file, SrvSession sess) throws TooManyFilesException
{
// Check if the file array has been allocated
if (m_files == null)
m_files = new NetworkFile[INITIALFILES];
// Find a free slot for the network file
int idx = 0;
while (idx < m_files.length && m_files[idx] != null)
idx++;
// Check if we found a free slot
if (idx == m_files.length)
{
// The file array needs to be extended, check if we reached the limit.
if (m_files.length >= MAXFILES)
throw new TooManyFilesException();
// Extend the file array
NetworkFile[] newFiles = new NetworkFile[m_files.length * 2];
System.arraycopy(m_files, 0, newFiles, 0, m_files.length);
m_files = newFiles;
}
// Store the network file, update the open file count and return the index
m_files[idx] = file;
m_fileCount++;
return idx;
}
/**
* Close the tree connection, release resources.
*
* @param sess SrvSession
*/
public final void closeConnection(SrvSession sess)
{
// Make sure all files are closed
if (openFileCount() > 0)
{
// Close all open files
for (int idx = 0; idx < m_files.length; idx++)
{
// Check if the file is active
if (m_files[idx] != null)
removeFile(idx, sess);
}
}
// Decrement the active connection count for the shared device
m_shareDev.decrementConnectionCount();
}
/**
* Return the specified network file.
*
* @return NetworkFile
*/
public final NetworkFile findFile(int fid)
{
// Check if the file id and file array are valid
if (m_files == null || fid >= m_files.length)
return null;
// Get the required file details
return m_files[fid];
}
/**
* Return the length of the file table
*
* @return int
*/
public final int getFileTableLength()
{
if (m_files == null)
return 0;
return m_files.length;
}
/**
* Determine if the shared device has an associated context
*
* @return boolean
*/
public final boolean hasContext()
{
if (m_shareDev != null)
return m_shareDev.getContext() != null ? true : false;
return false;
}
/**
* Return the interface specific context object.
*
* @return Device interface context object.
*/
public final DeviceContext getContext()
{
if (m_shareDev == null)
return null;
return m_shareDev.getContext();
}
/**
* Return the share access permissions that the user has been granted.
*
* @return int
*/
public final int getPermission()
{
return m_permission;
}
/**
* Deterimine if the access permission for the shared device allows read access
*
* @return boolean
*/
public final boolean hasReadAccess()
{
if (m_permission == FileAccess.ReadOnly || m_permission == FileAccess.Writeable)
return true;
return false;
}
/**
* Determine if the access permission for the shared device allows write access
*
* @return boolean
*/
public final boolean hasWriteAccess()
{
if (m_permission == FileAccess.Writeable)
return true;
return false;
}
/**
* Return the shared device that this tree connection is using.
*
* @return SharedDevice
*/
public final SharedDevice getSharedDevice()
{
return m_shareDev;
}
/**
* Return the shared device interface
*
* @return DeviceInterface
*/
public final DeviceInterface getInterface()
{
if (m_shareDev == null)
return null;
try
{
return m_shareDev.getInterface();
}
catch (InvalidDeviceInterfaceException ex)
{
}
return null;
}
/**
* Check if the user has been granted the required access permission for this share.
*
* @param perm int
* @return boolean
*/
public final boolean hasPermission(int perm)
{
if (m_permission >= perm)
return true;
return false;
}
/**
* Return the count of open files on this tree connection.
*
* @return int
*/
public final int openFileCount()
{
return m_fileCount;
}
/**
* Remove all files from the tree connection.
*/
public final void removeAllFiles()
{
// Check if the file array has been allocated
if (m_files == null)
return;
// Clear the file list
for (int idx = 0; idx < m_files.length; m_files[idx++] = null)
;
m_fileCount = 0;
}
/**
* Remove a network file from the list of open files for this connection.
*
* @param idx int
* @param sess SrvSession
*/
public final void removeFile(int idx, SrvSession sess)
{
// Range check the file index
if (m_files == null || idx >= m_files.length)
return;
// Make sure the files is closed
if (m_files[idx] != null && m_files[idx].isClosed() == false)
{
// Close the file
try
{
// Access the disk interface and close the file
DiskInterface disk = (DiskInterface) m_shareDev.getInterface();
disk.closeFile(sess, this, m_files[idx]);
m_files[idx].setClosed(true);
}
catch (Exception ex)
{
}
}
// Remove the file and update the open file count.
m_files[idx] = null;
m_fileCount--;
}
/**
* Set the access permission for this share that the user has been granted.
*
* @param perm int
*/
public final void setPermission(int perm)
{
m_permission = perm;
}
/**
* Return the tree connection as a string.
*
* @return java.lang.String
*/
public String toString()
{
StringBuffer str = new StringBuffer();
str.append("[");
str.append(m_shareDev.toString());
str.append(",");
str.append(m_fileCount);
str.append(":");
str.append(FileAccess.asString(m_permission));
str.append("]");
return str.toString();
}
}