package sk.stuba.fiit.perconik.core.services.listeners; import java.util.Set; import javax.annotation.Nullable; import sk.stuba.fiit.perconik.core.IllegalListenerClassException; import sk.stuba.fiit.perconik.core.Listener; import sk.stuba.fiit.perconik.core.ListenerInstantiationException; import sk.stuba.fiit.perconik.core.services.Provider; import sk.stuba.fiit.perconik.core.services.resources.ResourceProviders; /** * An object responsible for providing {@link Listener} instances. * * @author Pavol Zbell * @since 1.0 */ public interface ListenerProvider extends Provider { /** * Returns an instance of the specified listener implementation class. * * <p>This method is guaranteed to return the same listener instance * for the specified implementation class every time it is invoked. * * @param implementation the listener implementation class * @return the listener * * @throws NullPointerException if the specified listener implementation * class is {@code null} * @throws IllegalListenerClassException if the listener implementation * class is invalid * @throws ListenerInstantiationException if the listener instantiation * failed */ public <L extends Listener> L forClass(Class<L> implementation); /** * Loads a listener implementation class with the specified binary name. * * @param name the binary name of the listener implementation class, * not an empty string or {@code null} * @return the listener implementation class * * @throws IllegalArgumentException if the specified class name * is an empty string * @throws NullPointerException if the specified class name * is {@code null} * @throws ClassNotFoundException if the class was not found * @throws IllegalListenerClassException if the listener implementation * class is invalid */ public Class<? extends Listener> loadClass(String name) throws ClassNotFoundException; /** * Returns implementation classes of all provided listeners. */ public Set<Class<? extends Listener>> classes(); /** * Returns the listener provider's parent or {@code null} if there is no * parent. Standard implementations should return system listener provider * if there is no direct parent (only the system listener provider returns * {@code null} as it is at the top of the listener provider hierarchy). * @see ResourceProviders#superResourceProvider() */ @Override public ListenerProvider parent(); /** * {@inheritDoc} */ @Override public boolean equals(@Nullable Object o); /** * {@inheritDoc} */ @Override public int hashCode(); /** * A builder for creating listener provider instances. * * <p>Builder instances can be reused, it is safe to call {@link #build} * multiple times to build multiple listener providers in series. * * @author Pavol Zbell * @since 1.0 */ public interface Builder { /** * Adds listener implementation to the built listener provider. * If the listener provider already contains given implementation, * then this method has no effect. * @param implementation the listener type to add, not {@code null} * @return this {@code Builder} object * @throws NullPointerException if {@code type} is {@code null} */ public Builder add(Class<? extends Listener> implementation); /** * Adds each listener implementation to the built listener provider, * ignoring duplicate elements. * @param implementations the listener types to add * @return this {@code Builder} object * @throws NullPointerException if {@code implementations} * is {@code null} or contains a {@code null} element */ public Builder addAll(Iterable<Class<? extends Listener>> implementations); /** * Sets the parent listener provider of the built listener provider. * @param provider the parent provider, not {@code null} * @return this {@code Builder} object * @throws NullPointerException if the provider is {@code null} * @throws IllegalStateException if the provider is already set */ public Builder parent(ListenerProvider provider); /** * Returns a newly created listener provider. */ public ListenerProvider build(); } }