source: AE/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java@ 601

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