mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
Some fixes after merge. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4651 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
678 lines
14 KiB
Java
678 lines
14 KiB
Java
/*
|
|
* Copyright (C) 2006 Alfresco, Inc.
|
|
*
|
|
* Licensed under the Mozilla Public License version 1.1
|
|
* with a permitted attribution clause. You may obtain a
|
|
* copy of the License at
|
|
*
|
|
* http://www.alfresco.org/legal/license.txt
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
* either express or implied. See the License for the specific
|
|
* language governing permissions and limitations under the
|
|
* License.
|
|
*/
|
|
|
|
package org.alfresco.filesys.avm;
|
|
|
|
import org.alfresco.filesys.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, 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;
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* 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 ? 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();
|
|
|
|
// 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
|
|
|
|
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)
|
|
{
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* 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 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;
|
|
}
|
|
str.append("]");
|
|
|
|
return str.toString();
|
|
}
|
|
}
|