package sk.stuba.fiit.perconik.core; import java.util.Collection; import java.util.List; import java.util.Map.Entry; import java.util.Set; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.SetMultimap; import sk.stuba.fiit.perconik.core.services.Services; import sk.stuba.fiit.perconik.core.services.resources.ResourceManager; import sk.stuba.fiit.perconik.core.services.resources.ResourceNamesSupplier; import sk.stuba.fiit.perconik.core.services.resources.ResourceProvider; import sk.stuba.fiit.perconik.core.services.resources.ResourceService; import sk.stuba.fiit.perconik.utilities.MoreThrowables; import static com.google.common.collect.Lists.newLinkedList; /** * Static accessor methods pertaining to the resources core. * * <p>This class provides access to the underlying functionality * of the currently active {@code ResourceService}. * * @see Resource * @see Listeners * * @author Pavol Zbell * @since 1.0 */ public final class Resources { // TODO add javadocs private Resources() {} static ResourceService service() { return Services.getResourceService(); } static ResourceProvider provider() { return service().getResourceProvider(); } static ResourceManager manager() { return service().getResourceManager(); } public static Resource<?> forName(final String name) { return provider().forName(name); } public static <L extends Listener> Set<Resource<L>> forType(final Class<L> type) { return provider().forType(type); } public static <L extends Listener> void register(final Class<L> type, final Resource<? super L> resource) { manager().register(type, resource); } public static <L extends Listener> void registerAll(final Class<L> type, final Iterable<Resource<? super L>> resources) { List<Exception> failures = newLinkedList(); ResourceManager manager = manager(); for (Resource<? super L> resource: resources) { try { manager.register(type, resource); } catch (Exception failure) { failures.add(failure); } } if (!failures.isEmpty()) { throw MoreThrowables.initializeSuppressor(new ResourceRegistrationException(), failures); } } public static void registerAll(final ResourceNamesSupplier supplier) { List<Exception> failures = newLinkedList(); for (Entry<Class<? extends Listener>, Collection<String>> entry: supplier.get().asMap().entrySet()) { registerAllByNames(entry.getKey(), entry.getValue(), failures); } if (!failures.isEmpty()) { throw MoreThrowables.initializeSuppressor(new ResourceRegistrationException(), failures); } } private static <L extends Listener> void registerAllByNames(final Class<L> type, final Iterable<String> names, final List<Exception> failures) { ResourceProvider provider = provider(); ResourceManager manager = manager(); BiMap<String, Resource<L>> resources = toResourceNameMap(provider.forType(type)); for (String name: names) { Resource<L> resource = resources.get(name); if (resource == null) { throw new ResourceNotFoundException("Resource provider does not know resource by name " + name + " for type " + type.getName()); } try { manager.register(type, resource); } catch (Exception failure) { failures.add(failure); } } } public static <L extends Listener> void unregister(final Class<L> type, final Resource<? super L> resource) { manager().unregister(type, resource); } public static <L extends Listener> void unregisterAll() { unregisterAll(Listener.class); } public static <L extends Listener> void unregisterAll(final Class<L> type) { manager().unregisterAll(type); } public static <L extends Listener> Set<Resource<? extends L>> assignable(final Class<L> type) { return manager().assignables(type); } public static <L extends Listener> Set<Resource<? super L>> registrable(final Class<L> type) { return manager().registrables(type); } public static SetMultimap<Class<? extends Listener>, Resource<?>> registrations() { return manager().registrations(); } public static boolean isRegistered(final Class<? extends Listener> type, final Resource<?> resource) { return manager().registered(type, resource); } public static <L extends Listener> BiMap<String, Resource<L>> toResourceNameMap(final Set<Resource<L>> resources) { BiMap<String, Resource<L>> map = HashBiMap.create(resources.size()); for (Resource<L> resource: resources) { map.put(resource.getName(), resource); } return map; } }