Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)

78403: Merged EOL (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud)
      75700: ACE-2149: EOL AVM / WCM
       - Remove most of the AVM and WCM beans, scripts, classes, patches, etc
       - The Explorer client is very broken for compilation
         - TODO: Remove all WCM-related functionality, which I thought would be best left to a UI dev
                 I've murdered many of the classes and beans but there's more to do
       - The repository compiles
         TODO: Get it running again
       - TODO: Check if we can wipe the 'deployment' project as well


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@82540 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Erik Winlof
2014-09-03 12:01:49 +00:00
parent eaff240152
commit 0baa0f74f4
284 changed files with 206 additions and 58844 deletions

View File

@@ -1,667 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.filesys.avm;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.alfresco.IOControlHandler;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileSystem;
import org.alfresco.jlan.server.filesys.NotifyChange;
import org.alfresco.jlan.server.filesys.cache.FileState;
import org.alfresco.jlan.server.filesys.cache.FileStateCache;
import org.alfresco.jlan.util.StringList;
import org.alfresco.repo.avm.CreateStoreCallback;
import org.alfresco.repo.avm.CreateVersionCallback;
import org.alfresco.repo.avm.PurgeStoreCallback;
import org.alfresco.repo.avm.PurgeVersionCallback;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* AVM Filesystem Context Class
*
* <p>Contains per filesystem context.
*
* @author GKSpencer
*/
public class AVMContext extends AlfrescoContext
implements CreateStoreCallback, PurgeStoreCallback, CreateVersionCallback, PurgeVersionCallback {
// Logging
private static final Log logger = LogFactory.getLog(AVMContext.class);
// Constants
//
// Version id that indicates the head version
public static final int VERSION_HEAD = -1;
// Store types to show in the virtualization view
public static final int ShowNormalStores = 0x0001;
public static final int ShowSiteStores = 0x0002;
public static final int ShowStagingStores = 0x0004;
public static final int ShowAuthorStores = 0x0008;
public static final int ShowPreviewStores = 0x0010;
// Store, root path and version
private String m_storePath;
private int m_version = VERSION_HEAD;
// Flag to indicate if the virtualization view is enabled
//
// The first set of folders then map to the stores and the second layer map to the versions with
// paths below.
private boolean m_virtualView;
// Virtualization view filtering options
private int m_showOptions = ShowStagingStores + ShowAuthorStores;
// List of newly created store names that need adding into the virtualization view
private StringList m_newStores;
private Object m_newStoresLock;
// Allow admin user to write to web project staging stores
private boolean m_allowAdminStagingWrites;
// Auto create the store if it doesn't exist?
private boolean m_createStore;
/**
* Default constructor allowing initialization by container.
*/
public AVMContext()
{
}
/**
* Class constructor
*
* <p>Construct a context for a normal view onto a single store/version within AVM.
*
* @param filesysName String
* @param storePath String
* @param version int
*/
public AVMContext( String filesysName, String storePath, int version)
{
setDeviceName(filesysName);
// Set the store root path
setStorePath(storePath);
// Set the store version to use
setVersion(version);
}
/**
* Class constructor
*
* <p>Construct a context for a virtualization view onto all stores/versions within AVM.
*
* @param filesysName String
* @param showOptions int
* @param avmDriver AVMDiskDriver
*/
public AVMContext( String filesysName, int showOptions, AVMDiskDriver avmDriver)
{
setDeviceName(filesysName);
// Enable the virtualization view
setVirtualView(true);
setShowOptions(showOptions);
}
public void setStorePath(String path)
{
this.m_storePath = path;
}
public void setVersion(int version)
{
this.m_version = version;
}
public void setShowOptions(int showOptions)
{
this.m_showOptions = showOptions;
}
public void setStores(String showAttr)
{
if ( showAttr != null)
{
// Split the show options string
StringTokenizer tokens = new StringTokenizer( showAttr, ",");
StringList optList = new StringList();
while ( tokens.hasMoreTokens())
optList.addString( tokens.nextToken().trim().toLowerCase());
// Build the show options mask
this.m_showOptions = 0;
if ( optList.containsString("normal"))
this.m_showOptions += ShowNormalStores;
if ( optList.containsString("site"))
this.m_showOptions += ShowSiteStores;
if ( optList.containsString("author"))
this.m_showOptions += ShowAuthorStores;
if ( optList.containsString("preview"))
this.m_showOptions += ShowPreviewStores;
if ( optList.containsString("staging"))
this.m_showOptions += ShowStagingStores;
}
}
public void setVirtualView(boolean isVirtualView)
{
this.m_virtualView = isVirtualView;
}
public boolean getCreateStore()
{
return m_createStore;
}
public void setCreateStore(boolean createStore)
{
m_createStore = createStore;
}
@Override
public void initialize(AlfrescoDiskDriver filesysDriver)
{
if (m_virtualView)
{
// A context for a view onto all stores/versions within AVM.
m_newStoresLock = new Object();
m_newStores = new StringList();
setShareName("VirtualView");
}
else
{
if (m_storePath == null
|| m_storePath.length() == 0)
throw new AlfrescoRuntimeException("Device missing init value: storePath");
// A context for a normal view onto a single store/version within AVM.
if (m_storePath.endsWith("/"))
m_storePath = m_storePath.substring(0, m_storePath.length() - 1);
// Range check the version id
if (m_version < 0 && m_version != AVMContext.VERSION_HEAD)
throw new AlfrescoRuntimeException("Invalid store version id specified, " + m_version);
setShareName(m_storePath + "(" + m_version + ")");
}
super.initialize(filesysDriver);
}
/**
* Return the filesystem type, either FileSystem.TypeFAT or FileSystem.TypeNTFS.
*
* @return String
*/
public String getFilesystemType()
{
return FileSystem.TypeNTFS;
}
/**
* Return the store path
*
* @return String
*/
public final String getStorePath()
{
return m_storePath;
}
/**
* Return the version
*
* @return int
*/
public final int isVersion()
{
return m_version;
}
/**
* Check if the virtualization view is enabled
*
* @return boolean
*/
public final boolean isVirtualizationView()
{
return m_virtualView;
}
/**
* Check if the admin user is allowed to write to web project staging stores
*
* @return boolean
*/
public final boolean allowAdminStagingWrites() {
return m_allowAdminStagingWrites;
}
/**
* Set the admin web project staging store writeable status
*
* @param writeable boolean
*/
public final void setAllowAdminStagingWrites(boolean writeable) {
m_allowAdminStagingWrites = writeable;
}
/**
* Check if there are any new stores queued for adding to the virtualization view
*
* @return boolean
*/
protected final boolean hasNewStoresQueued() {
if ( m_newStores == null || m_newStores.numberOfStrings() == 0)
return false;
return true;
}
/**
* Return the new stores queue, and reset the current queue
*
* @return StringList
*/
protected StringList getNewStoresQueue() {
StringList storesQueue = null;
synchronized ( m_newStoresLock) {
storesQueue = m_newStores;
m_newStores = new StringList();
}
return storesQueue;
}
/**
* Check if normal stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showNormalStores()
{
return (m_showOptions & ShowNormalStores) != 0 ? true : false;
}
/**
* Check if site data stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showSiteStores()
{
return (m_showOptions & ShowSiteStores) != 0 ? true : false;
}
/**
* Check if author stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showAuthorStores()
{
return (m_showOptions & ShowAuthorStores) != 0 ? true : false;
}
/**
* Check if preview stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showPreviewStores()
{
return (m_showOptions & ShowPreviewStores) != 0 ? true : false;
}
/**
* Check if staging stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showStagingStores()
{
return (m_showOptions & ShowStagingStores) != 0 ? true : false;
}
/**
* Check if the specified store type should be visible
*
* @param storeType int
* @return boolean
*/
public final boolean showStoreType(int storeType)
{
boolean showStore = false;
switch (storeType)
{
case StoreType.Normal:
showStore = showNormalStores();
break;
case StoreType.SiteStore:
showStore = showSiteStores();
break;
case StoreType.WebAuthorMain:
showStore = showAuthorStores();
break;
case StoreType.WebStagingMain:
showStore = showStagingStores();
break;
case StoreType.WebAuthorPreview:
case StoreType.WebStagingPreview:
showStore = showPreviewStores();
break;
}
return showStore;
}
/**
* Close the filesystem context
*/
public void CloseContext() {
// Call the base class
super.CloseContext();
}
/**
* Create the I/O control handler for this filesystem type
*
* @param filesysDriver DiskInterface
* @return IOControlHandler
*/
protected IOControlHandler createIOHandler( DiskInterface filesysDriver)
{
return null;
}
/**
* Create store call back handler
*
* @param storeName String
* @param versionID int
*/
public void storeCreated(String storeName)
{
// Not interested if the virtualization view is not enabled
if ( isVirtualizationView() == false)
return;
// Make sure the file state cache is enabled
FileStateCache fsTable = getStateCache();
if ( fsTable == null)
return;
// Find the file state for the root folder
FileState rootState = fsTable.findFileState( FileName.DOS_SEPERATOR_STR, true);
if ( rootState != null)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Queueing new store " + storeName + " for addition to virtualization view");
// Add the new store name to the list to be picked up by the next file server access
// to the filesystem
synchronized ( m_newStoresLock) {
// Add the new store name
m_newStores.addString( storeName);
}
}
}
/**
* Purge store call back handler
*
* @param storeName String
*/
public void storePurged(String storeName)
{
// Not interested if the virtualization view is not enabled
if ( isVirtualizationView() == false)
return;
// Make sure the file state cache is enabled
FileStateCache fsTable = getStateCache();
if ( fsTable == null)
return;
// Find the file state for the root folder
FileState rootState = fsTable.findFileState( FileName.DOS_SEPERATOR_STR);
if ( rootState != null && rootState.hasPseudoFiles())
{
// Remove the pseudo folder for the store
rootState.getPseudoFileList().removeFile( storeName, false);
// Build the filesystem relative path to the deleted store folder
StringBuilder pathStr = new StringBuilder();
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( storeName);
// Remove the file state for the deleted store
String storePath = pathStr.toString();
fsTable.removeFileState( storePath);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Removed pseudo folder for purged store " + storeName);
// Update the file state modify time
rootState.updateModifyDateTime();
// Send a change notification for the deleted folder
if ( hasChangeHandler())
{
// Send the change notification
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, storePath);
}
}
}
/**
* Create version call back handler
*
* @param storeName String
* @param versionID int
*/
public void versionCreated(String storeName, int versionID)
{
// Not interested if the virtualization view is not enabled
if ( isVirtualizationView() == false)
return;
// Make sure the file state cache is enabled
FileStateCache fsTable = getStateCache();
if ( fsTable == null)
return;
// Build the path to the store version folder
StringBuilder pathStr = new StringBuilder();
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( storeName);
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( AVMPath.VersionsFolder);
// Find the file state for the store versions folder
FileState verState = fsTable.findFileState( pathStr.toString());
if ( verState != null)
{
// Create the version folder name
StringBuilder verStr = new StringBuilder();
verStr.append( AVMPath.VersionFolderPrefix);
verStr.append( versionID);
String verName = verStr.toString();
// Add a pseudo folder for the new version
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( verName);
verState.addPseudoFile( new VersionPseudoFile( verName, pathStr.toString()));
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Added pseudo folder for new version " + storeName + ":/" + verName);
// Send a change notification for the new folder
if ( hasChangeHandler())
{
// Build the filesystem relative path to the new version folder
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( verName);
// Send the change notification
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, pathStr.toString());
}
}
}
/**
* Purge version call back handler
*
* @param storeName String
*/
public void versionPurged(String storeName, int versionID)
{
// Not interested if the virtualization view is not enabled
if ( isVirtualizationView() == false)
return;
// Make sure the file state cache is enabled
FileStateCache fsTable = getStateCache();
if ( fsTable == null)
return;
// Build the path to the store version folder
StringBuilder pathStr = new StringBuilder();
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( storeName);
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( AVMPath.VersionsFolder);
// Find the file state for the store versions folder
FileState verState = fsTable.findFileState( pathStr.toString());
if ( verState != null && verState.hasPseudoFiles())
{
// Create the version folder name
StringBuilder verStr = new StringBuilder();
verStr.append( AVMPath.VersionFolderPrefix);
verStr.append( versionID);
String verName = verStr.toString();
// Remove the pseudo folder for the purged version
verState.getPseudoFileList().removeFile( verName, true);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Removed pseudo folder for purged version " + storeName + ":/" + verName);
// Send a change notification for the deleted folder
if ( hasChangeHandler())
{
// Build the filesystem relative path to the deleted version folder
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( verName);
// Send the change notification
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, pathStr.toString());
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,565 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.DiskFullException;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.smb.SeekType;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.usage.ContentQuotaException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* AVM Network File Class
*
* <p>Holds the details of an open file, and provides access to the file data.
*
* @author GKSpencer
*/
public class AVMNetworkFile extends AlfrescoNetworkFile {
// Logging
private static final Log logger = LogFactory.getLog(AVMNetworkFile.class);
// Node Service
private NodeService m_nodeService;
// AVM service
private AVMService m_avmService;
// AVM path to the file/folder and store version
private String m_avmPath;
private int m_avmVersion;
// Flag to indicate if the file has been modified
private boolean m_modified;
// Access to the file data, flag to indicate if the file channel is writable
private FileChannel m_channel;
private ContentWriter m_content;
private boolean m_writable;
// Mime type, if a writer is opened
private String m_mimeType;
/**
* Class constructor
*
* @param details AVMNodeDescriptor
* @param avmPath String
* @param avmVersion int
* @param nodeService NodeService
* @param avmService AVMService
*/
public AVMNetworkFile( AVMNodeDescriptor details, String avmPath, int avmVersion, NodeService nodeService, AVMService avmService)
{
super( details.getName());
// Save the service, apth and version
m_nodeService = nodeService;
m_avmService = avmService;
m_avmPath = avmPath;
m_avmVersion = avmVersion;
// Copy the file details
setAccessDate( details.getAccessDate());
setCreationDate( details.getCreateDate());
setModifyDate( details.getModDate());
if ( details.isFile())
setFileSize( details.getLength());
else
setFileSize( 0L);
int attr = 0;
if ( details.isDirectory())
attr += FileAttribute.Directory;
if ( avmVersion != AVMContext.VERSION_HEAD)
attr += FileAttribute.ReadOnly;
setAttributes( attr);
}
/**
* Check if there is an open file channel to the content
*
* @return boolean
*/
public final boolean hasContentChannel()
{
return m_channel != null ? true : false;
}
/**
* Return the mime type
*
* @return String
*/
public final String getMimeType()
{
return m_mimeType;
}
/**
* Set the mime type
*
* @param mimeType String
*/
public final void setMimeType(String mimeType)
{
m_mimeType = mimeType;
}
/**
* Open the file
*
* @param createFlag boolean
* @exception IOException
*/
public void openFile(boolean createFlag)
throws IOException
{
// Nothing to do, content is opened on first read/write
}
/**
* Read from the file.
*
* @param buf byte[]
* @param len int
* @param pos int
* @param fileOff long
* @return Length of data read.
* @exception IOException
*/
public int readFile(byte[] buf, int len, int pos, long fileOff)
throws java.io.IOException
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Read file " + getName() + ", len=" + len + ", offset=" + fileOff);
// Open the channel for reading
openContent(false, false);
// Read from the channel
ByteBuffer byteBuffer = ByteBuffer.wrap(buf, pos, len);
int count = m_channel.read(byteBuffer, fileOff);
if (count < 0)
{
// Return a zero count at end of file
count = 0;
}
// Return the length of data read
return count;
}
/**
* Write a block of data to the file.
*
* @param buf byte[]
* @param len int
* @param pos int
* @param fileOff long
* @exception IOException
*/
public void writeFile(byte[] buf, int len, int pos, long fileOff)
throws java.io.IOException
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Write file " + getName() + ", len=" + len + ", offset=" + fileOff);
// Open the channel for writing
openContent(true, false);
// Write to the channel
ByteBuffer byteBuffer = ByteBuffer.wrap(buf, pos, len);
m_channel.write(byteBuffer, fileOff);
// Set modification flag
m_modified = true;
incrementWriteCount();
// Update the current file size
setFileSize( m_channel.size());
}
/**
* Seek to the specified file position.
*
* @param pos long
* @param typ int
* @return int
* @exception IOException
*/
public long seekFile(long pos, int typ)
throws IOException
{
// Open the file, if not already open
openContent( false, false);
// Check if the current file position is the required file position
long curPos = m_channel.position();
switch (typ) {
// From start of file
case SeekType.StartOfFile :
if (curPos != pos)
m_channel.position( pos);
break;
// From current position
case SeekType.CurrentPos :
m_channel.position( curPos + pos);
break;
// From end of file
case SeekType.EndOfFile :
{
long newPos = m_channel.size() + pos;
m_channel.position(newPos);
}
break;
}
// Return the new file position
return m_channel.position();
}
/**
* Flush any buffered output to the file
*
* @throws IOException
*/
public void flushFile()
throws IOException
{
// If the file channel is open for write then flush the channel
if ( m_channel != null && m_writable)
m_channel.force( false);
}
/**
* Truncate the file to the specified file size
*
* @param siz long
* @exception IOException
*/
public void truncateFile(long siz)
throws IOException
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Truncate file " + getName() + ", size=" + siz);
// If the content data channel has not been opened yet and the requested size is zero
// then this is an open for overwrite so the existing content data is not copied
if ( m_channel == null && siz == 0L)
{
// Open content for overwrite, no need to copy existing content data
openContent(true, true);
}
else
{
// Normal open for write
openContent(true, false);
// Truncate or extend the channel
m_channel.truncate(siz);
}
// Set modification flag
m_modified = true;
incrementWriteCount();
}
/**
* Close the database file
*/
public void closeFile()
throws IOException
{
// If the file is a directory or the file channel has not been opened then there is nothing to do
if ( isDirectory() || m_channel == null && m_content == null)
return;
// We may be in a retry block, in which case this section will already have executed and channel will be null
if (m_channel != null)
{
// Close the file channel
try
{
m_channel.close();
m_channel = null;
}
catch ( IOException ex)
{
if (RetryingTransactionHelper.extractRetryCause(ex) != null)
{
throw ex;
}
logger.error("Failed to close file channel for " + getName(), ex);
}
}
if (m_content != null)
{
// Retrieve the content data and stop the content URL from being 'eagerly deleted', in case we need to
// retry the transaction
final ContentData contentData = m_content.getContentData();
try
{
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, m_avmPath);
m_nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, contentData);
}
catch (ContentQuotaException qe)
{
throw new DiskFullException(qe.getMessage());
}
// Tidy up after ourselves after a successful commit. Otherwise leave things to allow a
AlfrescoTransactionSupport.bindListener(new TransactionListenerAdapter()
{
@Override
public void afterCommit()
{
m_content = null;
}
});
}
}
/**
* Open a file channel to the file content, switching to a writable file channel if required.
*
* @param write boolean
* @param trunc boolean
* @throws AccessDeniedException If this network file is read only
* @throws AlfrescoRuntimeException If this network file represents a directory
*/
private void openContent(boolean write, boolean trunc)
throws AccessDeniedException, AlfrescoRuntimeException
{
// Check if this network file is a directory, no content to open
if ( isDirectory())
throw new AlfrescoRuntimeException("Unable to open channel for a directory network file: " + this);
// Check if write access is required and the current channel is read-only
long curPos = 0L;
if ( write && m_writable == false && m_channel != null)
{
// Close the existing read-only channel
try
{
// Save the current file position
curPos = m_channel.position();
// Close the read-only file channel
m_channel.close();
m_channel = null;
}
catch (IOException ex)
{
logger.error("Error closing read-only channel", ex);
}
// Debug
if ( logger.isDebugEnabled())
logger.debug("Switching to writable channel for " + getName());
}
else if ( m_channel != null)
{
// File channel already open
return;
}
// We need to create the channel
if (write && getGrantedAccess() <= NetworkFile.READONLY)
throw new AccessDeniedException("The network file was created for read-only: " + this);
// Access the content data and get a file channel to the data
if ( write )
{
// Access the content data for write
m_content = null;
try {
// Create a writer to access the file data
m_content = m_avmService.getContentWriter(m_avmPath, false);
// Set the mime-type
m_content.setMimetype( getMimeType());
}
catch (Exception ex) {
logger.debug( ex);
ex.printStackTrace();
// Rethrow exception, convert to access denied
throw new AccessDeniedException("Failed to open file for write access, " + m_avmPath);
}
// Indicate that we have a writable channel to the file
m_writable = true;
// Get the writable channel, do not copy existing content data if the file is to be truncated
m_channel = m_content.getFileChannel( trunc);
// Reset the file position to match the read-only file channel position, unless we truncated the file
if ( curPos != 0L && trunc == false)
{
try
{
m_channel.position( curPos);
}
catch (IOException ex)
{
logger.error("Failed to set file position for " + getName(), ex);
}
}
}
else
{
// Access the content data for read
ContentReader cReader = m_avmService.getContentReader( m_avmVersion, m_avmPath);
// Indicate that we only have a read-only channel to the data
m_writable = false;
// Get the read-only channel
m_channel = cReader.getFileChannel();
}
}
/**
* Return the writable state of the content channel
*
* @return boolean
*/
public final boolean isWritable()
{
return m_writable;
}
/**
* Return the network file details as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
str.append( "[");
str.append( getName());
str.append( ":");
str.append( isDirectory() ? "Dir," : "File,");
str.append( getFileSize());
str.append( "-Channel=");
str.append( m_channel);
str.append( m_writable ? ",Write" : ",Read");
str.append( m_modified ? ",Modified" : "");
str.append( "]");
return str.toString();
}
}

View File

@@ -1,727 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileName;
/**
* AVM Path Class
*
* <p>Parses a share relative path into store, version and remaining path values.
*
* @author gkspencer
*/
public class AVMPath {
// Constants
//
// Invalid version id value
private static final int InvalidVersionId = -2;
// Version id string for the head version
public static final String VersionNameHead = "HEAD";
// Folder name for the versions folder
public static final String VersionsFolder = "VERSION";
// Head and version sub-folders
public static final String DataFolder = "DATA";
public static final String MetaDataFolder = "METADATA";
// Version folder prefix
public static final String VersionFolderPrefix = "v";
// AVM path seperator
public static final char AVM_SEPERATOR = '/';
public static final String AVM_SEPERATOR_STR = "/";
// Level identifiers
public enum LevelId { Invalid, Root, StoreRoot, Head, HeadData, HeadMetaData, VersionRoot, Version, VersionData, VersionMetaData, StoreRootPath, StorePath };
// Level identifier for this path
private LevelId m_levelId = LevelId.Invalid;
// Store name
private String m_storeName;
// Version id
private int m_version = InvalidVersionId;
// Remaining path
private String m_path;
// AVM style path
private String m_avmPath;
// Path is read-only access
private boolean m_readOnly;
/**
* Default constructor
*/
public AVMPath()
{
}
/**
* Class constructor
*
* <p>Construct an AVM path for the virtualization view, with store and version folders
*
* @param shrPath String
*/
public AVMPath(String shrPath)
{
// Parse the path
parsePath( shrPath);
}
/**
* Class constructor
*
* <p>Construct an AVM path for a standard view onto a store/version
*
* @param storeName String
* @param version int
* @param path String
*/
public AVMPath(String storeName, int version, String path)
{
// Parse the path
parsePath( storeName, version, path);
}
/**
* Return the level id for the path
*
* @return LevelId
*/
public LevelId isLevel()
{
return m_levelId;
}
/**
* Check if the path is read-only
*
* @return boolean
*/
public final boolean isReadOnlyAccess() {
return m_readOnly;
}
/**
* Return the store name
*
* @return String
*/
public final String getStoreName()
{
return m_storeName;
}
/**
* Check if the version id was specified in the path
*
* @return boolean
*/
public final boolean hasVersion()
{
return m_version != InvalidVersionId ? true : false;
}
/**
* Return the version id
*
* @return int
*/
public final int getVersion()
{
return m_version;
}
/**
* Return the version as a string
*
* @return String
*/
public final String getVersionString()
{
if ( m_version == -1)
return VersionNameHead;
return "" + m_version;
}
/**
* Check if there is a share relative path
*
* @return boolean
*/
public final boolean hasRelativePath()
{
return m_path != null ? true : false;
}
/**
* Return the share relative path
*
* @return String
*/
public final String getRelativePath()
{
return m_path;
}
/**
* Return the AVM style path, in <store>:/<path> format
*
* @return String
*/
public final String getAVMPath()
{
return m_avmPath;
}
/**
* Check if the path is valid
*
* @return boolean
*/
public final boolean isValid()
{
return m_levelId == LevelId.Invalid ? false : true;
}
/**
* Check if the path is to a pseudo folder in the virtualization view
*
* @return boolean
*/
public final boolean isPseudoPath()
{
return m_levelId == LevelId.Invalid || m_levelId == LevelId.StorePath || m_levelId == LevelId.StoreRootPath ? false : true;
}
/**
* Check if hte path is a read-only part of the pseudo folder tree
*
* @return boolean
*/
public final boolean isReadOnlyPseudoPath()
{
if ( isLevel() == LevelId.Root || isLevel() == LevelId.StoreRoot || isLevel() == LevelId.VersionRoot ||
isLevel() == LevelId.Head || isLevel() == LevelId.Version)
return true;
return false;
}
/**
* Check if the path is the root path
*
* @return boolean
*/
public final boolean isRootPath()
{
return m_levelId == LevelId.Root ? true : false;
}
/**
* Parse the path, for the virtualization view onto all stores/versions
*
* @param path String
*/
public final void parsePath( String path)
{
// Clear current settings
m_storeName = null;
m_version = InvalidVersionId;
m_path = null;
m_avmPath = null;
// Split the path
String[] paths = FileName.splitAllPaths(path);
if ( paths == null || paths.length == 0)
{
m_path = FileName.DOS_SEPERATOR_STR;
m_levelId = LevelId.Root;
return;
}
// Set the store name
m_storeName = paths[0];
m_levelId = LevelId.StoreRoot;
if ( paths.length > 1)
{
// Validate the next element, should be either the HEAD or VERSIONS folder
String levelStr = paths[1];
if ( levelStr.equalsIgnoreCase( VersionNameHead))
{
m_version = -1;
m_levelId = LevelId.Head;
}
else if ( levelStr.equalsIgnoreCase( VersionsFolder))
{
m_levelId = LevelId.VersionRoot;
}
else
{
// Invalid folder at the current level
m_levelId = LevelId.Invalid;
return;
}
// Check the next level, if available
if ( paths.length > 2)
{
// If the previous level is the versions root then the next level should be a
// version id folder
String folderName = paths[2];
int pathIdx = 3;
if ( isLevel() == LevelId.VersionRoot)
{
// Check that the folder name starts with the version folder prefix
if ( folderName != null && folderName.startsWith( VersionFolderPrefix) &&
folderName.length() > VersionFolderPrefix.length())
{
try
{
// Parse the version id
m_version = Integer.parseInt( folderName.substring( VersionFolderPrefix.length()));
m_levelId = LevelId.Version;
// Validate the version id
if ( m_version < -1)
{
// Invalid version id
m_levelId = LevelId.Invalid;
return;
}
}
catch ( NumberFormatException ex)
{
m_levelId = LevelId.Invalid;
return;
}
// Check for the next level
if ( paths.length > 3)
{
// Get the next level name
folderName = paths[3];
pathIdx++;
// Check for the data folder
if ( folderName.equalsIgnoreCase( DataFolder))
{
m_levelId = LevelId.VersionData;
// Set the path to the root of the store
m_path = FileName.DOS_SEPERATOR_STR;
}
else if ( folderName.equalsIgnoreCase( MetaDataFolder))
{
m_levelId = LevelId.VersionMetaData;
// Set the path to the root of the metadata
m_path = FileName.DOS_SEPERATOR_STR;
}
else
{
m_levelId = LevelId.Invalid;
return;
}
}
}
else
{
m_levelId = LevelId.Invalid;
return;
}
}
// If the previous level is head the next level should be the data or metadata folder
else if ( isLevel() == LevelId.Head)
{
// Check for the data folder
if ( folderName.equalsIgnoreCase( DataFolder))
{
m_levelId = LevelId.HeadData;
// Set the path to the root of the store
m_path = FileName.DOS_SEPERATOR_STR;
}
else if ( folderName.equalsIgnoreCase( MetaDataFolder))
{
m_levelId = LevelId.HeadMetaData;
// Set the path to the root of the metadata
m_path = FileName.DOS_SEPERATOR_STR;
}
else
{
m_levelId = LevelId.Invalid;
return;
}
}
// If there are remaining paths then build a relative path
if ( paths.length > pathIdx)
{
StringBuilder pathStr = new StringBuilder();
for ( int i = pathIdx; i < paths.length; i++)
{
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( paths[i]);
}
m_path = pathStr.toString();
// ALF-1719: make "www" and "avm_webapps" read only by setting their level to
// StoreRootPath (which is checked in AVMDiskDriver.checkPathAccess).
String lastPath = paths[paths.length-1].toLowerCase();
if(lastPath.equals("www") || lastPath.equals("avm_webapps"))
{
// Set the level to indicate a store root path i.e. "www",
// "avm_webapps"
m_levelId = LevelId.StoreRootPath;
}
else
{
// Set the level to indicate a store relative path
m_levelId = LevelId.StorePath;
}
}
// Build the AVM path, in <store>:/<path> format
if ( m_path != null)
{
StringBuilder pathStr = new StringBuilder();
pathStr.append( m_storeName);
pathStr.append( ":");
pathStr.append( m_path.replace( FileName.DOS_SEPERATOR, AVM_SEPERATOR));
m_avmPath = pathStr.toString();
}
}
}
}
/**
* Parse the path, to generate a path for a single store/version
*
* @param storeName String
* @param version int
* @param path String
*/
public final void parsePath( String storeName, int version, String path)
{
// Clear current settings
m_levelId = LevelId.Invalid;
m_storeName = null;
m_version = InvalidVersionId;
m_path = null;
m_avmPath = null;
// Set the store/version
m_storeName = storeName;
m_version = version;
// Save the relative path
m_path = path;
// Build the store path
StringBuilder avmPath = new StringBuilder();
avmPath.append( m_storeName);
if ( storeName.indexOf( ":") == -1)
avmPath.append( ":");
if ( path == null || path.length() == 0)
{
avmPath.append( AVM_SEPERATOR);
// Set the share relative path as the root path
m_path = FileName.DOS_SEPERATOR_STR;
}
else
{
if ( path.startsWith( FileName.DOS_SEPERATOR_STR) == false)
avmPath.append( AVM_SEPERATOR);
avmPath.append( path.replace( FileName.DOS_SEPERATOR, AVM_SEPERATOR));
}
m_avmPath = avmPath.toString();
// Indicate that the path is to a store relative path
String lowerPath = path.toLowerCase();
String[] paths = FileName.splitAllPaths(lowerPath);
if(paths[paths.length - 1].equals("www") || paths[paths.length - 1].equals("avm_webapps"))
{
// Set the level to indicate a store root path i.e. "www",
// "avm_webapps"
m_levelId = LevelId.StoreRootPath;
}
else
{
m_levelId = LevelId.StorePath;
}
}
/**
* Generate a file id for the path
*
* @return int
*/
public final int generateFileId()
{
// Check if the path is a store path or pseudo path
int fid = -1;
if ( isLevel() == LevelId.StorePath || isLevel() == LevelId.StoreRootPath)
{
// Use the share relative path to generate the file id
fid = getRelativePath().hashCode();
}
else if ( isPseudoPath())
{
// Create a relative path to the pseudo folder
StringBuilder relStr = new StringBuilder();
relStr.append( FileName.DOS_SEPERATOR);
switch( isLevel())
{
case StoreRoot:
relStr.append( getStoreName());
break;
case Head:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionNameHead);
break;
case HeadData:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionNameHead);
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.DataFolder);
break;
case HeadMetaData:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionNameHead);
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.MetaDataFolder);
break;
case VersionRoot:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionsFolder);
break;
case Version:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionsFolder);
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionFolderPrefix);
relStr.append( getVersion());
break;
case VersionData:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionsFolder);
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionFolderPrefix);
relStr.append( getVersion());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.DataFolder);
break;
case VersionMetaData:
relStr.append( getStoreName());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionsFolder);
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.VersionFolderPrefix);
relStr.append( getVersion());
relStr.append( FileName.DOS_SEPERATOR);
relStr.append( AVMPath.MetaDataFolder);
break;
}
// Generate the file id using the pseudo folder relative path
fid = relStr.toString().hashCode();
}
// Return the file id
return fid;
}
/**
* Set the path access, true for read-only access
*
* @param access boolean
*/
public final void setReadOnlyAccess( boolean readOnly)
{
m_readOnly = readOnly;
}
/**
* Return the AVM path details as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
switch ( m_levelId)
{
case Invalid:
str.append("[Invalid");
break;
case Root:
str.append("[Root");
break;
case StoreRoot:
str.append("[StoresRoot");
break;
case Head:
str.append("[");
str.append(getStoreName());
str.append(":HEAD");
break;
case HeadData:
str.append("[");
str.append(getStoreName());
str.append(":HEAD\\");
str.append( DataFolder);
break;
case HeadMetaData:
str.append("[");
str.append(getStoreName());
str.append(":HEAD\\");
str.append( MetaDataFolder);
break;
case VersionRoot:
str.append("[");
str.append(getStoreName());
str.append(":Versions");
break;
case Version:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
break;
case VersionData:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append("\\");
str.append( DataFolder);
break;
case VersionMetaData:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append("\\");
str.append( MetaDataFolder);
break;
case StoreRootPath:
case StorePath:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append(",");
str.append(getRelativePath());
str.append(":");
str.append(getAVMPath());
break;
}
if ( isReadOnlyAccess())
str.append("-ReadOnly");
str.append("]");
return str.toString();
}
}

View File

@@ -1,324 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.util.WildCard;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
/**
* AVM Filesystem Search Context Class
*
* <p>Contains the details of a wildcard folder search.
*
* @author GKSpencer
*/
public class AVMSearchContext extends SearchContext {
// File list and current index
private AVMNodeDescriptor[] m_fileList;
private int m_fileIdx;
// File attributes
private int m_attrib;
// Optional wildcard filter
private WildCard m_filter;
// Relative path to the parent folder being searched
private String m_parentPath;
// Mark all files/folders as read-only
private boolean m_readOnly;
/**
* Class constructor
*
* @param fileList SortedMap<String, AVMNodeDescriptor>
* @param attrib int
* @param filter WildCard
* @param parentPath String
* @param readOnly boolean
*/
public AVMSearchContext( AVMNodeDescriptor[] fileList, int attrib, WildCard filter, String parentPath, boolean readOnly)
{
m_attrib = attrib;
m_filter = filter;
m_fileList = fileList;
m_parentPath = parentPath;
if ( m_parentPath != null && m_parentPath.endsWith( FileName.DOS_SEPERATOR_STR) == false)
m_parentPath = m_parentPath + FileName.DOS_SEPERATOR_STR;
m_readOnly = readOnly;
}
/**
* Determine if there are more files for the active search.
*
* @return boolean
*/
public boolean hasMoreFiles()
{
return m_fileIdx < m_fileList.length ? true : false;
}
/**
* Return file information for the next file in the active search. Returns false if the search
* is complete.
*
* @param info FileInfo to return the file information.
* @return true if the file information is valid, else false
*/
public boolean nextFileInfo(FileInfo info)
{
// Check if there is another file record to return
if ( m_fileIdx >= m_fileList.length)
return false;
// Search for the next valid file
boolean foundMatch = false;
AVMNodeDescriptor curFile = null;
while (foundMatch == false && m_fileIdx < m_fileList.length)
{
// Get the next file from the list
curFile = m_fileList[ m_fileIdx++];
// Check if the file name matches the search pattern
if ( m_filter.matchesPattern(curFile.getName()) == true)
{
// Check if the file matches the search attributes
if (FileAttribute.hasAttribute(m_attrib, FileAttribute.Directory) &&
curFile.isDirectory())
{
// Found a match
foundMatch = true;
}
else if ( curFile.isFile())
{
// Found a match
foundMatch = true;
}
// Check if we found a match
if ( foundMatch == false)
{
// Get the next file from the list
if ( ++m_fileIdx < m_fileList.length)
curFile = m_fileList[ m_fileIdx];
}
}
}
// If we found a match then fill in the file information
if ( foundMatch)
{
// Fill in the file information
info.setFileName( curFile.getName());
if ( curFile.isFile())
{
info.setFileSize( curFile.getLength());
info.setAllocationSize((curFile.getLength() + 512L) & 0xFFFFFFFFFFFFFE00L);
}
else
info.setFileSize( 0L);
info.setAccessDateTime( curFile.getAccessDate());
info.setCreationDateTime( curFile.getCreateDate());
info.setModifyDateTime( curFile.getModDate());
// Build the file attributes
int attr = 0;
if ( curFile.isDirectory())
attr += FileAttribute.Directory;
if ( curFile.getName().startsWith( ".") ||
curFile.getName().equalsIgnoreCase( "Desktop.ini") ||
curFile.getName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden;
if ( isReadOnly())
attr += FileAttribute.ReadOnly;
if ( attr == 0)
attr = FileAttribute.NTNormal;
info.setFileAttributes( attr);
// Generate a file id for the current file
StringBuilder pathStr = new StringBuilder( m_parentPath);
pathStr.append ( curFile.getName());
info.setFileId( pathStr.toString().hashCode());
}
// Indicate if the file information is valid
return foundMatch;
}
/**
* Return the file name of the next file in the active search. Returns null is the search is
* complete.
*
* @return String
*/
public String nextFileName()
{
// Check if there is another file record to return
// Find the next matching file name
while ( m_fileIdx < m_fileList.length) {
// Check if the current file name matches the search pattern
String fname = m_fileList[m_fileIdx++].getName();
if ( m_filter.matchesPattern(fname))
return fname;
}
// No more matching file names
return null;
}
/**
* Return the total number of file entries for this search if known, else return -1
*
* @return int
*/
public int numberOfEntries()
{
return m_fileList.length;
}
/**
* Return the resume id for the current file/directory in the search.
*
* @return int
*/
public int getResumeId()
{
return m_fileIdx;
}
/**
* Restart a search at the specified resume point.
*
* @param resumeId Resume point id.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(int resumeId)
{
// Range check the resume id
int resId = resumeId - 1;
if ( resId < 0 || resId >= m_fileList.length)
return false;
// Reset the current file index
m_fileIdx = resId;
return true;
}
/**
* Restart the current search at the specified file.
*
* @param info File to restart the search at.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(FileInfo info)
{
// Search backwards from the current file
int curFileIdx = m_fileIdx;
if (m_fileIdx >= m_fileList.length)
{
m_fileIdx = m_fileList.length - 1;
}
while ( m_fileIdx > 0) {
// Check if the current file is the required search restart point
if ( m_fileList[ m_fileIdx].getName().equals( info.getFileName()))
return true;
else
m_fileIdx--;
}
// Failed to find the restart file
m_fileIdx = curFileIdx;
return false;
}
/**
* Check if all files/folders returned by the search should be marked as read-only
*
* @return boolean
*/
public final boolean isReadOnly()
{
return m_readOnly;
}
/**
* Set all files/folders returned by the search as read-only
*
* @param readOnly boolean
*/
public final void setReadOnly( boolean readOnly)
{
m_readOnly = readOnly;
}
}

View File

@@ -1,393 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import java.util.Enumeration;
import org.springframework.extensions.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.config.ServerConfigurationBean;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.InvalidDeviceInterfaceException;
import org.alfresco.jlan.server.core.ShareMapper;
import org.alfresco.jlan.server.core.ShareType;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.core.SharedDeviceList;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection;
import org.alfresco.jlan.util.StringList;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMWrongTypeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* AVM Filesystem Share Mapper Class
*
* <p>Provides access to store versions using the share name '<storename>_<version>'.
*
* @author gkspencer
*/
public class AVMShareMapper implements ShareMapper, InitializingBean {
// Logging
private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol");
// Regular expression to test for AVM versioned share name
private static final String AVM_SHAREPATTERN = "[a-zA-Z0-9-]*_[0-9]+";
// Server configuration
private ServerConfiguration m_config;
private FilesystemsConfigSection m_filesysConfig;
// List of available AVM shares
private StringList m_avmShareNames;
// Filesystem driver to be used to create home shares
private AVMDiskDriver m_driver;
// Debug enable flag
private boolean m_debug;
/**
* Default constructor
*/
public AVMShareMapper()
{
}
public void setServerConfiguration(ServerConfiguration config)
{
this.m_config = config;
}
public void setDebug(boolean debug)
{
this.m_debug = debug;
}
/**
* Initialize the share mapper
*
* @param config ServerConfiguration
* @param params ConfigElement
* @exception InvalidConfigurationException
*/
public void initializeMapper(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
{
// Save the server configuration
setServerConfiguration(config);
// Check if debug is enabled
if (params != null && params.getChild("debug") != null)
setDebug(true);
// Complete the initialization
afterPropertiesSet();
}
public void afterPropertiesSet()
{
// Save the server configuration
m_filesysConfig = (FilesystemsConfigSection) m_config.getConfigSection(FilesystemsConfigSection.SectionName);
// Build the list of available AVM share names
m_avmShareNames = new StringList();
SharedDeviceList shrList = m_filesysConfig.getShares();
Enumeration<SharedDevice> shrEnum = shrList.enumerateShares();
while ( shrEnum.hasMoreElements())
{
// Get the current shared device and check if it is an AVM filesystem device
SharedDevice curShare = shrEnum.nextElement();
try
{
if ( curShare.getInterface() instanceof AVMDiskDriver)
{
// Add the shared filesystem name to the list of AVM shares
m_avmShareNames.addString( curShare.getName());
// Set the AVM filesystem driver to be used when creating dynamic shares
if ( m_driver == null)
m_driver = (AVMDiskDriver) curShare.getInterface();
}
}
catch ( InvalidDeviceInterfaceException ex)
{
}
}
}
/**
* Check if debug output is enabled
*
* @return boolean
*/
public final boolean hasDebug()
{
return m_debug;
}
/**
* Return the list of available shares.
*
* @param host String
* @param sess SrvSession
* @param allShares boolean
* @return SharedDeviceList
*/
public SharedDeviceList getShareList(String host, SrvSession sess, boolean allShares)
{
// Make a copy of the global share list and add the per session dynamic shares
SharedDeviceList shrList = new SharedDeviceList(m_filesysConfig.getShares());
if ( sess != null && sess.hasDynamicShares()) {
// Add the per session dynamic shares
shrList.addShares(sess.getDynamicShareList());
}
// Remove unavailable shares from the list and return the list
if ( allShares == false)
shrList.removeUnavailableShares();
return shrList;
}
/**
* Find a share using the name and type for the specified client.
*
* @param host String
* @param name String
* @param typ int
* @param sess SrvSession
* @param create boolean
* @return SharedDevice
* @exception InvalidUserException
*/
public SharedDevice findShare(String tohost, String name, int typ, SrvSession sess, boolean create)
throws Exception
{
// Find the required share by name/type. Use a case sensitive search first, if that fails use a case
// insensitive search.
SharedDevice share = m_filesysConfig.getShares().findShare(name, typ, false);
if ( share == null)
{
// Try a case insensitive search for the required share
share = m_filesysConfig.getShares().findShare(name, typ, true);
}
// If the share was not found then check if the share is in the AVM versioned share format - '<storename>_<version>'
if ( share == null && ( typ == ShareType.DISK || typ == ShareType.UNKNOWN))
{
// Check if the share has already been created for the session
if ( sess.hasDynamicShares())
{
// Check if the required share exists in the sessions dynamic share list
share = sess.getDynamicShareList().findShare(name, typ, false);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug(" Reusing existing dynamic share for " + name);
}
// Check if the share name matches the AVM versioned share name pattern
if ( share == null && create == true && name.matches( AVM_SHAREPATTERN))
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Map dynamic share " + name + ", type=" + ShareType.TypeAsString(typ));
// Split the store name and version id from the share name
int pos = name.indexOf( '_');
String storePath = name.substring(0, pos) + ":/";
int storeVersion = -1;
try
{
String storeVer = name.substring( pos + 1);
storeVersion = Integer.parseInt( storeVer);
if ( storeVersion < 0)
storeVersion = -1;
}
catch ( NumberFormatException ex)
{
logger.error( "Invalid store version id, name=" + name);
}
// Create the disk driver and context
if ( storePath.length() > 0 && storeVersion != -1)
{
// Validate the store name and version
AVMService avmService = m_driver.getAvmService();
m_driver.beginReadTransaction( sess);
try
{
// Validate the store name/version
avmService.lookup( storeVersion, storePath);
// Create a dynamic share mapped to the AVM store/version
AVMContext avmCtx = new AVMContext( name, storePath, storeVersion);
if(m_config instanceof ServerConfigurationBean)
{
ServerConfigurationBean config = (ServerConfigurationBean)m_config;
config.initialiseRuntimeContext("cifs.avm" + name, avmCtx);
// Enable file state caching
// diskCtx.enableStateCache(serverConfigurationBean, true);
}
else
{
throw new AlfrescoRuntimeException("configuration error, unknown configuration bean");
}
// Create a dynamic shared device for the store version
DiskSharedDevice diskShare = new DiskSharedDevice( name, m_driver, avmCtx, SharedDevice.Temporary);
// Add the new share to the sessions dynamic share list
sess.addDynamicShare(diskShare);
share = diskShare;
// DEBUG
if (logger.isDebugEnabled())
logger.debug(" Mapped share " + name + " - " + diskShare);
}
catch ( AVMNotFoundException ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Failed to map share to " + name + ", not such store/version");
}
catch ( AVMWrongTypeException ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Failed to map share to " + name + ", wrong type");
}
}
}
}
// Check if the share is available
if ( share != null && share.getContext() != null && share.getContext().isAvailable() == false)
share = null;
// Return the shared device, or null if no matching device was found
return share;
}
/**
* Delete temporary shares for the specified session
*
* @param sess SrvSession
*/
public void deleteShares(SrvSession sess)
{
// Check if the session has any dynamic shares
if ( sess.hasDynamicShares() == false)
return;
// Delete the dynamic shares
SharedDeviceList shares = sess.getDynamicShareList();
Enumeration<SharedDevice> enm = shares.enumerateShares();
while ( enm.hasMoreElements()) {
// Get the current share from the list
SharedDevice shr = (SharedDevice) enm.nextElement();
// Close the shared device
shr.getContext().CloseContext();
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Deleted dynamic share " + shr);
}
// Clear the dynamic share list
shares.removeAllShares();
}
/**
* Close the share mapper, release any resources.
*/
public void closeMapper()
{
// TODO Auto-generated method stub
}
}

View File

@@ -1,196 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
/**
* AVM Filesystem Single File Search Context Class
*
* <p>Contains the details of a non-wildcard file/folder search, where there is only one result to return.
*
* @author GKSpencer
*/
public class AVMSingleFileSearchContext extends SearchContext {
// Details of the single file/folder
private AVMNodeDescriptor m_fileDetails;
// Flag to indicate file details have been returned
private boolean m_endOfSearch;
// Relative path to the file/folder
private String m_relativePath;
// Mark thel file/folder as read-only
private boolean m_readOnly;
/**
* Class constructor
*
* @param fileDetails AVMNodeDescriptor
* @param relPath String
* @param readOnly boolean
*/
public AVMSingleFileSearchContext( AVMNodeDescriptor fileDetails, String relPath, boolean readOnly)
{
m_fileDetails = fileDetails;
m_relativePath = relPath;
m_readOnly = readOnly;
}
/**
* Determine if there are more files for the active search.
*
* @return boolean
*/
public boolean hasMoreFiles()
{
return m_endOfSearch == false ? true : false;
}
/**
* Return file information for the next file in the active search. Returns false if the search
* is complete.
*
* @param info FileInfo to return the file information.
* @return true if the file information is valid, else false
*/
public boolean nextFileInfo(FileInfo info)
{
// Check if the file details have been returned
if ( m_endOfSearch == true)
return false;
// Fill in the file information details
info.setFileName( m_fileDetails.getName());
if ( m_fileDetails.isFile())
{
info.setFileSize( m_fileDetails.getLength());
info.setAllocationSize((m_fileDetails.getLength() + 512L) & 0xFFFFFFFFFFFFFE00L);
}
else
info.setFileSize( 0L);
info.setAccessDateTime( m_fileDetails.getAccessDate());
info.setCreationDateTime( m_fileDetails.getCreateDate());
info.setModifyDateTime( m_fileDetails.getModDate());
// Build the file attributes
int attr = 0;
if ( m_fileDetails.isDirectory())
attr += FileAttribute.Directory;
if ( m_fileDetails.getName().startsWith( ".") ||
m_fileDetails.getName().equalsIgnoreCase( "Desktop.ini") ||
m_fileDetails.getName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden;
if ( m_readOnly == true)
attr += FileAttribute.ReadOnly;
info.setFileAttributes( attr);
info.setFileId( m_relativePath.hashCode());
// Set the end of search flag, indicate that the file informatin is valid
m_endOfSearch = true;
return true;
}
/**
* Return the file name of the next file in the active search. Returns null is the search is
* complete.
*
* @return String
*/
public String nextFileName()
{
// Check if the file details have been returned
if ( m_endOfSearch == true)
return null;
// Return the file/folder name, set the end of search flag
m_endOfSearch = true;
return m_fileDetails.getName();
}
/**
* Return the total number of file entries for this search if known, else return -1
*
* @return int
*/
public int numberOfEntries()
{
return 1;
}
/**
* Return the resume id for the current file/directory in the search.
*
* @return int
*/
public int getResumeId()
{
return 1;
}
/**
* Restart a search at the specified resume point.
*
* @param resumeId Resume point id.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(int resumeId)
{
// Validate the resume id and clear the end of search flag
if ( resumeId == 1)
m_endOfSearch = false;
else
return false;
return true;
}
/**
* Restart the current search at the specified file.
*
* @param info File to restart the search at.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(FileInfo info)
{
return true;
}
}

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
/**
* Dummy Folder Pseudo File Class
*
* <p>Represents a dummy folder within the virtualization filesystem view.
*
* @author gkspencer
*/
public class DummyFolderPseudoFile extends PseudoFile {
/**
* Class constructor
*
* @param fname String
* @param relPath String
*/
public DummyFolderPseudoFile( String fname, String relPath)
{
super( fname, FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the folder details
FileInfo fInfo = new FileInfo( fname, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( System.currentTimeMillis());
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
setFileInfo( fInfo);
}
/**
* Return a network file for reading/writing the pseudo file
*
* @param netPath String
* @return NetworkFile
*/
@Override
public NetworkFile getFile(String netPath) {
// Split the path to get the name
String[] paths = FileName.splitPath( netPath);
// Create a network file for the folder
return new PseudoFolderNetworkFile( paths[1], netPath);
}
/**
* Return the file information for the pseudo file
*
* @return FileInfo
*/
@Override
public FileInfo getFileInfo() {
return getInfo();
}
}

View File

@@ -1,296 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.jlan.util.WildCard;
/**
* Pseudo File List Search Context Class
*
* <p>Returns files from a pseudo file list for a wildcard search.
*
* @author gkspencer
*/
public class PseudoFileListSearchContext extends SearchContext {
// Pseudo file list and current index
private PseudoFileList m_fileList;
private int m_fileIdx;
// File attributes
private int m_attrib;
// Optional wildcard filter
private WildCard m_filter;
// Mark all files/folders as read-only
private boolean m_readOnly;
/**
* Class constructor
*
* @param fileList PseudoFileList
* @param attrib int
* @param filter WildCard
* @param readOnly boolean
*/
public PseudoFileListSearchContext( PseudoFileList fileList, int attrib, WildCard filter, boolean readOnly)
{
m_attrib = attrib;
m_filter = filter;
m_fileList = fileList;
m_readOnly = readOnly;
}
/**
* Determine if there are more files for the active search.
*
* @return boolean
*/
public boolean hasMoreFiles()
{
return m_fileIdx < m_fileList.numberOfFiles() ? true : false;
}
/**
* Return file information for the next file in the active search. Returns false if the search
* is complete.
*
* @param info FileInfo to return the file information.
* @return true if the file information is valid, else false
*/
public boolean nextFileInfo(FileInfo info)
{
// Check if there is another file record to return
if ( m_fileIdx >= m_fileList.numberOfFiles())
return false;
// Search for the next valid file
boolean foundMatch = false;
PseudoFile curFile = null;
while (foundMatch == false && m_fileIdx < m_fileList.numberOfFiles())
{
// Get the next file from the list
curFile = m_fileList.getFileAt( m_fileIdx++);
// Check if the file name matches the search pattern
if ( m_filter != null)
{
// Check if the current file matches the wildcard pattern
if ( m_filter.matchesPattern(curFile.getFileName()) == true)
{
// Check if the file matches the search attributes
if (FileAttribute.hasAttribute(m_attrib, FileAttribute.Directory) &&
curFile.isDirectory())
{
// Found a match
foundMatch = true;
}
else if ( curFile.isFile())
{
// Found a match
foundMatch = true;
}
// Check if we found a match
if ( foundMatch == false)
{
// Get the next file from the list
if ( ++m_fileIdx < m_fileList.numberOfFiles())
curFile = m_fileList.getFileAt( m_fileIdx);
}
}
}
else
foundMatch = true;
}
// If we found a match then fill in the file information
if ( foundMatch)
{
// Fill in the file information
info.setFileName( curFile.getFileName());
// Get the file information from the pseudo file
FileInfo pfInfo = curFile.getFileInfo();
if ( curFile.isFile())
{
info.setFileSize( pfInfo.getSize());
info.setAllocationSize( pfInfo.getAllocationSize());
}
else
info.setFileSize( 0L);
info.setAccessDateTime( pfInfo.getAccessDateTime());
info.setCreationDateTime( pfInfo.getCreationDateTime());
info.setModifyDateTime( pfInfo.getModifyDateTime());
// Build the file attributes
int attr = pfInfo.getFileAttributes();
if ( pfInfo.isHidden() == false &&
curFile.getFileName().startsWith( ".") ||
curFile.getFileName().equalsIgnoreCase( "Desktop.ini") ||
curFile.getFileName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden;
// Check if the file/folder should be marked as read-only
if ( m_readOnly && pfInfo.isReadOnly() == false)
attr += FileAttribute.ReadOnly;
info.setFileAttributes( attr);
info.setFileId( pfInfo.getFileId());
}
// Indicate if the file information is valid
return foundMatch;
}
/**
* Return the file name of the next file in the active search. Returns null is the search is
* complete.
*
* @return String
*/
public String nextFileName()
{
// Check if there is another file record to return
// Find the next matching file name
while ( m_fileIdx < m_fileList.numberOfFiles()) {
// Check if the current file name matches the search pattern
String fname = m_fileList.getFileAt( m_fileIdx++).getFileName();
if ( m_filter.matchesPattern(fname))
return fname;
}
// No more matching file names
return null;
}
/**
* Return the total number of file entries for this search if known, else return -1
*
* @return int
*/
public int numberOfEntries()
{
return m_fileList.numberOfFiles();
}
/**
* Return the resume id for the current file/directory in the search.
*
* @return int
*/
public int getResumeId()
{
return m_fileIdx;
}
/**
* Restart a search at the specified resume point.
*
* @param resumeId Resume point id.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(int resumeId)
{
// Range check the resume id
int resId = resumeId - 1;
if ( resId < 0 || resId >= m_fileList.numberOfFiles())
return false;
// Reset the current file index
m_fileIdx = resId;
return true;
}
/**
* Restart the current search at the specified file.
*
* @param info File to restart the search at.
* @return true if the search can be restarted, else false.
*/
public boolean restartAt(FileInfo info)
{
// Search backwards from the current file
int curFileIdx = m_fileIdx;
if (m_fileIdx >= m_fileList.numberOfFiles())
{
m_fileIdx = m_fileList.numberOfFiles() - 1;
}
while ( m_fileIdx > 0) {
// Check if the current file is the required search restart point
if ( m_fileList.getFileAt( m_fileIdx).getFileName().equals( info.getFileName()))
return true;
else
m_fileIdx--;
}
// Failed to find the restart file
m_fileIdx = curFileIdx;
return false;
}
}

View File

@@ -1,211 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
/**
* Store Pseudo File Class
*
* <p>Represents an AVM store as a folder.
*
* @author gkspencer
*/
public class StorePseudoFile extends PseudoFile {
// Store type
private int m_storeType = StoreType.Normal;
// Web project this sandbox links to, or null if this store is not linked
private String m_webProject;
// User name if this is an author sandbox for a web project
private String m_userName;
/**
* Class constructor
*
* @param storeDesc AVMStoreDescriptor
* @param relPath String
* @param storeType int
*/
public StorePseudoFile( AVMStoreDescriptor storeDesc, String relPath, int storeType)
{
super( storeDesc.getName(), FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeDesc.getName(), 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( storeDesc.getCreateDate());
fInfo.setModifyDateTime( storeDesc.getCreateDate());
fInfo.setAccessDateTime( storeDesc.getCreateDate());
fInfo.setChangeDateTime( storeDesc.getCreateDate());
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
setStoreType( storeType);
}
/**
* Class constructor
*
* @param storeName String
* @param relPath String
*/
public StorePseudoFile( String storeName, String relPath)
{
super( storeName, FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeName, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
}
/**
* Return a network file for reading/writing the pseudo file
*
* @param netPath String
* @return NetworkFile
*/
@Override
public NetworkFile getFile(String netPath) {
// Split the path to get the name
String[] paths = FileName.splitPath( netPath);
// Create a network file for the folder
return new PseudoFolderNetworkFile( paths[1], netPath);
}
/**
* Return the file information for the pseudo file
*
* @return FileInfo
*/
@Override
public FileInfo getFileInfo() {
return getInfo();
}
/**
* Return the store type
*
* @return int
*/
public final int isStoreType()
{
return m_storeType;
}
/**
* Check if this store is linked to a web project
*
* @return boolean
*/
public final boolean hasWebProject()
{
return m_webProject != null ? true : false;
}
/**
* Get the web project that this store links to, or null if not linked
*
* @return String
*/
public final String getWebProject()
{
return m_webProject;
}
/**
* Set the web project that this store is linked to
*
* @param webProject String
*/
public final void setWebProject(String webProject)
{
m_webProject = webProject;
}
/**
* Check if this store is an author sandbox
*
* @return boolean
*/
public final boolean hasUserName()
{
return m_userName != null ? true : false;
}
/**
* Get the owner of this sandbox
*
* @return String
*/
public final String getUserName()
{
return m_userName;
}
/**
* Set the owner of this sandbox
*
* @param userName String
*/
public final void setUserName(String userName)
{
m_userName = userName;
}
/**
* Set the store type
*
* @param storeType int
*/
public final void setStoreType(int storeType)
{
m_storeType = storeType;
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.filesys.avm;
/**
* Store Types Class
*
* @author gkspencer
*/
public class StoreType {
// Store types
public static final int Normal = 0;
// Site data store types
public static final int SiteStore = 1;
// Web project store types
public static final int WebAuthorMain = 2;
public static final int WebAuthorPreview = 3;
public static final int WebStagingPreview = 4;
public static final int WebStagingMain = 5;
// Store type strings
private static final String[] _types = { "Normal", "SiteStore", "AuthorMain", "AuthorPreview", "StagingPreview", "StagingMain" };
/**
* Return a store type as a string
*
* @param typ int
* @return String
*/
public final static String asString( int typ)
{
if ( typ < 0 || typ > _types.length)
return "Invalid";
return _types[ typ];
}
}

View File

@@ -1,119 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
import org.alfresco.service.cmr.avm.VersionDescriptor;
/**
* Version Pseudo File Class
*
* <p>Represents an AVM store version as a folder.
*
* @author gkspencer
*/
public class VersionPseudoFile extends PseudoFile {
/**
* Class constructor
*
* @param name String
* @param relPath String
*/
public VersionPseudoFile( String name, String relPath)
{
super( name, FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( name, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
setFileInfo( fInfo);
}
/**
* Class constructor
*
* @param name String
* @param verDesc VersionDescriptor
* @param relPath String
*/
public VersionPseudoFile( String name, VersionDescriptor verDesc, String relPath)
{
super( name, FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( name, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( verDesc.getCreateDate());
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
setFileInfo( fInfo);
}
/**
* Return a network file for reading/writing the pseudo file
*
* @param netPath String
* @return NetworkFile
*/
@Override
public NetworkFile getFile(String netPath) {
// Split the path to get the name
String[] paths = FileName.splitPath( netPath);
// Create a network file for the folder
return new PseudoFolderNetworkFile( paths[1], netPath);
}
/**
* Return the file information for the pseudo file
*
* @return FileInfo
*/
@Override
public FileInfo getFileInfo() {
return getInfo();
}
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. */
package org.alfresco.filesys.avm;
import java.util.Hashtable;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Web Project Store Pseudo File Class
*
* <p>Represents an AVM store as a folder.
*
* @author gkspencer
*/
public class WebProjectStorePseudoFile extends StorePseudoFile {
// Store/web project user access roles
public static final int RoleNone = 0;
public static final int RolePublisher = 1;
public static final int RoleContentManager = 2;
// Node ref for this store
private NodeRef m_noderef;
// List of users that are content managers/publishers for this web project store
private Hashtable<String, Integer> m_users;
/**
* Class constructor
*
* @param storeDesc AVMStoreDescriptor
* @param relPath String
* @param nodeRef NodeRef
*/
public WebProjectStorePseudoFile( AVMStoreDescriptor storeDesc, String relPath, NodeRef nodeRef)
{
super( storeDesc, relPath, StoreType.WebStagingMain);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeDesc.getName(), 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( storeDesc.getCreateDate());
fInfo.setModifyDateTime( storeDesc.getCreateDate());
fInfo.setAccessDateTime( storeDesc.getCreateDate());
fInfo.setChangeDateTime( storeDesc.getCreateDate());
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
// Set the associated node ref for the web project
m_noderef = nodeRef;
}
/**
* Class constructor
*
* @param storeName String
* @param relPath String
* @param nodeRef NodeRef
*/
public WebProjectStorePseudoFile( String storeName, String relPath, NodeRef nodeRef)
{
super( storeName, relPath);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeName, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
// Set the associated node ref for the web project
m_noderef = nodeRef;
}
/**
* Check if the associated node ref is valid
*
* @return boolean
*/
public final boolean hasNodeRef()
{
return m_noderef != null ? true : false;
}
/**
* Get the associated node ref for the store
*
* @return NodeRef
*/
public final NodeRef getNodeRef()
{
return m_noderef;
}
/**
* Set the associated node ref for the store
*
* @param node NodeRef
*/
public final void setNodeRef(NodeRef node)
{
m_noderef = node;
}
/**
* Return the role for the specified user within this web project
*
* @param userName String
* @return int
*/
public final int getUserRole(String userName)
{
if ( m_users == null)
return RoleNone;
Integer role = m_users.get( userName);
return role != null ? role.intValue() : RoleNone;
}
/**
* Add a user role for this web project
*
* @param userName String
* @param role int
*/
public final void addUserRole(String userName, int role)
{
if ( m_users == null)
m_users = new Hashtable<String, Integer>();
m_users.put(userName, Integer.valueOf(role));
}
/**
* Remove a user role for this project
*
* @param userName String
*/
public final void removeUserRole(String userName)
{
if ( m_users != null)
m_users.remove(userName);
}
}

View File

@@ -1,5 +0,0 @@
/**
*/
@PackageMarker
package org.alfresco.filesys.avm;
import org.alfresco.util.PackageMarker;

View File

@@ -40,8 +40,6 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.AbstractServerConfigurationBean;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.ExtendedDiskInterface;
import org.alfresco.filesys.avm.AVMContext;
import org.alfresco.filesys.avm.AVMDiskDriver;
import org.alfresco.filesys.config.acl.AccessControlListBean;
import org.alfresco.filesys.repo.BufferedContentDiskDriver;
import org.alfresco.filesys.repo.ContentContext;
@@ -107,7 +105,6 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
private FTPConfigBean ftpConfigBean;
private NFSConfigBean nfsConfigBean;
private List<DeviceContext> filesystemContexts;
private boolean avmAllStores;
private SecurityConfigBean securityConfigBean;
private CoreServerConfigBean coreServerConfigBean;
@@ -153,11 +150,6 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
this.filesystemContexts = filesystemContexts;
}
public void setAvmAllStores(boolean avmAllStores)
{
this.avmAllStores = avmAllStores;
}
public void setSecurityConfigBean(SecurityConfigBean securityConfigBean)
{
this.securityConfigBean = securityConfigBean;
@@ -1742,133 +1734,86 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
DiskSharedDevice filesys = null;
if (filesystem instanceof AVMContext)
// Create a new filesystem driver instance and register a context for
// the new filesystem
ExtendedDiskInterface filesysDriver = getRepoDiskInterface();
ContentContext filesysContext = (ContentContext) filesystem;
if(clusterConfigBean != null && clusterConfigBean.getClusterEnabled())
{
// Create a new filesystem driver instance and register a context for
// the new filesystem
ExtendedDiskInterface filesysDriver = getAvmDiskInterface();
DiskDeviceContext diskCtx = (DiskDeviceContext) filesystem;
if(clusterConfigBean != null && clusterConfigBean.getClusterEnabled())
if(logger.isDebugEnabled())
{
if(logger.isDebugEnabled())
{
logger.debug("start hazelcast cache : " + clusterConfigBean.getClusterName() + ", shareName: "+ diskCtx.getShareName());
}
GenericConfigElement hazelConfig = createClusterConfig("cifs.avm."+diskCtx.getShareName());
HazelCastClusterFileStateCache hazel = new HazelCastClusterFileStateCache();
hazel.initializeCache(hazelConfig, this);
diskCtx.setStateCache(hazel);
logger.debug("start hazelcast cache : " + clusterConfigBean.getClusterName() + ", shareName: "+ filesysContext.getShareName());
}
else
{
// Check if the filesystem uses the file state cache, if so then add to the file state reaper
StandaloneFileStateCache standaloneCache = new StandaloneFileStateCache();
standaloneCache.initializeCache( new GenericConfigElement( ""), this);
diskCtx.setStateCache(standaloneCache);
}
if ( diskCtx.hasStateCache()) {
// Register the state cache with the reaper thread
fsysConfig.addFileStateCache( filesystem.getDeviceName(), diskCtx.getStateCache());
}
filesysDriver.registerContext(filesystem);
// Create the shared filesystem
filesys = new DiskSharedDevice(filesystem.getDeviceName(), filesysDriver, (AVMContext)filesystem);
filesys.setConfiguration( this);
// Start the filesystem
((AVMContext)filesystem).startFilesystem(filesys);
GenericConfigElement hazelConfig = createClusterConfig("cifs.filesys."+filesysContext.getShareName());
HazelCastClusterFileStateCache hazel = new HazelCastClusterFileStateCache();
hazel.initializeCache(hazelConfig, this);
filesysContext.setStateCache(hazel);
}
else
{
// Create a new filesystem driver instance and register a context for
// the new filesystem
ExtendedDiskInterface filesysDriver = getRepoDiskInterface();
ContentContext filesysContext = (ContentContext) filesystem;
if(clusterConfigBean != null && clusterConfigBean.getClusterEnabled())
{
if(logger.isDebugEnabled())
{
logger.debug("start hazelcast cache : " + clusterConfigBean.getClusterName() + ", shareName: "+ filesysContext.getShareName());
}
GenericConfigElement hazelConfig = createClusterConfig("cifs.filesys."+filesysContext.getShareName());
HazelCastClusterFileStateCache hazel = new HazelCastClusterFileStateCache();
hazel.initializeCache(hazelConfig, this);
filesysContext.setStateCache(hazel);
}
else
{
// Create state cache here and inject
StandaloneFileStateCache standaloneCache = new StandaloneFileStateCache();
standaloneCache.initializeCache( new GenericConfigElement( ""), this);
filesysContext.setStateCache(standaloneCache);
}
if ( filesysContext.hasStateCache()) {
// Register the state cache with the reaper thread
// has many side effects including initialisation of the cache
fsysConfig.addFileStateCache( filesystem.getDeviceName(), filesysContext.getStateCache());
// Create the lock manager for the context.
FileStateLockManager lockMgr = new FileStateLockManager(filesysContext.getStateCache());
filesysContext.setLockManager(lockMgr);
filesysContext.setOpLockManager(lockMgr);
}
if ((!cifsConfigBean.getServerEnabled() && !ftpConfigBean.getServerEnabled())
&& isContentDiskDriver2(filesysDriver))
{
((ContentContext) filesystem).setDisableNodeMonitor(true);
}
filesysDriver.registerContext(filesystem);
// Check if an access control list has been specified
AccessControlList acls = null;
AccessControlListBean accessControls = filesysContext.getAccessControlList();
if (accessControls != null)
{
// Parse the access control list
acls = accessControls.toAccessControlList(secConfig);
}
else if (secConfig.hasGlobalAccessControls())
{
// Use the global access control list for this disk share
acls = secConfig.getGlobalAccessControls();
}
// Create the shared filesystem
filesys = new DiskSharedDevice(filesystem.getDeviceName(), filesysDriver, filesysContext);
filesys.setConfiguration( this);
// Add any access controls to the share
filesys.setAccessControlList(acls);
// Check if change notifications should be enabled
if ( filesysContext.getDisableChangeNotifications() == false)
filesysContext.enableChangeHandler( true);
// Start the filesystem
filesysContext.startFilesystem(filesys);
// Create state cache here and inject
StandaloneFileStateCache standaloneCache = new StandaloneFileStateCache();
standaloneCache.initializeCache( new GenericConfigElement( ""), this);
filesysContext.setStateCache(standaloneCache);
}
if ( filesysContext.hasStateCache()) {
// Register the state cache with the reaper thread
// has many side effects including initialisation of the cache
fsysConfig.addFileStateCache( filesystem.getDeviceName(), filesysContext.getStateCache());
// Create the lock manager for the context.
FileStateLockManager lockMgr = new FileStateLockManager(filesysContext.getStateCache());
filesysContext.setLockManager(lockMgr);
filesysContext.setOpLockManager(lockMgr);
}
if ((!cifsConfigBean.getServerEnabled() && !ftpConfigBean.getServerEnabled())
&& isContentDiskDriver2(filesysDriver))
{
((ContentContext) filesystem).setDisableNodeMonitor(true);
}
filesysDriver.registerContext(filesystem);
// Check if an access control list has been specified
AccessControlList acls = null;
AccessControlListBean accessControls = filesysContext.getAccessControlList();
if (accessControls != null)
{
// Parse the access control list
acls = accessControls.toAccessControlList(secConfig);
}
else if (secConfig.hasGlobalAccessControls())
{
// Use the global access control list for this disk share
acls = secConfig.getGlobalAccessControls();
}
// Create the shared filesystem
filesys = new DiskSharedDevice(filesystem.getDeviceName(), filesysDriver, filesysContext);
filesys.setConfiguration( this);
// Add any access controls to the share
filesys.setAccessControlList(acls);
// Check if change notifications should be enabled
if ( filesysContext.getDisableChangeNotifications() == false)
filesysContext.enableChangeHandler( true);
// Start the filesystem
filesysContext.startFilesystem(filesys);
// Add the new filesystem
@@ -1891,50 +1836,6 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
logger.warn("No filesystems defined");
}
// Check if shares should be added for all AVM stores
if (this.avmAllStores && getAvmDiskInterface() != null)
{
// Get the list of store names
AVMDiskDriver avmDriver = (AVMDiskDriver) getAvmDiskInterface();
StringList storeNames = avmDriver.getAVMStoreNames();
// Add shares for each of the store names, if the share name does not already exist
if (storeNames != null && storeNames.numberOfStrings() > 0)
{
// Add a share for each store
for (int i = 0; i < storeNames.numberOfStrings(); i++)
{
String storeName = storeNames.getStringAt(i);
// Check if a share of the same name already exists
if (fsysConfig.getShares().findShare(storeName, ShareType.DISK, true) == null)
{
// Create the new share for the store
AVMContext avmContext = new AVMContext(storeName, storeName + ":/", AVMContext.VERSION_HEAD);
// avmContext.enableStateCache(this, true);
// Create the shared filesystem
DiskSharedDevice filesys = new DiskSharedDevice(storeName, avmDriver, avmContext);
filesys.setConfiguration( this);
fsysConfig.addShare( filesys);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Added AVM share " + storeName);
}
}
}
}
// home folder share mapper could be declared in security config
}