opensim – Blame information for rev 1
?pathlinks?
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.Text; |
||
33 | using System.Xml; |
||
34 | using log4net; |
||
35 | using OpenMetaverse; |
||
36 | using OpenSim.Framework; |
||
37 | using OpenSim.Framework.Serialization; |
||
38 | using OpenSim.Services.Interfaces; |
||
39 | |||
40 | namespace OpenSim.Region.CoreModules.World.Archiver |
||
41 | { |
||
42 | /// <summary> |
||
43 | /// Dearchives assets |
||
44 | /// </summary> |
||
45 | public class AssetsDearchiver |
||
46 | { |
||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
||
48 | |||
49 | /// <summary> |
||
50 | /// Store for asset data we received before we get the metadata |
||
51 | /// </summary> |
||
52 | protected Dictionary<string, byte[]> m_assetDataAwaitingMetadata = new Dictionary<string, byte[]>(); |
||
53 | |||
54 | /// <summary> |
||
55 | /// Asset metadata. Is null if asset metadata isn't yet available. |
||
56 | /// </summary> |
||
57 | protected Dictionary<string, AssetMetadata> m_metadata; |
||
58 | |||
59 | /// <summary> |
||
60 | /// Cache to which dearchived assets will be added |
||
61 | /// </summary> |
||
62 | protected IAssetService m_cache; |
||
63 | |||
64 | public AssetsDearchiver(IAssetService cache) |
||
65 | { |
||
66 | m_cache = cache; |
||
67 | } |
||
68 | |||
69 | /// <summary> |
||
70 | /// Add asset data to the dearchiver |
||
71 | /// </summary> |
||
72 | /// <param name="assetFilename"></param> |
||
73 | /// <param name="data"></param> |
||
74 | public void AddAssetData(string assetFilename, byte[] data) |
||
75 | { |
||
76 | if (null == m_metadata) |
||
77 | { |
||
78 | m_assetDataAwaitingMetadata[assetFilename] = data; |
||
79 | } |
||
80 | else |
||
81 | { |
||
82 | ResolveAssetData(assetFilename, data); |
||
83 | } |
||
84 | } |
||
85 | |||
86 | /// <summary> |
||
87 | /// Add asset metadata xml |
||
88 | /// </summary> |
||
89 | /// <param name="xml"></param> |
||
90 | public void AddAssetMetadata(string xml) |
||
91 | { |
||
92 | m_metadata = new Dictionary<string, AssetMetadata>(); |
||
93 | |||
94 | StringReader sr = new StringReader(xml); |
||
95 | XmlTextReader reader = new XmlTextReader(sr); |
||
96 | |||
97 | reader.ReadStartElement("assets"); |
||
98 | reader.Read(); |
||
99 | |||
100 | while (reader.Name.Equals("asset")) |
||
101 | { |
||
102 | reader.Read(); |
||
103 | |||
104 | AssetMetadata metadata = new AssetMetadata(); |
||
105 | |||
106 | string filename = reader.ReadElementString("filename"); |
||
107 | m_log.DebugFormat("[DEARCHIVER]: Reading node {0}", filename); |
||
108 | |||
109 | metadata.Name = reader.ReadElementString("name"); |
||
110 | metadata.Description = reader.ReadElementString("description"); |
||
111 | metadata.AssetType = Convert.ToSByte(reader.ReadElementString("asset-type")); |
||
112 | |||
113 | m_metadata[filename] = metadata; |
||
114 | |||
115 | // Read asset end tag |
||
116 | reader.ReadEndElement(); |
||
117 | |||
118 | reader.Read(); |
||
119 | } |
||
120 | |||
121 | m_log.DebugFormat("[DEARCHIVER]: Resolved {0} items of asset metadata", m_metadata.Count); |
||
122 | |||
123 | ResolvePendingAssetData(); |
||
124 | } |
||
125 | |||
126 | /// <summary> |
||
127 | /// Resolve asset data that we collected before receiving the metadata |
||
128 | /// </summary> |
||
129 | protected void ResolvePendingAssetData() |
||
130 | { |
||
131 | foreach (string filename in m_assetDataAwaitingMetadata.Keys) |
||
132 | { |
||
133 | ResolveAssetData(filename, m_assetDataAwaitingMetadata[filename]); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | /// <summary> |
||
138 | /// Resolve a new piece of asset data against stored metadata |
||
139 | /// </summary> |
||
140 | /// <param name="assetFilename"></param> |
||
141 | /// <param name="data"></param> |
||
142 | protected void ResolveAssetData(string assetPath, byte[] data) |
||
143 | { |
||
144 | // Right now we're nastily obtaining the UUID from the filename |
||
145 | string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); |
||
146 | |||
147 | if (m_metadata.ContainsKey(filename)) |
||
148 | { |
||
149 | AssetMetadata metadata = m_metadata[filename]; |
||
150 | |||
151 | if (ArchiveConstants.ASSET_TYPE_TO_EXTENSION.ContainsKey(metadata.AssetType)) |
||
152 | { |
||
153 | string extension = ArchiveConstants.ASSET_TYPE_TO_EXTENSION[metadata.AssetType]; |
||
154 | filename = filename.Remove(filename.Length - extension.Length); |
||
155 | } |
||
156 | |||
157 | m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename); |
||
158 | |||
159 | AssetBase asset = new AssetBase(new UUID(filename), metadata.Name, metadata.AssetType, UUID.Zero.ToString()); |
||
160 | asset.Description = metadata.Description; |
||
161 | asset.Data = data; |
||
162 | |||
163 | m_cache.Store(asset); |
||
164 | } |
||
165 | else |
||
166 | { |
||
167 | m_log.ErrorFormat( |
||
168 | "[DEARCHIVER]: Tried to dearchive data with filename {0} without any corresponding metadata", |
||
169 | assetPath); |
||
170 | } |
||
171 | } |
||
172 | |||
173 | /// <summary> |
||
174 | /// Metadata for an asset |
||
175 | /// </summary> |
||
176 | protected struct AssetMetadata |
||
177 | { |
||
178 | public string Name; |
||
179 | public string Description; |
||
180 | public sbyte AssetType; |
||
181 | } |
||
182 | } |
||
183 | } |