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

Last change on this file since 597 was 592, checked in by alloc, 12 years ago

AEI - Current state

File size: 11.5 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.network.DrupalJSONQuery;
21
22import org.json.JSONArray;
23import org.json.JSONException;
24import org.json.JSONObject;
25
26import com.thoughtworks.xstream.XStream;
27import com.thoughtworks.xstream.io.xml.StaxDriver;
28
29/**
30 * @author Christian Illy
31 */
32public 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.getNodeType_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(
199 DepotConfig.getVocabularyName_ModType()).getVid();
200 vocabId_platform = getVocabulary(
201 DepotConfig.getVocabularyName_Platform()).getVid();
202 vocabId_instmethod = getVocabulary(
203 DepotConfig.getVocabularyName_InstallType()).getVid();
204 } catch (JSONException e) {
205 e.printStackTrace();
206 } catch (Exception e) {
207 System.err.println(e.getMessage());
208 e.printStackTrace();
209 }
210 }
211
212 /**
213 * @return All TaxVocabs
214 */
215 public Vector<TaxonomyVocabulary> getVocabulary() {
216 return new Vector<TaxonomyVocabulary>(taxonomyVocabulary.values());
217 }
218
219 /**
220 * @param id
221 * Get taxonomy vocabulary by given ID
222 * @return TaxVocab
223 */
224 public TaxonomyVocabulary getVocabulary(int id) {
225 return taxonomyVocabulary.get(id);
226 }
227
228 /**
229 * @param name
230 * Get taxonomy vocabulary by given name
231 * @return TaxVocab
232 */
233 public TaxonomyVocabulary getVocabulary(String name) {
234 for (TaxonomyVocabulary v : taxonomyVocabulary.values()) {
235 if (v.getName().equalsIgnoreCase(name))
236 return v;
237 }
238 return null;
239 }
240
241 /**
242 * @param vocabId
243 * Get all taxonomy terms of a given vocabulary
244 * @return TaxTerms
245 */
246 public Vector<TaxonomyTerm> getTaxonomyTermsByVocabulary(int vocabId) {
247 Vector<TaxonomyTerm> res = new Vector<TaxonomyTerm>();
248 for (TaxonomyTerm t : taxonomyTerms.values()) {
249 if (t.getVid() == vocabId)
250 res.add(t);
251 }
252 return res;
253 }
254
255 /**
256 * @param id
257 * Get taxonomy term by given ID
258 * @return TaxTerm
259 */
260 public TaxonomyTerm getTaxonomyTerm(int id) {
261 return taxonomyTerms.get(id);
262 }
263
264 /**
265 * @param name
266 * Get taxonomy term by given name
267 * @return TaxTerm
268 */
269 public TaxonomyTerm getTaxonomyTerm(String name) {
270 for (TaxonomyTerm t : taxonomyTerms.values()) {
271 if (t.getName().equalsIgnoreCase(name))
272 return t;
273 }
274 return null;
275 }
276
277 /**
278 * Get all nodes of given node type
279 *
280 * @param nodeType
281 * Node type
282 * @return Nodes of type nodeType
283 */
284 public Vector<Node> getNodesByType(String nodeType) {
285 return new Vector<Node>(nodesByType.get(nodeType).values());
286 }
287
288 /**
289 * @return Mod-Nodes
290 */
291 public Vector<NodeMod> getModPackageNodes() {
292 Vector<NodeMod> result = new Vector<NodeMod>();
293 TaxonomyTerm tt = getTaxonomyTerm(DepotConfig.getTaxonomyName_InstallType_Package());
294 if (tt == null)
295 return result;
296
297 int packageterm_id = tt.getTid();
298
299 Vector<Node> files = getNodesByType(DepotConfig.getNodeType_Mod());
300 for (Node n : files) {
301 if (n instanceof NodeMod) {
302 NodeMod nm = (NodeMod) n;
303 if (nm.getTaxonomyTerms().get(vocabId_instmethod)
304 .contains(packageterm_id))
305 result.add(nm);
306 }
307 }
308 return result;
309 }
310
311 /**
312 * @param node
313 * Node to check validity on
314 * @param platform
315 * Platform to check against
316 * @return True if valid on platform
317 */
318 public boolean isModValidOnPlatform(NodeMod node, Settings.Platform platform) {
319 int termId = node.getTaxonomyTerms().get(vocabId_platform).iterator()
320 .next();
321 String validPlatform = getTaxonomyTerm(termId).getName();
322 if (validPlatform.equalsIgnoreCase(DepotConfig.getTaxonomyName_Platform_Both()))
323 return true;
324
325 if ((platform == Platform.WIN) || (platform == Platform.LINUX))
326 return validPlatform.equalsIgnoreCase(DepotConfig.getTaxonomyName_Platform_Win());
327 else if (platform == Platform.MACOS)
328 return validPlatform.equalsIgnoreCase(DepotConfig.getTaxonomyName_Platform_Mac());
329 else
330 return false;
331 }
332
333 /**
334 * Checks if the given mod-node is of the given mod-type(s)
335 *
336 * @param node
337 * Node to check
338 * @param type
339 * Type(s) to check
340 * @param or
341 * If false check if all given types are included in node. If
342 * true checks if either of the given types is included.
343 * @return True if of given type(s)
344 */
345 public boolean isModOfType(NodeMod node, HashSet<Integer> type, boolean or) {
346 boolean matching = true;
347 if (or)
348 matching = false;
349
350 for (int t : type) {
351 if (or)
352 matching |= node.getTaxonomyTerms().get(vocabId_type)
353 .contains(t);
354 else
355 matching &= node.getTaxonomyTerms().get(vocabId_type)
356 .contains(t);
357 }
358 return matching;
359 }
360
361 /**
362 * Print stats about nodes and files
363 */
364 public void printStats() {
365 System.out.println("Nodes by type:");
366 for (String t : nodesByType.keySet()) {
367 System.out.println(" " + t + ": " + nodesByType.get(t).size());
368 }
369
370 System.out.println("Files: " + files.size());
371 }
372
373 private XStream getXStream() {
374 XStream xs = new XStream(new StaxDriver());
375 xs.alias("Depot", DepotManager.class);
376 xs.alias("File", net.oni2.aeinstaller.backend.depot.model.File.class);
377 xs.alias("Node", Node.class);
378 xs.alias("NodeField_Body", NodeField_Body.class);
379 xs.alias("NodeField_Upload", NodeField_Upload.class);
380 xs.alias("NodeMod", NodeMod.class);
381 xs.alias("TaxonomyTerm", TaxonomyTerm.class);
382 xs.alias("TaxonomyVocabulary", TaxonomyVocabulary.class);
383 return xs;
384 }
385
386 /**
387 * Save Depot cache instance to file
388 *
389 * @param f
390 * File to write to
391 */
392 public void saveToFile(java.io.File f) {
393 try {
394 FileOutputStream fos = new FileOutputStream(f);
395 XStream xs = getXStream();
396 xs.toXML(this, fos);
397 fos.close();
398 } catch (FileNotFoundException e) {
399 e.printStackTrace();
400 } catch (IOException e) {
401 e.printStackTrace();
402 }
403 }
404
405 /**
406 * Load Depot cache instance from file
407 *
408 * @param f
409 * File to read from
410 */
411 public void loadFromFile(java.io.File f) {
412 try {
413 FileInputStream fis = new FileInputStream(f);
414 XStream xs = getXStream();
415 Object obj = xs.fromXML(fis);
416 if (obj instanceof DepotManager)
417 instance = (DepotManager) obj;
418 fis.close();
419 } catch (FileNotFoundException e) {
420 } catch (IOException e) {
421 }
422 }
423}
Note: See TracBrowser for help on using the repository browser.