package org.intellimate.izou.identification; import org.apache.commons.cli.MissingArgumentException; import org.intellimate.izou.addon.AddOnModel; import org.intellimate.izou.main.Main; import org.intellimate.izou.util.IdentifiableSet; import org.intellimate.izou.util.IzouModule; import ro.fortsoft.pf4j.IzouPluginClassLoader; import ro.fortsoft.pf4j.PluginDescriptor; import java.util.Optional; import java.util.function.Supplier; /** * The AddOnInformationManager is a class that gives access to all kinds of information about registered addOns in Izou. * For example, any addOn can find out the names of all other registered addOns through this class. */ public class AddOnInformationManager extends IzouModule { private final IdentifiableSet<AddOnInformation> addOnInformations; private final IdentifiableSet<AddOnModel> addOns; /** * Creates a new instance of AddOnInformationManager. */ public AddOnInformationManager(Main main) { super(main); addOnInformations = new IdentifiableSet<>(); addOns = new IdentifiableSet<>(); IdentificationManagerImpl identificationManager = (IdentificationManagerImpl) IdentificationManagerM.getInstance(); identificationManager.setAddOnInformationManager(this); } /** * Registers an addOn with the AddOnInformationManager by extracting all relevant information from the addOn and * adding it the the sets. * * Once an addOn is registered, its public data can be viewed by any other addOn through the context. * * @param addOn The addOn to register with the AddOnInformationManager. */ public void registerAddOn(AddOnModel addOn) { PluginDescriptor descriptor = addOn.getPlugin().getDescriptor(); String name = descriptor.getTitle(); String version = descriptor.getVersion().toString(); String provider = descriptor.getProvider(); String id = descriptor.getPluginId(); String sdkVersion = descriptor.getSdkVersion().toString(); String artifactID = descriptor.getArtifactID(); Optional<Integer> serverID = descriptor.getServerID(); try { AddOnInformation addOnInformation = new AddOnInformationImpl(name, provider, version, id, sdkVersion, serverID, artifactID); addOnInformations.add(addOnInformation); addOns.add(addOn); } catch (MissingArgumentException e) { error("Unable to register addOn: " + addOn.getID() + " with the AddOnInformationManager", e); } } /** * Removes a addOn from the sets. The id can either be the fully classified id of an addOn, that is * intellimate.izou.addOn.myaddon, or it can just be the artifact id, that is myaddon. On success, true is returned * and otherwise false is returned. * * @param id The ID of the addOn to remove. This can either be intellimate.izou.addOn.myaddon as an * example, or just myaddon. * @return True on success, else false. */ boolean unregisterAddOn(String id) { return unregisterHelper(() -> getAddOn(id), () -> getAddOnInformation(id)); } /** * Removes a addOn from the sets. The id is the serverID of an addOn. On success, true is returned * and otherwise false is returned. * * @param serverID The serverID of the addOn to remove. * @return True on success, else false. */ boolean unregisterAddOn(int serverID) { return unregisterHelper(() -> getAddOn(serverID), () -> getAddOnInformation(serverID)); } /** * Helper to unregister an addOn. * * @param suppAdd The first get function to find the right addon. * @param suppAddInf The second get function to find the right addonInformation. * @return True if the operation was successful, otherwise false. */ private boolean unregisterHelper(Supplier<Optional<AddOnModel>> suppAdd, Supplier<Optional<AddOnInformation>> suppAddInf) { boolean success1 = false; Optional<AddOnModel> addOnModel = suppAdd.get(); if (addOnModel.isPresent()) { success1 = addOns.remove(addOnModel.get()); } boolean success2 = false; Optional<AddOnInformation> addOnInformation = suppAddInf.get(); if (addOnInformation.isPresent()) { success2 = addOnInformations.remove(addOnInformation.get()); } return success1 && success2; } /** * Gets the {@link AddOnModel} that has the given id. The id can either be the fully classified id of an addOn, * that is intellimate.izou.addOn.myaddon, or it can just be the artifact id, that is myaddon. * * @param id The id can either be the fully classified id of an addOn, that is * intellimate.izou.addOn.myaddon, or it can just be the artifact id, that is myaddon. * @return An optional wrapping the addOn. If the addOn was found the optional will not be empty and otherwise it * will. */ public Optional<AddOnModel> getAddOn(final String id) { return addOns.stream() .filter(addOn -> addOn.getID().equals(id) || addOn.getPlugin().getDescriptor().getArtifactID().equals(id)) .findFirst(); } /** * Gets the {@link AddOnModel} that has the given id. The id is the serverID of the addOn. * * @param serverID The id is the serverID of the addOn. * @return An optional wrapping the addOn. If the addOn was found the optional will not be empty and otherwise it * will. */ public Optional<AddOnModel> getAddOn(final int serverID) { return addOns.stream() .filter(addOn -> { Optional<Integer> serverIDOpt = addOn.getPlugin().getDescriptor().getServerID(); return serverIDOpt.isPresent() && serverIDOpt.get() == serverID; }) .findFirst(); } /** * gets the AddonModel for the Identification, or null if none found * @param identification the Identification * @return an AddonModel or null */ public AddOnModel getAddonModel(Identification identification) { IdentificationImpl impl = (IdentificationImpl) identification; return getAddonModel(impl.getIdentifiable()); } /** * gets the AddonModel for the Identifiable, or null if none found * @param identifiable the Identifiable * @return an AddonModel or null */ public AddOnModel getAddonModel(Identifiable identifiable) { if (identifiable.getClass().getClassLoader() instanceof IzouPluginClassLoader && !identifiable.getClass().getName().toLowerCase() .contains(IzouPluginClassLoader.PLUGIN_PACKAGE_PREFIX_IZOU_SDK)) { return getMain().getAddOnInformationManager().getAddOnForClassLoader(identifiable.getClass().getClassLoader()) .orElse(null); } return null; } /** * Gets the {@link AddOnInformation} that has the given id. The id can either be the fully classified id of an addOn, * that is intellimate.izou.addOn.myaddon, or it can just be the artifact id, that is myaddon. * * @param id The id can either be the fully classified id of an addOn, that is * intellimate.izou.addOn.myaddon, or it can just be the artifact id, that is myaddon. * @return An optional wrapping the addOnInformation. If the addOn was found the optional will not be empty and * otherwise it will. */ public Optional<AddOnInformation> getAddOnInformation(final String id) { return addOnInformations.stream() .filter(addOn -> addOn.getID().equals(id) || addOn.getArtifactID().equals(id)) .findFirst(); } /** * Gets the {@link AddOnInformation} that has the given id. The id is the serverID of the addOn. * * @param serverID The id is the serverID of the addOn. * @return An optional wrapping the addOn. If the addOn was found the optional will not be empty and otherwise it * will. */ public Optional<AddOnInformation> getAddOnInformation(final int serverID) { if (serverID == -1) { return Optional.empty(); } return addOnInformations.stream() .filter(addOn -> addOn.getServerID().orElse(-1) == serverID) .findFirst(); } /** * Gets all registered addOnInformations. * * @return All registered addOnInformations. */ public IdentifiableSet<AddOnInformation> getAllAddOnInformations() { return addOnInformations; } /** * Gets all registered addOns. * * @return All registered addOns. */ public IdentifiableSet<AddOnModel> getAllAddOns() { return addOns; } /** * Returns the addOn loaded from the given classLoader. * * @param classLoader The classLoader. * @return The (optional) AddOnModel. */ public Optional<AddOnModel> getAddOnForClassLoader(ClassLoader classLoader) { return addOns.stream() .filter(addOnModel -> addOnModel.getClass().getClassLoader().equals(classLoader)) .findFirst(); } }