package net.oni2.moddepot; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.UnknownHostException; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import net.oni2.moddepot.model.File; import net.oni2.moddepot.model.Node; import net.oni2.moddepot.model.NodeField_Body; import net.oni2.moddepot.model.NodeField_Upload; import net.oni2.moddepot.model.NodeMod; import net.oni2.moddepot.model.TaxonomyTerm; import net.oni2.moddepot.model.TaxonomyVocabulary; import net.oni2.httpfiledownloader.FileDownloader; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStreamException; import com.thoughtworks.xstream.io.xml.StaxDriver; /** * @author Christian Illy */ public class DepotManager { private static DepotManager instance = null; private HashMap taxonomyVocabulary = new HashMap(); private HashMap taxonomyTerms = new HashMap(); private HashMap nodes = new HashMap(); private HashMap> nodesByType = new HashMap>(); private HashMap files = new HashMap(); /** * Caching the vocab id for the package type vocabulary */ public int vocabId_type = -1; /** * Caching the vocab id for the platform vocabulary */ public int vocabId_platform = -1; /** * Caching the vocab id for the install method vocabulary */ public int vocabId_instmethod = -1; /** * @return Singleton instance */ public static DepotManager getInstance() { if (instance == null) instance = new DepotManager(); return instance; } /** * Update local Depot information cache * * @return Update successfully done? */ public boolean updateInformation() { try { java.io.File zipName = new java.io.File( System.getProperty("java.io.tmpdir"), "aei_jsoncache.zip"); FileDownloader fd = new FileDownloader(DepotConfig.depotUrl + "jsoncache/jsoncache.zip?ts=" + (new Date().getTime() / 1000), zipName); fd.start(); while (fd.getState() != FileDownloader.EState.FINISHED) { Thread.sleep(50); } String jsonVocab = null; String jsonTerms = null; String jsonNodes = null; String jsonFiles = null; ZipFile zf = null; try { zf = new ZipFile(zipName); for (Enumeration e = zf.entries(); e .hasMoreElements();) { ZipEntry ze = e.nextElement(); if (!ze.isDirectory()) { BufferedReader input = new BufferedReader( new InputStreamReader(zf.getInputStream(ze))); StringBuffer json = new StringBuffer(); char data[] = new char[1024]; int dataRead; while ((dataRead = input.read(data, 0, 1024)) != -1) { json.append(data, 0, dataRead); } if (ze.getName().toLowerCase().contains("vocabulary")) jsonVocab = json.toString(); if (ze.getName().toLowerCase().contains("terms")) jsonTerms = json.toString(); if (ze.getName().toLowerCase().contains("nodes")) jsonNodes = json.toString(); if (ze.getName().toLowerCase().contains("files")) jsonFiles = json.toString(); } } } finally { if (zf != null) zf.close(); zipName.delete(); } initVocabulary(new JSONArray(jsonVocab)); vocabId_type = getVocabulary(DepotConfig.vocabName_ModType) .getVid(); vocabId_platform = getVocabulary(DepotConfig.vocabName_Platform) .getVid(); vocabId_instmethod = getVocabulary( DepotConfig.vocabName_InstallType).getVid(); initTerms(new JSONArray(jsonTerms)); initFiles(new JSONArray(jsonFiles)); initNodes(new JSONArray(jsonNodes)); return true; } catch (JSONException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return false; } private void initFiles(JSONArray ja) throws JSONException { files = new HashMap(); JSONObject jo; for (int i = 0; i < ja.length(); i++) { jo = ja.getJSONObject(i); int fid = jo.getInt("fid"); File f = new File(jo); files.put(fid, f); } } private void initNodes(JSONArray ja) throws JSONException { nodes = new HashMap(); nodesByType = new HashMap>(); JSONObject jo; for (int i = 0; i < ja.length(); i++) { jo = ja.getJSONObject(i); int nid = jo.getInt("nid"); String type = jo.getString("type"); Node n = null; if (type.equalsIgnoreCase(DepotConfig.nodeType_Package)) n = new NodeMod(jo); else n = new Node(jo); if (n.getStatus() > 0) { nodes.put(nid, n); if (!nodesByType.containsKey(type)) nodesByType.put(type, new HashMap()); nodesByType.get(type).put(nid, n); } } } private void initTerms(JSONArray ja) throws JSONException { taxonomyTerms.clear(); JSONObject jo; for (int i = 0; i < ja.length(); i++) { jo = ja.getJSONObject(i); TaxonomyTerm tt = new TaxonomyTerm(jo); taxonomyTerms.put(tt.getTid(), tt); } } private void initVocabulary(JSONArray ja) throws JSONException { taxonomyVocabulary.clear(); JSONObject jo; for (int i = 0; i < ja.length(); i++) { jo = ja.getJSONObject(i); TaxonomyVocabulary tv = new TaxonomyVocabulary(jo); taxonomyVocabulary.put(tv.getVid(), tv); } } /** * @return Can we connect to the Depot? */ public boolean checkConnection() { HttpRequestBase httpQuery = null; try { DefaultHttpClient httpclient = new DefaultHttpClient(); httpQuery = new HttpHead(DepotConfig.depotUrl); HttpResponse response = httpclient.execute(httpQuery); int code = response.getStatusLine().getStatusCode(); return (code >= 200) && (code <= 299); } catch (UnknownHostException e) { } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (httpQuery != null) httpQuery.releaseConnection(); } return false; } private TaxonomyVocabulary getVocabulary(String name) { for (TaxonomyVocabulary v : taxonomyVocabulary.values()) { if (v.getName().equalsIgnoreCase(name)) return v; } return null; } /** * @param vocabId * Get all taxonomy terms of a given vocabulary * @return TaxTerms */ private Vector getTaxonomyTermsByVocabulary(int vocabId) { Vector res = new Vector(); for (TaxonomyTerm t : taxonomyTerms.values()) { if (t.getVid() == vocabId) res.add(t); } return res; } /** * @return All defined types */ public Vector getTypes() { return getTaxonomyTermsByVocabulary(vocabId_type); } /** * @param id * Get taxonomy term by given ID * @return TaxTerm */ public TaxonomyTerm getTaxonomyTerm(int id) { return taxonomyTerms.get(id); } /** * Get all nodes of given node type * * @param nodeType * Node type * @return Nodes of type nodeType */ public Vector getNodesByType(String nodeType) { if (nodesByType.get(nodeType) == null) return new Vector(); return new Vector(nodesByType.get(nodeType).values()); } /** * @return Mod-Nodes */ public Vector getModPackageNodes() { Vector result = new Vector(); String instMethName = DepotConfig.taxName_InstallType_Package; Vector files = getNodesByType(DepotConfig.nodeType_Package); for (Node n : files) { if (n instanceof NodeMod) { NodeMod nm = (NodeMod) n; if (nm.getInstallMethod().equalsIgnoreCase(instMethName)) { if (nm.getPackageNumber() >= 0) result.add(nm); else System.err.println("Node " + nm.getNid() + " does not have a package number!!!"); } } } return result; } /** * @param id * ID of file to get * @return the file */ public File getFile(int id) { return files.get(id); } private static XStream getXStream() { XStream xs = new XStream(new StaxDriver()); xs.alias("Depot", DepotManager.class); xs.alias("File", net.oni2.moddepot.model.File.class); xs.alias("Node", Node.class); xs.alias("NodeField_Body", NodeField_Body.class); xs.alias("NodeField_Upload", NodeField_Upload.class); xs.alias("NodeMod", NodeMod.class); xs.alias("TaxonomyTerm", TaxonomyTerm.class); xs.alias("TaxonomyVocabulary", TaxonomyVocabulary.class); return xs; } /** * Save Depot cache instance to file * * @param cacheFile * File to save to */ public void saveToCacheFile(java.io.File cacheFile) { try { FileOutputStream fos = new FileOutputStream(cacheFile); XStream xs = getXStream(); xs.toXML(this, fos); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * Load cache from file * * @param cacheFile * File to load */ public static void loadFromCacheFile(java.io.File cacheFile) { try { FileInputStream fis = new FileInputStream(cacheFile); XStream xs = getXStream(); Object obj = xs.fromXML(fis); fis.close(); if (obj instanceof DepotManager) instance = (DepotManager) obj; } catch (XStreamException e) { } catch (FileNotFoundException e) { } catch (IOException e) { } } }