opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 OpenSimulator 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 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Threading;
33 using System.Xml;
34  
35 using log4net;
36 using OpenMetaverse;
37 using OpenSim.Framework;
38  
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Region.Framework.Scenes.Serialization;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Services.Interfaces;
43  
44 //using HyperGrid.Framework;
45 //using OpenSim.Region.Communications.Hypergrid;
46  
47 namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
48 {
49 public class HGAssetMapper
50 {
51 #region Fields
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53  
54 // This maps between inventory server urls and inventory server clients
55 // private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
56  
57 private Scene m_scene;
58 private string m_HomeURI;
59  
60 #endregion
61  
62 #region Constructor
63  
64 public HGAssetMapper(Scene scene, string homeURL)
65 {
66 m_scene = scene;
67 m_HomeURI = homeURL;
68 }
69  
70 #endregion
71  
72 #region Internal functions
73  
74 private AssetMetadata FetchMetadata(string url, UUID assetID)
75 {
76 if (string.IsNullOrEmpty(url))
77 return null;
78  
79 if (!url.EndsWith("/") && !url.EndsWith("="))
80 url = url + "/";
81  
82 AssetMetadata meta = m_scene.AssetService.GetMetadata(url + assetID.ToString());
83  
84 if (meta != null)
85 m_log.DebugFormat("[HG ASSET MAPPER]: Fetched metadata for asset {0} of type {1} from {2} ", assetID, meta.Type, url);
86 else
87 m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetched metadata for asset {0} from {1} ", assetID, url);
88  
89 return meta;
90 }
91  
92 private AssetBase FetchAsset(string url, UUID assetID)
93 {
94 // Test if it's already here
95 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
96 if (asset == null)
97 {
98 if (string.IsNullOrEmpty(url))
99 return null;
100  
101 if (!url.EndsWith("/") && !url.EndsWith("="))
102 url = url + "/";
103  
104 asset = m_scene.AssetService.Get(url + assetID.ToString());
105  
106 //if (asset != null)
107 // m_log.DebugFormat("[HG ASSET MAPPER]: Fetched asset {0} of type {1} from {2} ", assetID, asset.Metadata.Type, url);
108 //else
109 // m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetch asset {0} from {1} ", assetID, url);
110  
111 }
112  
113 return asset;
114 }
115  
116 public bool PostAsset(string url, AssetBase asset)
117 {
118 if (string.IsNullOrEmpty(url))
119 return false;
120  
121 if (asset != null)
122 {
123 if (!url.EndsWith("/") && !url.EndsWith("="))
124 url = url + "/";
125  
126 bool success = true;
127 // See long comment in AssetCache.AddAsset
128 if (!asset.Temporary || asset.Local)
129 {
130 // We need to copy the asset into a new asset, because
131 // we need to set its ID to be URL+UUID, so that the
132 // HGAssetService dispatches it to the remote grid.
133 // It's not pretty, but the best that can be done while
134 // not having a global naming infrastructure
135 AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID);
136 Copy(asset, asset1);
137 asset1.ID = url + asset.ID;
138  
139 AdjustIdentifiers(asset1.Metadata);
140 if (asset1.Metadata.Type == (sbyte)AssetType.Object)
141 asset1.Data = AdjustIdentifiers(asset.Data);
142 else
143 asset1.Data = asset.Data;
144  
145 string id = m_scene.AssetService.Store(asset1);
146 if (id == string.Empty)
147 {
148 m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID);
149 success = false;
150 }
151 else
152 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
153 }
154 return success;
155 }
156 else
157 m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache.");
158  
159 return false;
160 }
161  
162 private void Copy(AssetBase from, AssetBase to)
163 {
164 //to.Data = from.Data; // don't copy this, it's copied elsewhere
165 to.Description = from.Description;
166 to.FullID = from.FullID;
167 to.ID = from.ID;
168 to.Local = from.Local;
169 to.Name = from.Name;
170 to.Temporary = from.Temporary;
171 to.Type = from.Type;
172  
173 }
174  
175 private void AdjustIdentifiers(AssetMetadata meta)
176 {
177 if (!string.IsNullOrEmpty(meta.CreatorID))
178 {
179 UUID uuid = UUID.Zero;
180 UUID.TryParse(meta.CreatorID, out uuid);
181 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
182 if (creator != null)
183 meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
184 }
185 }
186  
187 protected byte[] AdjustIdentifiers(byte[] data)
188 {
189 string xml = Utils.BytesToString(data);
190 return Utils.StringToBytes(RewriteSOP(xml));
191 }
192  
193 protected string RewriteSOP(string xml)
194 {
195 XmlDocument doc = new XmlDocument();
196 doc.LoadXml(xml);
197 XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
198  
199 foreach (XmlNode sop in sops)
200 {
201 UserAccount creator = null;
202 bool hasCreatorData = false;
203 XmlNodeList nodes = sop.ChildNodes;
204 foreach (XmlNode node in nodes)
205 {
206 if (node.Name == "CreatorID")
207 {
208 UUID uuid = UUID.Zero;
209 UUID.TryParse(node.InnerText, out uuid);
210 creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
211 }
212 if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
213 hasCreatorData = true;
214  
215 //if (node.Name == "OwnerID")
216 //{
217 // UserAccount owner = GetUser(node.InnerText);
218 // if (owner != null)
219 // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
220 //}
221 }
222  
223 if (!hasCreatorData && creator != null)
224 {
225 XmlElement creatorData = doc.CreateElement("CreatorData");
226 creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
227 sop.AppendChild(creatorData);
228 }
229 }
230  
231 using (StringWriter wr = new StringWriter())
232 {
233 doc.Save(wr);
234 return wr.ToString();
235 }
236  
237 }
238  
239 // TODO: unused
240 // private void Dump(Dictionary<UUID, bool> lst)
241 // {
242 // m_log.Debug("XXX -------- UUID DUMP ------- XXX");
243 // foreach (KeyValuePair<UUID, bool> kvp in lst)
244 // m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
245 // m_log.Debug("XXX -------- UUID DUMP ------- XXX");
246 // }
247  
248 #endregion
249  
250  
251 #region Public interface
252  
253 public void Get(UUID assetID, UUID ownerID, string userAssetURL)
254 {
255 // Get the item from the remote asset server onto the local AssetService
256  
257 AssetMetadata meta = FetchMetadata(userAssetURL, assetID);
258 if (meta == null)
259 return;
260  
261 // The act of gathering UUIDs downloads some assets from the remote server
262 // but not all...
263 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
264 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
265 uuidGatherer.GatherAssetUuids(assetID, meta.Type, ids);
266 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count);
267 bool success = true;
268 foreach (UUID uuid in ids.Keys)
269 if (FetchAsset(userAssetURL, uuid) == null)
270 success = false;
271  
272 // maybe all pieces got here...
273 if (!success)
274 m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL);
275 else
276 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL);
277 }
278  
279  
280 public void Post(UUID assetID, UUID ownerID, string userAssetURL)
281 {
282 // Post the item from the local AssetCache onto the remote asset server
283 // and place an entry in m_assetMap
284  
285 m_log.Debug("[HG ASSET MAPPER]: Posting object " + assetID + " to asset server " + userAssetURL);
286 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
287 if (asset != null)
288 {
289 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
290 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
291 uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids);
292 bool success = false;
293 foreach (UUID uuid in ids.Keys)
294 {
295 asset = m_scene.AssetService.Get(uuid.ToString());
296 if (asset == null)
297 m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid);
298 else
299 success = PostAsset(userAssetURL, asset);
300 }
301  
302 // maybe all pieces got there...
303 if (!success)
304 m_log.DebugFormat("[HG ASSET MAPPER]: Problems posting item {0} to asset server {1}", assetID, userAssetURL);
305 else
306 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL);
307  
308 }
309 else
310 m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID);
311  
312 }
313  
314 #endregion
315  
316 }
317 }