ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/AE/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java
Revision: 591
Committed: Fri Dec 28 20:12:33 2012 UTC (12 years, 11 months ago) by alloc
Content type: text/x-java
File size: 11613 byte(s)
Log Message:
AEI2-import

File Contents

# Content
1 package net.oni2.aeinstaller.backend.depot;
2
3 import java.io.FileInputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.Vector;
10
11 import net.oni2.aeinstaller.backend.Settings;
12 import net.oni2.aeinstaller.backend.Settings.Platform;
13 import net.oni2.aeinstaller.backend.depot.model.File;
14 import net.oni2.aeinstaller.backend.depot.model.Node;
15 import net.oni2.aeinstaller.backend.depot.model.NodeField_Body;
16 import net.oni2.aeinstaller.backend.depot.model.NodeField_Upload;
17 import net.oni2.aeinstaller.backend.depot.model.NodeMod;
18 import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
19 import net.oni2.aeinstaller.backend.depot.model.TaxonomyVocabulary;
20 import net.oni2.aeinstaller.backend.network.DrupalJSONQuery;
21
22 import org.json.JSONArray;
23 import org.json.JSONException;
24 import org.json.JSONObject;
25
26 import com.thoughtworks.xstream.XStream;
27 import com.thoughtworks.xstream.io.xml.StaxDriver;
28
29 /**
30 * @author Christian Illy
31 */
32 public class DepotManager {
33 private static DepotManager instance = new DepotManager();
34
35 private HashMap<Integer, TaxonomyVocabulary> taxonomyVocabulary = new HashMap<Integer, TaxonomyVocabulary>();
36 private HashMap<Integer, TaxonomyTerm> taxonomyTerms = new HashMap<Integer, TaxonomyTerm>();
37
38 private HashMap<Integer, Node> nodes = new HashMap<Integer, Node>();
39 private HashMap<String, HashMap<Integer, Node>> nodesByType = new HashMap<String, HashMap<Integer, Node>>();
40
41 private HashMap<Integer, File> files = new HashMap<Integer, File>();
42
43 private int vocabId_type = -1;
44 private int vocabId_platform = -1;
45 private int vocabId_instmethod = -1;
46
47 /**
48 * @return Singleton instance
49 */
50 public static DepotManager getInstance() {
51 return instance;
52 }
53
54 /**
55 * Update local Depot information cache
56 *
57 * @param forceRefreshAll
58 * Force refreshing all data, even if it seems to be cached
59 * @param listener
60 * Listener for update status
61 */
62 public void updateInformation(boolean forceRefreshAll,
63 DepotCacheUpdateProgressListener listener) {
64 taxonomyTerms.clear();
65 taxonomyVocabulary.clear();
66
67 HashMap<Integer, Node> oldNodes = null;
68 HashMap<Integer, File> oldFiles = null;
69
70 if (forceRefreshAll) {
71 oldNodes = new HashMap<Integer, Node>();
72 oldFiles = new HashMap<Integer, File>();
73 } else {
74 oldNodes = nodes;
75 oldFiles = files;
76 }
77
78 nodes = new HashMap<Integer, Node>();
79 nodesByType = new HashMap<String, HashMap<Integer, Node>>();
80 files = new HashMap<Integer, File>();
81
82 try {
83 JSONArray ja;
84 JSONObject jo;
85 int page;
86
87 // Get taxonomy vocabulary
88 listener.cacheUpdateProgress("Updating taxonomy vocabulary", 0, 100);
89 page = 0;
90 do {
91 ja = DrupalJSONQuery.getIndex("taxonomy_vocabulary", page);
92 for (int i = 0; i < ja.length(); i++) {
93 jo = ja.getJSONObject(i);
94 TaxonomyVocabulary tv = new TaxonomyVocabulary(jo);
95 taxonomyVocabulary.put(tv.getVid(), tv);
96 }
97 page++;
98 } while (ja.length() > 0);
99
100 // Get taxonomy terms
101 listener.cacheUpdateProgress("Updating taxonomy terms", 0, 100);
102 page = 0;
103 do {
104 ja = DrupalJSONQuery.getIndex("taxonomy_term", page);
105 for (int i = 0; i < ja.length(); i++) {
106 jo = ja.getJSONObject(i);
107 TaxonomyTerm tt = new TaxonomyTerm(jo);
108 taxonomyTerms.put(tt.getTid(), tt);
109 }
110 page++;
111 } while (ja.length() > 0);
112
113 // Check nodes for new information
114 listener.cacheUpdateProgress("Checking for new/updated nodes", 1,
115 100);
116 HashSet<Integer> nodesToUpdate = new HashSet<Integer>();
117 page = 0;
118 do {
119 ja = DrupalJSONQuery.getIndex("node", page);
120 for (int i = 0; i < ja.length(); i++) {
121 jo = ja.getJSONObject(i);
122 int nid = jo.getInt("nid");
123 long changedRemote = jo.getLong("changed");
124 if (oldNodes.containsKey(nid)) {
125 if (changedRemote > oldNodes.get(nid).getChanged())
126 nodesToUpdate.add(nid);
127 else {
128 Node n = oldNodes.get(nid);
129 nodes.put(nid, n);
130 if (!nodesByType.containsKey(n.getType()))
131 nodesByType.put(n.getType(),
132 new HashMap<Integer, Node>());
133 nodesByType.get(n.getType()).put(nid, n);
134 }
135 } else {
136 nodesToUpdate.add(nid);
137 }
138 }
139 page++;
140 } while (ja.length() > 0);
141
142 // Check files for new stuff
143 listener.cacheUpdateProgress("Checking for new/updated files", 2,
144 100);
145 HashSet<Integer> filesToUpdate = new HashSet<Integer>();
146 page = 0;
147 do {
148 ja = DrupalJSONQuery.getIndex("file", page);
149 for (int i = 0; i < ja.length(); i++) {
150 jo = ja.getJSONObject(i);
151 int fid = jo.getInt("fid");
152 long changedRemote = jo.getLong("timestamp");
153 if (oldFiles.containsKey(fid)) {
154 if (changedRemote > oldFiles.get(fid).getTimestamp())
155 filesToUpdate.add(fid);
156 else
157 files.put(fid, oldFiles.get(fid));
158 } else {
159 filesToUpdate.add(fid);
160 }
161 }
162 page++;
163 } while (ja.length() > 0);
164
165 int total = nodesToUpdate.size() + filesToUpdate.size() + 3;
166 int step = 3;
167 // Update nodes with new information
168 for (int nid : nodesToUpdate) {
169 listener.cacheUpdateProgress("Updating nodes", step++, total);
170
171 ja = DrupalJSONQuery.getItem("node", nid, "");
172 jo = ja.getJSONObject(0);
173 String type = jo.getString("type");
174
175 Node n = null;
176 if (type.equalsIgnoreCase(DepotConfig.NODETYPE_MOD))
177 n = new NodeMod(jo);
178 else
179 n = new Node(jo);
180
181 nodes.put(nid, n);
182 if (!nodesByType.containsKey(type))
183 nodesByType.put(type, new HashMap<Integer, Node>());
184 nodesByType.get(type).put(nid, n);
185 }
186
187 // Update new files
188 for (int fid : filesToUpdate) {
189 listener.cacheUpdateProgress("Updating files", step++, total);
190
191 ja = DrupalJSONQuery.getItem("file", fid, "&file_contents=0");
192 jo = ja.getJSONObject(0);
193
194 File f = new File(jo);
195 files.put(fid, f);
196 }
197
198 vocabId_type = getVocabulary(DepotConfig.MODTYPE_VOCAB).getVid();
199 vocabId_platform = getVocabulary(DepotConfig.PLATFORM_VOCAB)
200 .getVid();
201 vocabId_instmethod = getVocabulary(DepotConfig.INSTALLTYPE_VOCAB)
202 .getVid();
203 } catch (JSONException e) {
204 e.printStackTrace();
205 } catch (Exception e) {
206 System.err.println(e.getMessage());
207 e.printStackTrace();
208 }
209 }
210
211 /**
212 * @return All TaxVocabs
213 */
214 public Vector<TaxonomyVocabulary> getVocabulary() {
215 return new Vector<TaxonomyVocabulary>(taxonomyVocabulary.values());
216 }
217
218 /**
219 * @param id
220 * Get taxonomy vocabulary by given ID
221 * @return TaxVocab
222 */
223 public TaxonomyVocabulary getVocabulary(int id) {
224 return taxonomyVocabulary.get(id);
225 }
226
227 /**
228 * @param name
229 * Get taxonomy vocabulary by given name
230 * @return TaxVocab
231 */
232 public TaxonomyVocabulary getVocabulary(String name) {
233 for (TaxonomyVocabulary v : taxonomyVocabulary.values()) {
234 if (v.getName().equalsIgnoreCase(name))
235 return v;
236 }
237 return null;
238 }
239
240 /**
241 * @param vocabId
242 * Get all taxonomy terms of a given vocabulary
243 * @return TaxTerms
244 */
245 public Vector<TaxonomyTerm> getTaxonomyTermsByVocabulary(int vocabId) {
246 Vector<TaxonomyTerm> res = new Vector<TaxonomyTerm>();
247 for (TaxonomyTerm t : taxonomyTerms.values()) {
248 if (t.getVid() == vocabId)
249 res.add(t);
250 }
251 return res;
252 }
253
254 /**
255 * @param id
256 * Get taxonomy term by given ID
257 * @return TaxTerm
258 */
259 public TaxonomyTerm getTaxonomyTerm(int id) {
260 return taxonomyTerms.get(id);
261 }
262
263 /**
264 * @param name
265 * Get taxonomy term by given name
266 * @return TaxTerm
267 */
268 public TaxonomyTerm getTaxonomyTerm(String name) {
269 for (TaxonomyTerm t : taxonomyTerms.values()) {
270 if (t.getName().equalsIgnoreCase(name))
271 return t;
272 }
273 return null;
274 }
275
276 /**
277 * Get all nodes of given node type
278 *
279 * @param nodeType
280 * Node type
281 * @return Nodes of type nodeType
282 */
283 public Vector<Node> getNodesByType(String nodeType) {
284 return new Vector<Node>(nodesByType.get(nodeType).values());
285 }
286
287 /**
288 * @return Mod-Nodes
289 */
290 public Vector<NodeMod> getModPackageNodes() {
291 int packageterm_id = getTaxonomyTerm(DepotConfig.INSTALLTYPE_PACKAGE)
292 .getTid();
293
294 Vector<Node> files = getNodesByType(DepotConfig.NODETYPE_MOD);
295 Vector<NodeMod> result = new Vector<NodeMod>();
296 for (Node n : files) {
297 if (n instanceof NodeMod) {
298 NodeMod nm = (NodeMod) n;
299 if (nm.getTaxonomyTerms().get(vocabId_instmethod)
300 .contains(packageterm_id))
301 result.add(nm);
302 }
303 }
304 return result;
305 }
306
307 /**
308 * @param node
309 * Node to check validity on
310 * @param platform
311 * Platform to check against
312 * @return True if valid on platform
313 */
314 public boolean isModValidOnPlatform(NodeMod node, Settings.Platform platform) {
315 int termId = node.getTaxonomyTerms().get(vocabId_platform).iterator()
316 .next();
317 String validPlatform = getTaxonomyTerm(termId).getName();
318 if (validPlatform.equalsIgnoreCase(DepotConfig.PLATFORM_BOTH))
319 return true;
320
321 if ((platform == Platform.WIN) || (platform == Platform.LINUX))
322 return validPlatform.equalsIgnoreCase(DepotConfig.PLATFORM_WIN);
323 else if (platform == Platform.MACOS)
324 return validPlatform.equalsIgnoreCase(DepotConfig.PLATFORM_MAC);
325 else
326 return false;
327 }
328
329 /**
330 * Checks if the given mod-node is of the given mod-type(s)
331 *
332 * @param node
333 * Node to check
334 * @param type
335 * Type(s) to check
336 * @param or
337 * If false check if all given types are included in node. If
338 * true checks if either of the given types is included.
339 * @return True if of given type(s)
340 */
341 public boolean isModOfType(NodeMod node, HashSet<Integer> type, boolean or) {
342 boolean matching = true;
343 if (or)
344 matching = false;
345
346 for (int t : type) {
347 if (or)
348 matching |= node.getTaxonomyTerms().get(vocabId_type)
349 .contains(t);
350 else
351 matching &= node.getTaxonomyTerms().get(vocabId_type)
352 .contains(t);
353 }
354 return matching;
355 }
356
357 /**
358 * Print stats about nodes and files
359 */
360 public void printStats() {
361 System.out.println("Nodes by type:");
362 for (String t : nodesByType.keySet()) {
363 System.out.println(" " + t + ": " + nodesByType.get(t).size());
364 }
365
366 System.out.println("Files: " + files.size());
367 }
368
369 private XStream getXStream() {
370 XStream xs = new XStream(new StaxDriver());
371 xs.alias("Depot", DepotManager.class);
372 xs.alias("File", net.oni2.aeinstaller.backend.depot.model.File.class);
373 xs.alias("Node", Node.class);
374 xs.alias("NodeField_Body", NodeField_Body.class);
375 xs.alias("NodeField_Upload", NodeField_Upload.class);
376 xs.alias("NodeMod", NodeMod.class);
377 xs.alias("TaxonomyTerm", TaxonomyTerm.class);
378 xs.alias("TaxonomyVocabulary", TaxonomyVocabulary.class);
379 return xs;
380 }
381
382 /**
383 * Save Depot cache instance to file
384 *
385 * @param f
386 * File to write to
387 */
388 public void saveToFile(java.io.File f) {
389 try {
390 FileOutputStream fos = new FileOutputStream(f);
391 XStream xs = getXStream();
392 xs.toXML(this, fos);
393 fos.close();
394 } catch (FileNotFoundException e) {
395 e.printStackTrace();
396 } catch (IOException e) {
397 e.printStackTrace();
398 }
399 }
400
401 /**
402 * Load Depot cache instance from file
403 *
404 * @param f
405 * File to read from
406 */
407 public void loadFromFile(java.io.File f) {
408 try {
409 FileInputStream fis = new FileInputStream(f);
410 XStream xs = getXStream();
411 Object obj = xs.fromXML(fis);
412 if (obj instanceof DepotManager)
413 instance = (DepotManager) obj;
414 fis.close();
415 } catch (FileNotFoundException e) {
416 } catch (IOException e) {
417 }
418 }
419 }