/* * 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 * *

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 * *

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 * *

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 :/ 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 :/ 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; } /** * 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(); } }