/redistributable/AppLimit.CloudComputing.SharpBox/StorageProvider/GenericStorageProvider.cs
C# | 305 lines | 138 code | 41 blank | 126 comment | 22 complexity | 93a7b6b086d6789cfb567d4ee3ec189b MD5 | raw file
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using AppLimit.CloudComputing.SharpBox.Common.IO;
5using AppLimit.CloudComputing.SharpBox.Exceptions;
6using AppLimit.CloudComputing.SharpBox.StorageProvider.API;
7using AppLimit.CloudComputing.SharpBox.StorageProvider.BaseObjects;
8
9namespace AppLimit.CloudComputing.SharpBox.StorageProvider
10{
11 /// <summary>
12 /// The generic storage provider class implements platform independent logic as
13 /// base for all managed storage provider. All platform specific logic has to be implemented
14 /// in the storage provider service interface
15 /// </summary>
16 public class GenericStorageProvider : ICloudStorageProviderInternal
17 {
18 /// <summary>
19 /// A specific implementation of a storage service interface which contains
20 /// all provider specific logic
21 /// </summary>
22 protected IStorageProviderService Service;
23
24 /// <summary>
25 /// A provider specific implementation of a session
26 /// </summary>
27 protected IStorageProviderSession Session;
28
29 /// <summary>
30 /// The constructure need a specific service implementation
31 /// </summary>
32 /// <param name="service"></param>
33 public GenericStorageProvider(IStorageProviderService service)
34 {
35 Service = service;
36 }
37
38 #region ICloudStorageProvider Members
39
40 /// <summary>
41 /// This method opens a session for the implemented storage provider based on an existing
42 /// security token.
43 /// </summary>
44 /// <param name="configuration"></param>
45 /// <param name="token"></param>
46 /// <returns></returns>
47 public ICloudStorageAccessToken Open(ICloudStorageConfiguration configuration, ICloudStorageAccessToken token)
48 {
49 // Verify the compatibility of the credentials
50 if (!Service.VerifyAccessTokenType(token))
51 throw new SharpBoxException(SharpBoxErrorCodes.ErrorInvalidCredentialsOrConfiguration);
52
53 // create a new session
54 Session = Service.CreateSession(token, configuration);
55
56 // check the session
57 if (Session == null)
58 throw new SharpBoxException(SharpBoxErrorCodes.ErrorInvalidCredentialsOrConfiguration);
59
60 // return the accesstoken token
61 return Session.SessionToken;
62 }
63
64 /// <summary>
65 /// This method closes the established session to a service provider
66 /// </summary>
67 public void Close()
68 {
69 // close the session
70 Service.CloseSession(Session);
71
72 // remove reference
73 Session = null;
74 }
75
76 /// <summary>
77 /// This methid returns the root node of the virtual filesystem which
78 /// is abstracted by SharpBox
79 /// </summary>
80 /// <returns></returns>
81 public ICloudDirectoryEntry GetRoot()
82 {
83 return Service.RequestResource(Session, "/", null) as ICloudDirectoryEntry;
84 }
85
86 /// <summary>
87 /// This method returns a filesystem object, this can be files or folders
88 /// </summary>
89 /// <param name="path"></param>
90 /// <param name="parent"></param>
91 /// <returns></returns>
92 public ICloudFileSystemEntry GetFileSystemObject(string path, ICloudDirectoryEntry parent)
93 {
94 /*
95 * This section generates for every higher object the object tree
96 */
97 var ph = new PathHelper(path);
98 var elements = ph.GetPathElements();
99
100 // create the virtual root
101 var current = parent ?? GetRoot();
102
103 // build the root
104
105 // check if we request only the root
106 if (path.Equals("/"))
107 return current;
108
109 if (Service.SupportsDirectRetrieve)
110 {
111 //Request directly
112 return Service.RequestResource(Session, path.TrimStart('/'), current);
113 }
114
115 // create the path tree
116 for (var i = 0; i <= elements.Length - 1; i++)
117 {
118 var elem = elements[i];
119
120 if (i == elements.Length - 1)
121 {
122 return current.GetChild(elem, false);
123 }
124
125 try
126 {
127 current = current.GetChild(elem, true) as ICloudDirectoryEntry;
128 }
129 catch (SharpBoxException e)
130 {
131 // if not found, create a virtual one
132 if (e.ErrorCode == SharpBoxErrorCodes.ErrorFileNotFound)
133 current = GenericStorageProviderFactory.CreateDirectoryEntry(Session, elem, current);
134 else
135 throw;
136 }
137 }
138
139 // looks like an error
140 return null;
141 }
142
143 /// <summary>
144 /// This method creates a folder in a given parent folder.
145 /// Override this if your storage support resources having same name in one folder.
146 /// </summary>
147 /// <param name="name"></param>
148 /// <param name="parent"></param>
149 /// <returns></returns>
150 public virtual ICloudDirectoryEntry CreateFolder(string name, ICloudDirectoryEntry parent)
151 {
152 // solve the parent issue
153 if (parent == null)
154 {
155 parent = GetRoot();
156
157 if (parent == null)
158 return null;
159 }
160
161 // Don't support resources having same name in one folder by default
162 var child = parent.FirstOrDefault(x => x.Name.Equals(name) && x is ICloudDirectoryEntry);
163 if (child != null)
164 return child as ICloudDirectoryEntry;
165
166 return Service.CreateResource(Session, name, parent) as ICloudDirectoryEntry;
167 }
168
169 /// <summary>
170 /// This method removes a given filesystem object from the cloud storage
171 /// </summary>
172 /// <param name="fsentry"></param>
173 /// <returns></returns>
174 public bool DeleteFileSystemEntry(ICloudFileSystemEntry fsentry)
175 {
176 return Service.DeleteResource(Session, fsentry);
177 }
178
179 /// <summary>
180 /// This method moves a specifc filesystem object from his current location
181 /// into a new folder
182 /// </summary>
183 /// <param name="fsentry"></param>
184 /// <param name="newParent"></param>
185 /// <returns></returns>
186 public bool MoveFileSystemEntry(ICloudFileSystemEntry fsentry, ICloudDirectoryEntry newParent)
187 {
188 return Service.MoveResource(Session, fsentry, newParent);
189 }
190
191 /// <summary>
192 /// This method moves a specifc filesystem object from his current location
193 /// into a new folder
194 /// </summary>
195 /// <param name="fsentry"></param>
196 /// <param name="newParent"></param>
197 /// <returns></returns>
198 public bool CopyFileSystemEntry(ICloudFileSystemEntry fsentry, ICloudDirectoryEntry newParent)
199 {
200 return Service.CopyResource(Session, fsentry, newParent);
201 }
202
203 /// <summary>
204 /// This method renames a given filesystem object (file or folder)
205 /// </summary>
206 /// <param name="fsentry"></param>
207 /// <param name="newName"></param>
208 /// <returns></returns>
209 public bool RenameFileSystemEntry(ICloudFileSystemEntry fsentry, string newName)
210 {
211 // save the old name
212 var renamedId = fsentry.Id;
213
214 // rename the resource
215 if (Service.RenameResource(Session, fsentry, newName))
216 {
217 // get the parent
218 var p = fsentry.Parent as BaseDirectoryEntry;
219
220 // remove the old childname
221 p.RemoveChildById(renamedId);
222
223 // readd the child
224 p.AddChild(fsentry as BaseFileEntry);
225
226 // go ahead
227 return true;
228 }
229 return false;
230 }
231
232 /// <summary>
233 /// This method creates a file in the cloud storage
234 /// </summary>
235 /// <param name="parent"></param>
236 /// <param name="name"></param>
237 /// <returns></returns>
238 public virtual ICloudFileSystemEntry CreateFile(ICloudDirectoryEntry parent, string name)
239 {
240 // build the parent
241 if (parent == null)
242 parent = GetRoot();
243
244 // build the file entry
245 var newEntry = GenericStorageProviderFactory.CreateFileSystemEntry(Session, name, parent);
246 return newEntry;
247 }
248
249 /// <summary>
250 /// This method returns the absolut URL (with all authentication decorators) for a specific file
251 /// system object
252 /// </summary>
253 /// <param name="path"></param>
254 /// <param name="parent"></param>
255 /// <returns></returns>
256 public virtual Uri GetFileSystemObjectUrl(string path, ICloudDirectoryEntry parent)
257 {
258 var url = Service.GetResourceUrl(Session, parent, path);
259 return new Uri(url);
260 }
261
262 /// <summary>
263 /// This method returns the filesystem path (UNIX style) of a specific object
264 /// </summary>
265 /// <param name="fsObject"></param>
266 /// <returns></returns>
267 public virtual string GetFileSystemObjectPath(ICloudFileSystemEntry fsObject)
268 {
269 if (fsObject is ICloudDirectoryEntry)
270 return GenericHelper.GetResourcePath(fsObject);
271
272 return GenericHelper.GetResourcePath(fsObject.Parent) + "/" + fsObject.Id;
273 }
274
275 /// <summary>
276 /// This method stores the given security token into a tokendictionary
277 /// </summary>
278 /// <param name="tokendata"></param>
279 /// <param name="token"></param>
280 public void StoreToken(Dictionary<string, string> tokendata, ICloudStorageAccessToken token)
281 {
282 Service.StoreToken(Session, tokendata, token);
283 }
284
285 /// <summary>
286 /// This method loads the given token from the token dictionary
287 /// </summary>
288 /// <param name="tokendata"></param>
289 /// <returns></returns>
290 public ICloudStorageAccessToken LoadToken(Dictionary<string, string> tokendata)
291 {
292 return Service.LoadToken(tokendata);
293 }
294
295 /// <summary>
296 /// This property returns the current accesstoken
297 /// </summary>
298 public ICloudStorageAccessToken CurrentAccessToken
299 {
300 get { return Session == null ? null : Session.SessionToken; }
301 }
302
303 #endregion
304 }
305}