home *** CD-ROM | disk | FTP | other *** search
Wrap
/* * Xceed Zip for .NET - ExtendingDemo Sample Classes * Copyright (c) 2000-2002 - Xceed Software Inc. * * [IsolatedFolder.cs] * * This application demonstrates how to extend the Xceed FileSystem object model * by deriving from the AbstractFolder class. * * This file is part of Xceed Zip for .NET. The source code in this file * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ using System; using System.Collections; using System.IO; using System.IO.IsolatedStorage; using Xceed.FileSystem; namespace Xceed.FileSystem.Samples.ExtendingDemo { /// <summary> /// This class demonstrates how to create a class that derives /// from the <see cref="AbstractFolder"/> class and handles isolated storage folders. /// </summary> public class IsolatedFolder : AbstractFolder { #region PUBLIC CONSTRUCTORS /// <summary> /// Creates a new instance of IsolatedFolder class. /// </summary> /// <param name="folderName">Name (with path) of the folder.</param> /// <remarks><para>Allowed path: "foo", "foo\bar", "\foo\bar"</para></remarks> public IsolatedFolder( string folderName ) { if( folderName == null ) throw new ArgumentNullException( "folderName" ); folderName = folderName.Trim(); if( folderName.IndexOfAny( this.InvalidChars ) != -1 ) throw new ArgumentException( "The folder name contains invalid characters.", "folderName" ); folderName = folderName.Replace( Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar ); folderName = folderName.StartsWith( Path.DirectorySeparatorChar.ToString() ) ? folderName : ( Path.DirectorySeparatorChar + folderName ); folderName = folderName.EndsWith( Path.DirectorySeparatorChar.ToString() ) ? folderName : ( folderName + Path.DirectorySeparatorChar ); m_fullName = folderName; if( m_fullName == Path.DirectorySeparatorChar.ToString() ) { m_name = string.Empty; m_isRoot = true; } else { m_name = Path.GetFileName( m_fullName.TrimEnd( Path.DirectorySeparatorChar ) ); } } #endregion PUBLIC CONSTRUCTORS #region PRIVATE METHODS /// <summary> /// Retrieves an array of <see cref="FileSystemItem"/> objects representing each /// item ( file and folder ) within the isolated storage folder. /// </summary> /// <param name="session">A reference to a <see cref="FileSystemEventsSession"/> object which is /// responsible for raising all events that occur during the process.</param> /// <returns>An array of <see cref="FileSystemItem"/> objects representing each item /// ( file and folder ) within the isolated storage folder.</returns> protected override FileSystemItem[] DoGetChildItems( FileSystemEventsSession session ) { try { FileSystemItem[] childItems; IsolatedStorageFile isoStore = IsolatedFolder.m_domainStore; string[] childFiles = isoStore.GetFileNames( this.FullName + "*" ); string[] childFolders = isoStore.GetDirectoryNames( this.FullName + "*" ); childItems = new FileSystemItem[ childFolders.Length + childFiles.Length ]; for( int i = 0; i < childFolders.Length; i++ ) { childItems[ i ] = new IsolatedFolder( this.FullName + childFolders[ i ] ); } for( int i = 0; i < childFiles.Length; i++ ) { childItems[ childFolders.Length + i ] = new IsolatedFile( this.FullName + childFiles[ i ] ); } return childItems; } catch( IsolatedStorageException except ) { throw new FileSystemException( "The list of child items could not be retrieved from the folder.", this, except ); } } /// <summary> /// Gets or sets the short name of the folder /// </summary> /// <value>A string that represents the short name of the folder.</value> /// <remarks><para>The short name consists of the item's name without a path. /// For example, the short name of a folder named "c:\foo\" is "foo". /para></remarks> protected override string DoName { get { return m_name; } set { if( value == this.Name ) return; if( this.Exists ) { // Renaming a folder in the isolated storage isn't that simple. // We must create a new folder with the new name, move each // child file and folder into that new foldera and then delete the // original folder. string path = this.ParentFolder.FullName; IsolatedFolder folder = new IsolatedFolder( path + value ); folder.Create(); foreach( FileSystemItem item in this.GetItems( false ) ) { item.MoveTo( folder, true ); } this.Delete(); m_fullName = folder.FullName; m_name = folder.Name; } else { m_fullName = this.ParentFolder.FullName + value + Path.DirectorySeparatorChar; m_name = value; } } } /// <summary> /// Gets the full name of the folder /// </summary> /// <value>A string that contains the full name of the folder.</value> /// <remarks><para>The full name consists of the item's name fully-qualified /// with a path. For example: "c:\foo\".</para></remarks> protected override string DoFullName { get { return m_fullName; } } /// <summary> /// Folders in isolated storage do have attributes. Therefore, we throw /// a <see cref="FileSystemNotSupportException"/> when trying to get or set the folder attributes. /// </summary> /// <returns><see cref="FileSystemNotSupportException"/></returns> protected override FileAttributes DoAttributes { get { throw new FileSystemNotSupportedException( this ); } set { throw new FileSystemNotSupportedException( this ); } } /// <summary> /// Since there is no notion of date/time when dealing with folders in /// isolate storage, we throw a <see cref="FileSystemNotSupportException"/> when trying /// to get or set the CreationDateTime. /// </summary> /// <returns><see cref="FileSystemNotSupportException"/></returns> protected override DateTime DoCreationDateTime { get { throw new FileSystemNotSupportedException( this ); } set { throw new FileSystemNotSupportedException( this ); } } /// <summary> /// Since there is no notion of date/time when dealing with folders in /// isolate storage, we throw a <see cref="FileSystemNotSupportException"/> when trying /// to get or set the LastWriteDateTime. /// </summary> /// <returns><see cref="FileSystemNotSupportException"/></returns> protected override DateTime DoLastWriteDateTime { get { throw new FileSystemNotSupportedException( this ); } set { throw new FileSystemNotSupportedException( this ); } } /// <summary> /// Since there is no notion of date/time when dealing with folders in /// isolate storage, we throw a <see cref="FileSystemNotSupportException"/> when trying /// to get or set the LastAccessDateTime. /// </summary> /// <returns><see cref="FileSystemNotSupportException"/></returns> protected override DateTime DoLastAccessDateTime { get { throw new FileSystemNotSupportedException( this ); } set { throw new FileSystemNotSupportedException( this ); } } /// <summary> /// Gets a reference to the parent folder of the folder. /// </summary> /// <returns>A reference to an IsolatedFolder object that represents the folder which /// contains the folder, or a null reference if the folder does not have a parent.</returns> protected override AbstractFolder DoParentFolder { get { string directoryName = this.FullName.TrimEnd( Path.DirectorySeparatorChar ); if( directoryName.Length != 0 ) { string parentFullName = Path.GetDirectoryName( directoryName ); if( ( parentFullName != null ) && ( parentFullName.Length != 0 ) ) { return new IsolatedFolder( parentFullName ); } } return null; } } /// <summary> /// Gets a reference to the root folder of the folder. /// </summary> /// <returns>A reference to an IsolatedFolder object that represents /// the root folder of the folder.</returns> protected override AbstractFolder DoRootFolder { get { return new IsolatedFolder( string.Empty ); } } /// <summary> /// Gets a boolean value indicating if the folder physically exists. /// </summary> /// <returns><see langword="true"/> if the item physically exists; <see langword="false"/> otherwise.</returns> protected override bool DoExists { get { if( this.IsRoot ) return true; try { string directoryName = this.FullName.TrimEnd( Path.DirectorySeparatorChar ); IsolatedStorageFile isoStore = IsolatedFolder.m_domainStore; return ( isoStore.GetDirectoryNames( directoryName ).Length != 0 ); } catch( DirectoryNotFoundException ) { return false; } catch( IsolatedStorageException ) { return false; } } } /// <summary> /// Physically created the folder in the isolated storage. /// </summary> /// <param name="session">A reference to a <see cref="FileSystemEventsSession"/> object which is /// responsible for raising all events that occur during the process.</param> protected override void DoCreate( FileSystemEventsSession session ) { if( this.Exists ) throw new ItemAlreadyExistsException( this ); // The public Create method is responsible for making sure our parent folder // exists. The DoCreate method can assume it's parents exist. We still verify if they do // in case something real bad happened. if( this.ParentFolder != null && !this.ParentFolder.Exists ) { System.Diagnostics.Debug.Assert( false ); throw new FileSystemInternalException( "An unexpected attempt was made to create an item in a folder that does not exist.", this ); } try { string directoryName = this.FullName.TrimEnd( Path.DirectorySeparatorChar ); IsolatedStorageFile isoStore = IsolatedFolder.m_domainStore; isoStore.CreateDirectory( directoryName ); } catch( IsolatedStorageException except ) { throw new FileSystemException( "The physical folder represented by the item could not be created.", this, except ); } } /// <summary> /// Re-reads the information from the physical folder. /// </summary> protected override void DoRefresh( FileSystemEventsSession session ) { if( !this.Exists ) throw new ItemDoesNotExistException( this ); // We have nothing to refresh! } /// <summary> /// Retrieves a reference to an <see cref="AbstractFile"/> object representing /// a file in the isolated store. /// </summary> /// <param name="session">A reference to a <see cref="FileSystemEventsSession"/> object which is /// responsible for raising all events that occur during the process.</param> /// <param name="fileName">The name of the file to retrieve.</param> /// <returns>A reference to an <see cref="AbstractFile"/> object regardless of if the file represented by the object exists or not. /// </returns> /// <remarks><para><paramref name="fileName"/> should not end with a <see cref="System.IO.Path.DirectorySeparatorChar"/>. /// </para></remarks> protected override AbstractFile DoGetFile( FileSystemEventsSession session, string fileName ) { System.Diagnostics.Debug.Assert( fileName.IndexOf( Path.DirectorySeparatorChar ) == -1, "The fileName parameter cannot end with a directory separator char." ); return new IsolatedFile( this.FullName + fileName ); } /// <summary> /// Retrieves a reference to an <see cref="AbstractFolder"/> object representing /// a folder in the isolated store. /// </summary> /// <param name="session">A reference to a <see cref="FileSystemEventsSession"/> object which is /// responsible for raising all events that occur during the process.</param> /// <param name="folderName">The name of the folder to retrieve.</param> /// <returns>A reference to an <see cref="AbstractFolder"/> object regardless of if the folder represented by the object exists or not.</returns> /// <remarks><para><paramref name="folderName"/> should not end with a <see cref="System.IO.Path.DirectorySeparatorChar"/>. /// </para></remarks> protected override AbstractFolder DoGetFolder( FileSystemEventsSession session, string folderName ) { System.Diagnostics.Debug.Assert( folderName.IndexOf( Path.DirectorySeparatorChar ) == -1, "The folderName parameter cannot end with a directory separator char." ); return new IsolatedFolder( this.FullName + folderName ); } /// <summary> /// Gets a boolean value indicating if the source and target items are the same. /// </summary> /// <param name="target">A <see cref="FileSystemItem"/> object representing the destination folder.</param> /// <returns><see langword="true"/> if the source and target <see cref="FileSystemItem"/> objects are the same; <see langword="false"/> otherwise.</returns> protected override bool IsSameAs( FileSystemItem target ) { if( target == null ) return false; // In some file systems, two identical folder names does not mean // it's the same folder. With the isolated storage's domain store, // we can simply check if both items have the same type and fullname. if( target is IsolatedFolder ) { return( this.FullName == target.FullName ); } else { return false; } } /// <summary> /// Indicates if the provided path contains a root description. /// </summary> /// <param name="path">The path to verify</param> /// <returns><see langword="true"/> if the path is rooted; <see langword="false"/> otherwise.</returns> protected override bool IsPathRooted( string path ) { // With Isolated Storage, there is no such thing as a rooted path. // For example, "D:\Folder" is a rooted path for disk items. return false; } /// <summary> /// Permanently deletes the file. /// </summary> /// <param name="session">A reference to a <see cref="FileSystemEventsSession"/> object which is responsible for raising all /// events that occur during the process.</param> protected override void DoDelete( FileSystemEventsSession session ) { if( !this.Exists ) throw new ItemDoesNotExistException( this ); // The public Delete method is responsible for calling Delete on all // children. We simply need to delete ourself. If we're not empty, it // means one or more child items were ignored in the OnItemException event. try { string directoryName = this.FullName.TrimEnd( Path.DirectorySeparatorChar ); IsolatedStorageFile isoStore = IsolatedFolder.m_domainStore; isoStore.DeleteDirectory( directoryName ); } catch( IsolatedStorageException except ) { throw new FileSystemException( "The physical folder represented by the item could not be deleted.", this, except ); } } #endregion PRIVATE METHODS #region PRIVATE FIELDS /// <summary>The name of the folder without it's parent's path.</summary> private string m_name = string.Empty; /// <summary>The fully qualified name of the folder.</summary> private string m_fullName = string.Empty; #endregion PRIVATE FIELDS #region INTERNAL STATIC FIELDS /// <summary>This implementation only supports the User Store.</summary> internal static IsolatedStorageFile m_domainStore = IsolatedStorageFile.GetUserStoreForDomain(); #endregion STATIC PUBLIC PROPERTIES } }