1
/****************************************************************************
3
| Copyright (c) 2007 Novell, Inc.
6
| This program is free software; you can redistribute it and/or
7
| modify it under the terms of version 2 of the GNU General Public License as
8
| published by the Free Software Foundation.
10
| This program is distributed in the hope that it will be useful,
11
| but WITHOUT ANY WARRANTY; without even the implied warranty of
12
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
| GNU General Public License for more details.
15
| You should have received a copy of the GNU General Public License
16
| along with this program; if not, contact Novell, Inc.
18
| To contact Novell about this file by physical or electronic mail,
19
| you may find current contact information at www.novell.com
21
| Author: Mike Lasky <mlasky@novell.com>
22
|***************************************************************************/
25
using System.Collections;
26
using System.Collections.Specialized;
28
using System.Reflection;
33
namespace Simias.Storage
36
/// Represents a generic file object.
39
public abstract class BaseFileNode : Node
43
/// Xml file where metadata file types are registered.
45
private const string metadataExtensionFile = "csmetadata.xml";
48
/// Well known xml attribute tags.
50
private const string associatedtypeString = "associatedtype";
51
private const string extensionString = "extension";
52
private const string assemblyString = "assembly";
55
/// Name of the method to invoke to gather the file's metadata.
57
private const string metadataMethodName = "GetMetaData";
62
/// Gets or sets the file creation time in the metadata.
64
new public DateTime CreationTime
68
Property p = properties.FindSingleValue( PropertyTags.CreationTime );
69
return ( p != null ) ? ( DateTime )p.Value : DateTime.MinValue;
72
set { properties.ModifyNodeProperty( PropertyTags.CreationTime, value ); }
76
/// Gets or sets the file last access time in the metadata.
78
public DateTime LastAccessTime
82
Property p = properties.FindSingleValue( PropertyTags.LastAccessTime );
83
return ( p != null ) ? ( DateTime )p.Value : DateTime.MinValue;
86
set { properties.ModifyNodeProperty( PropertyTags.LastAccessTime, value ); }
90
/// Gets or sets the file last write time in the metadata.
92
public DateTime LastWriteTime
96
Property p = properties.FindSingleValue( PropertyTags.LastWriteTime );
97
return ( p != null ) ? ( DateTime )p.Value : DateTime.MinValue;
100
set { properties.ModifyNodeProperty( PropertyTags.LastWriteTime, value ); }
104
/// Gets or sets the file length in the metadata.
110
Property p = properties.FindSingleValue( PropertyTags.FileLength );
111
return ( p != null ) ? ( long )p.Value : 0;
114
set { properties.ModifyNodeProperty( PropertyTags.FileLength, value ); }
120
/// Constructor used to create a new BaseFileNode object.
122
/// <param name="collection">Collection that this file entry will be associated with.</param>
123
/// <param name="parentPath">Fully qualified path to the parent directory.</param>
124
/// <param name="fileName">Friendly name of the file entry.</param>
125
/// <param name="fileID">Globally unique identifier for the file entry.</param>
126
/// <param name="fileType">Class type to deserialize file entry as.</param>
127
internal protected BaseFileNode( Collection collection, string parentPath, string fileName, string fileID, string fileType ) :
128
this ( fileName, fileID, fileType )
130
// Add the disk file attributes if the file exists.
131
if ( UpdateFileInfo( collection, Path.Combine( parentPath, fileName ) ) )
133
// If there are metadata collectors registered for this file type, add the extra metadata.
134
AddFileMetadata( collection, GetFullPath( collection ) );
139
/// Constructor used to create a new BaseFileNode object.
141
/// <param name="stream">Stream object that contains the file data.</param>
142
/// <param name="fileName">Friendly name of the file entry.</param>
143
/// <param name="fileID">Globally unique identifier for the file entry.</param>
144
/// <param name="fileType">Class type to deserialize file entry as.</param>
145
internal protected BaseFileNode( Stream stream, string fileName, string fileID, string fileType ) :
146
this ( fileName, fileID, fileType )
148
// Add the length of the file.
149
Length = stream.Length;
153
/// Constructor used to create a new BaseFileNode object.
155
/// <param name="fileName">Friendly name of the file entry.</param>
156
/// <param name="fileID">Globally unique identifier for the file entry.</param>
157
/// <param name="fileType">Class type to deserialize file entry as.</param>
158
internal protected BaseFileNode( string fileName, string fileID, string fileType ) :
159
base ( fileName, fileID, fileType )
161
// Add to the Types list.
162
properties.AddNodeProperty( PropertyTags.Types, NodeTypes.BaseFileNodeType );
166
/// Constructor for creating an existing BaseFileNode object.
168
/// <param name="node">Node object to create BaseFileNode object from.</param>
169
internal protected BaseFileNode( Node node ) :
175
/// Constructor for create an existing BaseFileNode object from a ShallowNode object.
177
/// <param name="collection">Collection that the ShallowNode belongs to.</param>
178
/// <param name="shallowNode">ShallowNode object to create new BaseFileNode object from.</param>
179
internal protected BaseFileNode( Collection collection, ShallowNode shallowNode ) :
180
base( collection, shallowNode )
185
/// Constructor for creating an existing BaseFileNode object from an Xml document object.
187
/// <param name="document">Xml document object to create BaseFileNode object from.</param>
188
internal protected BaseFileNode( XmlDocument document ) :
194
#region Private Methods
196
/// If file type is a registered metadata type, then the file metadata is collected and automatically
197
/// added to this node.
199
/// <param name="collection">Collection that this file entry will be associated with.</param>
200
/// <param name="filePath">Fully qualified path to the file.</param>
201
private void AddFileMetadata( Collection collection, string filePath )
203
// Get the directory path that this assembly was loaded from.
204
string loadDir = Path.GetDirectoryName( Assembly.GetExecutingAssembly().CodeBase );
206
// Build a path to the extension mapping file.
207
string xmlMetaFile = Path.Combine( loadDir, metadataExtensionFile );
208
if ( File.Exists( xmlMetaFile ) )
210
// Check if this file is a registered metadata type.
211
XmlDocument regExtDoc = new XmlDocument();
212
regExtDoc.Load( xmlMetaFile );
214
// See if this file has an extension.
215
string extension = Path.GetExtension( filePath );
216
if (extension != String.Empty )
218
// Find out if there is a registered entry for this extension.
219
XmlNode metaNode = regExtDoc.DocumentElement.SelectSingleNode( associatedtypeString + "[@" + extensionString + "='" + extension.ToLower() + "']" );
220
if ( metaNode != null )
222
// Load the assembly that knows how to parse the file metadata.
223
Assembly metaAssembly = Assembly.LoadFrom( Path.Combine( loadDir, metaNode.Attributes[ assemblyString ].Value ) );
224
Type[] types = metaAssembly.GetTypes();
225
foreach ( Type type in types )
227
// Find the method to invoke to gather the metadata.
228
MethodInfo method = type.GetMethod( metadataMethodName, BindingFlags.Static | BindingFlags.Public );
229
if ( method != null )
233
// Found the method. Invoke it to return a name-value object that will contain the metadata.
234
StringDictionary sd = ( StringDictionary )method.Invoke( null, new object[] { filePath } );
236
// Walk through each name-value and add it to the parent node.
237
foreach ( string s in sd.Keys )
239
properties.ModifyProperty( s, sd[ s ] );
244
// Do nothing. Just don't let it blow up.
256
#region Public Methods
258
/// Gets the file entry name with its extension.
260
/// <returns>The name of the file including the extension.</returns>
261
public abstract string GetFileName();
264
/// Gets the full path of the file entry.
266
/// <param name="collection">Collection that this file entry is associated with.</param>
267
/// <returns>The absolute path to the file.</returns>
268
public abstract string GetFullPath( Collection collection );
271
/// Updates the file node with file information from the disk file.
273
/// <param name="collection">Collection that this file entry is associated with.</param>
274
/// <returns>True if the file information has changed, otherwise false is returned.</returns>
275
public bool UpdateFileInfo( Collection collection )
277
return UpdateFileInfo( collection, GetFullPath( collection ) );
281
/// Updates the file node with file information from the disk file.
283
/// <param name="collection">Collection that this file entry is associated with.</param>
284
/// <param name="fullPath">Absolute path to the disk file.</param>
285
/// <returns>True if the file information has changed, otherwise false is returned.</returns>
286
public bool UpdateFileInfo( Collection collection, string fullPath )
288
bool infoChanged = false;
289
if ( File.Exists( fullPath ) )
291
// Get the file information for this file and set it as properties in the object.
292
FileInfo fi = new FileInfo( fullPath );
295
// Don't update the creation time if it already exists.
296
if ( CreationTime == DateTime.MinValue )
298
CreationTime = fi.CreationTime;
301
LastAccessTime = fi.LastAccessTime;
302
LastWriteTime = fi.LastWriteTime;
308
public bool UpdateWebFileInfo( Collection collection, long length)
310
bool infoChanged = false;
311
if ( File.Exists( GetFullPath(collection) ) )
313
// Get the file information for this file and set it as properties in the object.
314
FileInfo fi = new FileInfo( GetFullPath(collection) );
317
// Don't update the creation time if it already exists.
318
if ( CreationTime == DateTime.MinValue )
320
CreationTime = fi.CreationTime;
323
LastAccessTime = fi.LastAccessTime;
324
LastWriteTime = fi.LastWriteTime;