package net.oni2.aeinstaller.backend.packages; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.TreeSet; import java.util.Vector; import net.oni2.aeinstaller.backend.Paths; import net.oni2.moddepot.DepotManager; import net.oni2.moddepot.model.NodeMod; import net.oni2.moddepot.model.TaxonomyTerm; import net.oni2.aeinstaller.backend.oni.management.Installer; import net.oni2.aeinstaller.backend.oni.management.ToolsManager; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.StaxDriver; /** * @author Christian Illy */ public class PackageManager { private static PackageManager instance = new PackageManager(); private HashMap types = new HashMap(); private HashMap mods = new HashMap(); private HashMap tools = new HashMap(); private Vector currentlyInstalled = new Vector(); /** * @param f * Mod selection file * @return Mod selection */ @SuppressWarnings("unchecked") public Vector loadModSelection(File f) { Vector res = new Vector(); try { if (f.exists()) { FileInputStream fis = new FileInputStream(f); XStream xs = new XStream(new StaxDriver()); Object obj = xs.fromXML(fis); if (obj instanceof Vector) res = (Vector) obj; fis.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return res; } /** * @param f * Mod selection file * @param mods * Selected mods */ public void saveModSelection(File f, TreeSet mods) { try { Vector installed = new Vector(); for (Package m : mods) { installed.add(m.getPackageNumber()); } FileOutputStream fos = new FileOutputStream(f); XStream xs = new XStream(new StaxDriver()); xs.toXML(installed, fos); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * First initialization of ModManager */ public void init() { types = new HashMap(); mods = new HashMap(); Type localType = new Type("-Local-"); types.put("-Local-", localType); for (TaxonomyTerm tt : DepotManager.getInstance().getTypes()) { types.put(tt.getName(), new Type(tt.getName())); } HashMap modFolders = new HashMap(); if (Paths.getModsPath().exists()) { for (File f : Paths.getModsPath().listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } })) { Package m = new Package(f); modFolders.put(m.getPackageNumber(), m); } } for (NodeMod nm : DepotManager.getInstance().getModPackageNodes()) { if (nm.getUploads().size() == 1) { Package m = new Package(nm); if (nm.isTool()) tools.put(m.getPackageNumber(), m); else mods.put(m.getPackageNumber(), m); modFolders.remove(m.getPackageNumber()); } } for (Package m : modFolders.values()) { if (!m.isCorePackage()) { localType.addEntry(m); m.getTypes().add(localType); } if (m.isTool()) tools.put(m.getPackageNumber(), m); else mods.put(m.getPackageNumber(), m); } updateInstalledMods(); } /** * Update the list of currently installed mods */ public void updateInstalledMods() { currentlyInstalled = Installer.getInstalledMods(); if (currentlyInstalled == null) currentlyInstalled = new Vector(); } /** * @return Singleton instance */ public static PackageManager getInstance() { return instance; } Type getTypeByName(String name) { return types.get(name); } /** * @return Collection of types which do have mods associated */ public Collection getTypesWithContent() { Vector res = new Vector(); for (Type t : types.values()) { if (t.getEntries().size() > 0) res.add(t); } return res; } /** * @return Collection of mods valid on this platform and not core package */ public Collection getModsValidAndNotCore() { Vector res = new Vector(); for (Package m : mods.values()) if (m.isValidOnPlatform() && !m.isCorePackage()) res.add(m); return res; } /** * @return Mods which are always installed and valid on this platform */ public TreeSet getCoreMods() { TreeSet res = new TreeSet(); for (Package m : mods.values()) { if (m.isValidOnPlatform() && m.isCorePackage()) res.add(m); } return res; } /** * @return Mods which are already locally available */ public TreeSet getLocalAvailableMods() { TreeSet res = new TreeSet(); for (Package m : mods.values()) { if (m.isLocalAvailable()) res.add(m); } return res; } /** * @return Mods which can be updated */ public TreeSet getUpdatableMods() { TreeSet res = new TreeSet(); for (Package m : getLocalAvailableMods()) { if (m.isNewerAvailable()) res.add(m); } return res; } /** * @return Collection of tools valid on this platform and not core */ public Collection getTools() { Vector res = new Vector(); for (Package m : tools.values()) if (m.isValidOnPlatform() && !m.isCorePackage()) res.add(m); return res; } /** * @return Tools which are always installed and valid on this platform */ public TreeSet getCoreTools() { TreeSet res = new TreeSet(); for (Package m : tools.values()) { if (m.isValidOnPlatform() && m.isCorePackage()) res.add(m); } return res; } /** * @return Tools which are already locally available */ public TreeSet getLocalAvailableTools() { TreeSet res = new TreeSet(); for (Package m : tools.values()) { if (m.isLocalAvailable()) res.add(m); } return res; } /** * @return Tools which can be updated */ public TreeSet getUpdatableTools() { TreeSet res = new TreeSet(); for (Package m : getLocalAvailableTools()) { if (m.isNewerAvailable()) res.add(m); } return res; } /** * @return Currently installed tools */ public TreeSet getInstalledTools() { TreeSet res = new TreeSet(); for (int n : ToolsManager.getInstalledTools()) { res.add(getPackageByNumber(n)); } return res; } /** * Get a mod/tool by its package number * * @param number * Package number * @return Mod/tool or null */ private Package getPackageByNumber(int number) { if (mods.containsKey(number)) return mods.get(number); if (tools.containsKey(number)) return tools.get(number); return null; } /** * Check for unresolved dependencies within the given mods * * @param mods * Mods to check * @return Unmet dependencies */ public HashMap> checkDependencies( TreeSet mods) { HashMap> res = new HashMap>(); for (Package m : mods) { for (int depNum : m.getDependencies()) { Package other = getPackageByNumber(depNum); if (!mods.contains(other)) { if (!res.containsKey(m)) res.put(m, new HashSet()); res.get(m).add(other); } } } return res; } /** * Check for incompabitilites between given mods * * @param mods * Mods to check * @return Incompatible mods */ public HashMap> checkIncompabitilites( TreeSet mods) { HashMap> res = new HashMap>(); for (Package m : mods) { for (int confNum : m.getIncompabitilities()) { Package other = getPackageByNumber(confNum); if (mods.contains(other)) { if (!res.containsKey(m)) res.put(m, new HashSet()); res.get(m).add(other); } } } return res; } /** * @param m * Mod to check * @return Is mod installed? */ boolean isModInstalled(Package m) { return currentlyInstalled.contains(m.getPackageNumber()); } }