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

Last change on this file since 610 was 605, checked in by alloc, 12 years ago

AEI2:

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