diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs new file mode 100644 index 0000000..6a50906 --- /dev/null +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #region Header | ||
29 | |||
30 | // FileSystemDatabase.cs | ||
31 | // User: bongiojp | ||
32 | |||
33 | #endregion Header | ||
34 | |||
35 | using System; | ||
36 | using System.Collections.Generic; | ||
37 | using System.Diagnostics; | ||
38 | using System.IO; | ||
39 | using Slash = System.IO.Path; | ||
40 | using System.Reflection; | ||
41 | using System.Xml; | ||
42 | |||
43 | using OpenMetaverse; | ||
44 | |||
45 | using Nini.Config; | ||
46 | |||
47 | using OpenSim.Framework; | ||
48 | using OpenSim.Region.Framework.Interfaces; | ||
49 | using OpenSim.Region.Framework.Scenes; | ||
50 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
51 | using OpenSim.Region.CoreModules.World.Terrain; | ||
52 | using OpenSim.Region.Physics.Manager; | ||
53 | |||
54 | using log4net; | ||
55 | |||
56 | namespace OpenSim.Region.OptionalModules.ContentManagement | ||
57 | { | ||
58 | public class FileSystemDatabase : IContentDatabase | ||
59 | { | ||
60 | #region Static Fields | ||
61 | |||
62 | public static float TimeToDownload = 0; | ||
63 | public static float TimeToSave = 0; | ||
64 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
65 | |||
66 | #endregion Static Fields | ||
67 | |||
68 | #region Fields | ||
69 | |||
70 | private string m_repodir = null; | ||
71 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||
72 | private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>(); | ||
73 | |||
74 | #endregion Fields | ||
75 | |||
76 | #region Constructors | ||
77 | |||
78 | public FileSystemDatabase() | ||
79 | { | ||
80 | } | ||
81 | |||
82 | #endregion Constructors | ||
83 | |||
84 | #region Private Methods | ||
85 | |||
86 | // called by postinitialise | ||
87 | private void CreateDirectory() | ||
88 | { | ||
89 | string scenedir; | ||
90 | if (!Directory.Exists(m_repodir)) | ||
91 | Directory.CreateDirectory(m_repodir); | ||
92 | |||
93 | foreach (UUID region in m_scenes.Keys) | ||
94 | { | ||
95 | scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar; | ||
96 | if (!Directory.Exists(scenedir)) | ||
97 | Directory.CreateDirectory(scenedir); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | // called by postinitialise | ||
102 | private void SetupSerialiser() | ||
103 | { | ||
104 | if (m_serialiser.Count == 0) | ||
105 | { | ||
106 | foreach (UUID region in m_scenes.Keys) | ||
107 | { | ||
108 | m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>()); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | #endregion Private Methods | ||
114 | |||
115 | #region Public Methods | ||
116 | |||
117 | public int GetMostRecentRevision(UUID regionid) | ||
118 | { | ||
119 | return NumOfRegionRev(regionid); | ||
120 | } | ||
121 | |||
122 | public string GetRegionObjectHeightMap(UUID regionid) | ||
123 | { | ||
124 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | ||
125 | Slash.DirectorySeparatorChar + "heightmap.r32"; | ||
126 | FileStream fs = new FileStream( filename, FileMode.Open); | ||
127 | StreamReader sr = new StreamReader(fs); | ||
128 | String result = sr.ReadToEnd(); | ||
129 | sr.Close(); | ||
130 | fs.Close(); | ||
131 | return result; | ||
132 | } | ||
133 | |||
134 | public string GetRegionObjectHeightMap(UUID regionid, int revision) | ||
135 | { | ||
136 | String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + | ||
137 | Slash.DirectorySeparatorChar + "heightmap.r32"; | ||
138 | FileStream fs = new FileStream( filename, FileMode.Open); | ||
139 | StreamReader sr = new StreamReader(fs); | ||
140 | String result = sr.ReadToEnd(); | ||
141 | sr.Close(); | ||
142 | fs.Close(); | ||
143 | return result; | ||
144 | } | ||
145 | |||
146 | public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision) | ||
147 | { | ||
148 | System.Collections.ArrayList objectList = new System.Collections.ArrayList(); | ||
149 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + | ||
150 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; | ||
151 | XmlDocument doc = new XmlDocument(); | ||
152 | XmlNode rootNode; | ||
153 | //int primCount = 0; | ||
154 | //SceneObjectGroup obj = null; | ||
155 | |||
156 | if (File.Exists(filename)) | ||
157 | { | ||
158 | XmlTextReader reader = new XmlTextReader(filename); | ||
159 | reader.WhitespaceHandling = WhitespaceHandling.None; | ||
160 | doc.Load(reader); | ||
161 | reader.Close(); | ||
162 | rootNode = doc.FirstChild; | ||
163 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) | ||
164 | { | ||
165 | objectList.Add(aPrimNode.OuterXml); | ||
166 | } | ||
167 | return objectList; | ||
168 | } | ||
169 | return null; | ||
170 | } | ||
171 | |||
172 | public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid) | ||
173 | { | ||
174 | int revision = NumOfRegionRev(regionid); | ||
175 | m_log.Info("[FSDB]: found revisions:" + revision); | ||
176 | System.Collections.ArrayList xmlList = new System.Collections.ArrayList(); | ||
177 | string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + | ||
178 | + revision + Slash.DirectorySeparatorChar + "objects.xml"; | ||
179 | XmlDocument doc = new XmlDocument(); | ||
180 | XmlNode rootNode; | ||
181 | |||
182 | m_log.Info("[FSDB]: Checking if " + filename + " exists."); | ||
183 | if (File.Exists(filename)) | ||
184 | { | ||
185 | Stopwatch x = new Stopwatch(); | ||
186 | x.Start(); | ||
187 | |||
188 | XmlTextReader reader = new XmlTextReader(filename); | ||
189 | reader.WhitespaceHandling = WhitespaceHandling.None; | ||
190 | doc.Load(reader); | ||
191 | reader.Close(); | ||
192 | rootNode = doc.FirstChild; | ||
193 | |||
194 | foreach (XmlNode aPrimNode in rootNode.ChildNodes) | ||
195 | { | ||
196 | xmlList.Add(aPrimNode.OuterXml); | ||
197 | } | ||
198 | |||
199 | x.Stop(); | ||
200 | TimeToDownload += x.ElapsedMilliseconds; | ||
201 | m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload); | ||
202 | |||
203 | return xmlList; | ||
204 | } | ||
205 | return null; | ||
206 | } | ||
207 | |||
208 | public void Initialise(Scene scene, string dir) | ||
209 | { | ||
210 | lock (this) | ||
211 | { | ||
212 | if (m_repodir == null) | ||
213 | m_repodir = dir; | ||
214 | } | ||
215 | lock (m_scenes) | ||
216 | m_scenes.Add(scene.RegionInfo.RegionID, scene); | ||
217 | } | ||
218 | |||
219 | public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid) | ||
220 | { | ||
221 | SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>(); | ||
222 | |||
223 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
224 | string[] directories = Directory.GetDirectories(scenedir); | ||
225 | |||
226 | FileStream fs = null; | ||
227 | StreamReader sr = null; | ||
228 | String logMessage = ""; | ||
229 | String logLocation = ""; | ||
230 | foreach (string revisionDir in directories) | ||
231 | { | ||
232 | try | ||
233 | { | ||
234 | logLocation = revisionDir + Slash.DirectorySeparatorChar + "log"; | ||
235 | fs = new FileStream( logLocation, FileMode.Open); | ||
236 | sr = new StreamReader(fs); | ||
237 | logMessage = sr.ReadToEnd(); | ||
238 | sr.Close(); | ||
239 | fs.Close(); | ||
240 | revisionDict.Add(revisionDir, logMessage); | ||
241 | } | ||
242 | catch (Exception) | ||
243 | { | ||
244 | } | ||
245 | } | ||
246 | |||
247 | return revisionDict; | ||
248 | } | ||
249 | |||
250 | public int NumOfRegionRev(UUID regionid) | ||
251 | { | ||
252 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
253 | m_log.Info("[FSDB]: Reading scene dir: " + scenedir); | ||
254 | string[] directories = Directory.GetDirectories(scenedir); | ||
255 | return directories.Length; | ||
256 | } | ||
257 | |||
258 | // Run once and only once. | ||
259 | public void PostInitialise() | ||
260 | { | ||
261 | SetupSerialiser(); | ||
262 | |||
263 | m_log.Info("[FSDB]: Creating repository in " + m_repodir + "."); | ||
264 | CreateDirectory(); | ||
265 | } | ||
266 | |||
267 | public void SaveRegion(UUID regionid, string regionName, string logMessage) | ||
268 | { | ||
269 | m_log.Info("[FSDB]: ..............................."); | ||
270 | string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; | ||
271 | |||
272 | m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir); | ||
273 | if (!Directory.Exists(scenedir)) | ||
274 | Directory.CreateDirectory(scenedir); | ||
275 | |||
276 | int newRevisionNum = GetMostRecentRevision(regionid)+1; | ||
277 | string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar; | ||
278 | |||
279 | m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir); | ||
280 | if (!Directory.Exists(revisiondir)) | ||
281 | Directory.CreateDirectory(revisiondir); | ||
282 | |||
283 | try { | ||
284 | Stopwatch x = new Stopwatch(); | ||
285 | x.Start(); | ||
286 | if (m_scenes.ContainsKey(regionid)) | ||
287 | { | ||
288 | m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir); | ||
289 | } | ||
290 | x.Stop(); | ||
291 | TimeToSave += x.ElapsedMilliseconds; | ||
292 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds); | ||
293 | m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave); | ||
294 | } | ||
295 | catch (Exception e) | ||
296 | { | ||
297 | m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | try { | ||
302 | // Finish by writing log message. | ||
303 | FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite); | ||
304 | StreamWriter sw = new StreamWriter(file); | ||
305 | sw.Write(logMessage); | ||
306 | sw.Close(); | ||
307 | } | ||
308 | catch (Exception e) | ||
309 | { | ||
310 | m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e); | ||
311 | return; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | #endregion Public Methods | ||
316 | } | ||
317 | } | ||