-
Notifications
You must be signed in to change notification settings - Fork 11
/
FileSystemStoreObject.cs
146 lines (145 loc) · 6.39 KB
/
FileSystemStoreObject.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.IO;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp.Utils;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
namespace FileSystemData.BusinessObjects {
/// <summary>
/// This class enables you to store uploaded files in a centralized file system location instead of the database. You can configure the file system store location via the static FileSystemDataModule.FileSystemStoreLocation property.
/// </summary>
[DefaultProperty(nameof(FileName))]
public class FileSystemStoreObject : BaseObject, IFileData, IEmptyCheckable {
private Stream tempSourceStream;
private string tempFileName = string.Empty;
private static object syncRoot = new object();
public FileSystemStoreObject(Session session) : base(session) { }
public string RealFileName {
get {
if (!string.IsNullOrEmpty(FileName) && Oid != Guid.Empty)
return Path.Combine(FileSystemDataModule.FileSystemStoreLocation, string.Format("{0}-{1}", Oid, FileName));
return null;
}
}
protected virtual void SaveFileToStore() {
if(!string.IsNullOrEmpty(RealFileName) && TempSourceStream != null) {
try {
using(Stream destination = File.Create(RealFileName)) { //T582918
FileSystemDataModule.CopyStream(TempSourceStream, destination);
Size = (int)destination.Length;
}
}
catch(DirectoryNotFoundException exc) {
throw new UserFriendlyException(exc);
}
}
}
private void RemoveOldFileFromStore() {
//Dennis: We need to remove the old file from the store when saving the current object.
if (!string.IsNullOrEmpty(tempFileName) && tempFileName != RealFileName) {//B222892
try {
File.Delete(tempFileName);
tempFileName = string.Empty;
} catch (DirectoryNotFoundException exc) {
throw new UserFriendlyException(exc);
}
}
}
protected override void OnSaving() {
base.OnSaving();
Guard.ArgumentNotNullOrEmpty(FileSystemDataModule.FileSystemStoreLocation, "FileSystemStoreLocation");
lock (syncRoot) {
if (!Directory.Exists(FileSystemDataModule.FileSystemStoreLocation))
Directory.CreateDirectory(FileSystemDataModule.FileSystemStoreLocation);
}
SaveFileToStore();
RemoveOldFileFromStore();
}
protected override void OnDeleting() {
//Dennis: We need to remove the old file from the store.
Clear();
base.OnDeleting();
}
protected override void Invalidate(bool disposing) {
if (disposing && TempSourceStream != null) {
TempSourceStream.Close();
TempSourceStream = null;
}
base.Invalidate(disposing);
}
#region IFileData Members
public void Clear() {
//Dennis: When clearing the file name property we need to save the name of the old file to remove it from the store in the future. You can also setup a separate service for that.
if (string.IsNullOrEmpty(tempFileName))
tempFileName = RealFileName;
FileName = string.Empty;
Size = 0;
}
[Size(260)]
public string FileName {
get { return GetPropertyValue<string>(nameof(FileName)); }
set { SetPropertyValue(nameof(FileName), value); }
}
[Browsable(false)]
public Stream TempSourceStream {
get { return tempSourceStream; }
set {
//Michael: The original Stream might be closed after a while (on the web too - T160753)
if (value == null) {
tempSourceStream = null;
} else {
if (value.Length > (long)int.MaxValue) throw new UserFriendlyException("File is too long");
tempSourceStream = new MemoryStream((int)value.Length);
FileSystemDataModule.CopyStream(value, tempSourceStream);
tempSourceStream.Position = 0;
}
}
}
//Dennis: Fires when uploading a file.
void IFileData.LoadFromStream(string fileName,Stream source) {
//Dennis: When assigning a new file we need to save the name of the old file to remove it from the store in the future.
if(fileName != FileName) {// updated, old code was: if (string.IsNullOrEmpty(tempFileName))
tempFileName = RealFileName;
}
FileName = fileName;
TempSourceStream = source;
Size = (int)TempSourceStream.Length;
OnChanged();//T582918
}
//Dennis: Fires when saving or opening a file.
void IFileData.SaveToStream(Stream destination) {
try {
if(!File.Exists(RealFileName)) {
return;
}
if (!string.IsNullOrEmpty(RealFileName)) {
if (destination == null)
FileSystemDataModule.OpenFileWithDefaultProgram(RealFileName);
else
FileSystemDataModule.CopyFileToStream(RealFileName, destination);
}
else if (TempSourceStream != null)
FileSystemDataModule.CopyStream(TempSourceStream, destination);
} catch (DirectoryNotFoundException exc) {
throw new UserFriendlyException(exc);
} catch (FileNotFoundException exc) {
throw new UserFriendlyException(exc);
}
}
[Persistent]
public int Size {
get { return GetPropertyValue<int>(nameof(Size)); }
private set { SetPropertyValue(nameof(Size), value); }
}
#endregion
#region IEmptyCheckable Members
public bool IsEmpty {
//T153149
get { return FileDataHelper.IsFileDataEmpty(this) || !(TempSourceStream!= null || File.Exists(RealFileName)); }
}
#endregion
}
}