Moved SQLite dlls to separate 32/64 folders in Libraries
[pithos-ms-client] / trunk / Pithos.Interfaces / ObjectInfo.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics.Contracts;
4 using System.Dynamic;
5 using System.Globalization;
6 using System.IO;
7 using System.Text.RegularExpressions;
8 using Newtonsoft.Json;
9
10 namespace Pithos.Interfaces
11 {
12     public class ObjectInfo:DynamicObject 
13     {
14         private readonly List<string> _knownContainers= new List<string>{"trash"};
15         public string Name { get; set; }
16         public string Hash { get; set; }
17         public long Bytes { get; set; }
18         public string Content_Type { get; set; }
19         public DateTime Last_Modified { get; set; }
20
21         private Dictionary<string, string> _tags=new Dictionary<string, string>();
22         public Dictionary<string, string> Tags
23         {
24             get { return _tags; }
25             set { _tags = value; }
26         }
27
28         private Dictionary<string, string> _extensions=new Dictionary<string, string>();
29         public Dictionary<string, string> Extensions
30         {
31             get { return _extensions; }
32             set
33             {
34                 _extensions = value;
35                 ExtractKnownExtensions();
36             }
37         }
38         
39         
40         private Dictionary<string, string> _permissions=new Dictionary<string, string>();
41         [JsonProperty("x_object_sharing")]
42         [JsonConverter(typeof(PermissionConverter))]
43         public Dictionary<string, string> Permissions
44         {
45             get { return _permissions; }
46             set
47             {
48                 _permissions = value;                
49             }
50         }
51
52         /// <summary>
53         /// Version number
54         /// </summary>
55         [JsonProperty("x_object_version")]
56         public long? Version { get; set; }
57
58
59         /// <summary>
60         /// Shared object permissions can be Read or Write
61         /// </summary>
62         [JsonProperty("x_object_allowed_to")]
63         public string AllowedTo { get; set; }
64
65
66         /// <summary>
67         /// Version timestamp
68         /// </summary>
69         [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
70         public DateTime? VersionTimestamp { get; set; }
71
72         [JsonProperty("X_Object_Modified_By")]
73         public string ModifiedBy { get; set; }
74
75
76         public Stream Stream { get; set; }
77
78         public string Account { get; set; }
79
80         public string Container { get; set; }
81
82         public ObjectInfo()
83         {}
84
85         public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
86         {
87             var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
88             //The first part of the URL is the container
89             var slashIndex = relativeUrl.IndexOf('/');
90             var container = relativeUrl.Substring(0, slashIndex);
91             //The second is the file's url relative to the container
92             var fileUrl = relativeUrl.Substring(slashIndex + 1);
93
94             Account = accountName;
95             Container = container;
96             Name = fileUrl; 
97         }
98
99
100         private void ExtractKnownExtensions()
101         {
102             Version=GetLong(KnownExtensions.X_Object_Version);
103             VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
104             ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
105         }
106
107         private string GetString(string name)
108         {            
109             var value=String.Empty;
110             _extensions.TryGetValue(name, out value);
111             return value ;                        
112         }
113
114         private long? GetLong(string name)
115         {
116             string version;
117             long value;
118             return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
119                        ? (long?) value
120                        : null;
121         }
122
123         private DateTime? GetTimestamp(string name)
124         {
125             string version;
126             DateTime value;
127             if (_extensions.TryGetValue(name, out version) && 
128                 DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
129             {
130                 return value;
131             }
132             return null;
133         }
134
135
136         public static ObjectInfo Empty = new ObjectInfo
137         {
138             Name = String.Empty,
139             Hash = String.Empty,
140             Bytes = 0,
141             Content_Type = String.Empty,
142             Last_Modified = DateTime.MinValue
143         };
144
145         public string RelativeUrlToFilePath(string currentAccount)
146         {
147             if (Name==null)
148                 throw new InvalidOperationException("Name can't be null");
149             if (String.IsNullOrWhiteSpace(currentAccount))
150                 throw new ArgumentNullException("currentAccount");
151             Contract.EndContractBlock();
152
153             if (this == Empty)
154                 return String.Empty;
155
156             var unescaped = Uri.UnescapeDataString(Name);
157             var path = unescaped.Replace("/", "\\");
158             var pathParts=new Stack<string>();
159             pathParts.Push(path);
160             if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
161                 pathParts.Push(Container);
162             if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
163             {
164                 if (Account != null)
165                 {
166                     pathParts.Push(Account);
167                     pathParts.Push("others");
168                 }
169             }
170             var finalPath=Path.Combine(pathParts.ToArray());
171             return finalPath;
172         }
173
174         public override bool TrySetMember(SetMemberBinder binder, object value)
175         {
176             if (binder.Name.StartsWith("x_object_meta"))
177             {
178                 Tags[binder.Name] = value.ToString();
179             }
180             return false;
181         }
182
183     }
184 }