package net.oni2.aeinstaller.backend.mods; 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.TreeMap; import java.util.TreeSet; import java.util.Vector; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.StaxDriver; import net.oni2.aeinstaller.backend.Paths; import net.oni2.aeinstaller.backend.depot.DepotManager; import net.oni2.aeinstaller.backend.depot.model.NodeMod; import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm; import net.oni2.aeinstaller.backend.oni.Installer; /** * @author Christian Illy */ public class ModManager { private static ModManager instance = new ModManager(); 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 (Mod 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-", null); types.put("-Local-", localType); for (TaxonomyTerm tt : DepotManager.getInstance().getTypes()) { types.put(tt.getName(), new Type(tt.getName(), tt)); } 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(); } })) { Mod m = new Mod(f); modFolders.put(m.getPackageNumber(), m); } } for (NodeMod nm : DepotManager.getInstance().getModPackageNodes()) { if (nm.getUploads().size() == 1) { Mod m = new Mod(nm); if (nm.isTool()) tools.put(m.getPackageNumber(), m); else mods.put(m.getPackageNumber(), m); modFolders.remove(m.getPackageNumber()); } } for (Mod m : modFolders.values()) { if (!m.isMandatoryMod()) { 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 ModManager 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 mandatory */ public Collection getModsValidAndNotMandatory() { Vector res = new Vector(); for (Mod m : mods.values()) if (m.isValidOnPlatform() && !m.isMandatoryMod()) res.add(m); return res; } /** * @return Mods which are always installed and valid on this platform */ public TreeSet getMandatoryMods() { TreeSet res = new TreeSet(); for (Mod m : mods.values()) { if (m.isValidOnPlatform() && m.isMandatoryMod()) res.add(m); } return res; } /** * @return Mods which are already locally available */ public TreeSet getLocalAvailableMods() { TreeSet res = new TreeSet(); for (Mod 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 (Mod m : getLocalAvailableMods()) { if (m.isNewerAvailable()) res.add(m); } return res; } /** * @return Collection of tools valid on this platform and not mandatory */ public TreeMap getTools() { TreeMap res = new TreeMap(); for (Mod m : tools.values()) if (m.isValidOnPlatform() && !m.isMandatoryMod()) res.put(m.getName(), m); return res; } /** * @return Tools which are always installed and valid on this platform */ public TreeSet getMandatoryTools() { TreeSet res = new TreeSet(); for (Mod m : tools.values()) { if (m.isValidOnPlatform() && m.isMandatoryMod()) res.add(m); } return res; } /** * @return Tools which are already locally available */ public TreeSet getLocalAvailableTools() { TreeSet res = new TreeSet(); for (Mod 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 (Mod m : getLocalAvailableTools()) { if (m.isNewerAvailable()) res.add(m); } return res; } /** * @return Currently installed tools */ public TreeSet getInstalledTools() { TreeSet res = new TreeSet(); for (int n : Installer.getInstalledTools()) { res.add(getModByNumber(n)); } return res; } /** * Get a mod/tool by its package number * * @param number * Package number * @return Mod/tool or null */ private Mod getModByNumber(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) { // TODO: Verify functionality (checkDependencies) HashMap> res = new HashMap>(); for (Mod m : mods) { for (int depNum : m.getDependencies()) { Mod other = getModByNumber(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) { // TODO: Verify functionality (checkIncompatibilities) HashMap> res = new HashMap>(); for (Mod m : mods) { for (int confNum : m.getIncompabitilities()) { Mod other = getModByNumber(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(Mod m) { return currentlyInstalled.contains(m.getPackageNumber()); } }