All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cedarsoft.utils.Registry Maven / Gradle / Ivy

The newest version!
package com.cedarsoft.utils;

import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @param  the type that is stored within this registry
 */
public class Registry {
  @NotNull
  @NonNls
  protected final List storedObjects = new ArrayList();
  @NotNull
  protected final ReadWriteLock lock = new ReentrantReadWriteLock();

  /**
   * This comparator may optionally be set to ensure the registry only contains unique values
   */
  @Nullable
  protected final Comparator comparator;

  public Registry() {
    comparator = null;
  }

  public Registry( @NotNull List storedObjects ) {
    this( storedObjects, null );
  }

  public Registry( @NotNull List storedObjects, @Nullable Comparator comparator ) {
    this.comparator = comparator;
    this.storedObjects.addAll( storedObjects );
  }

  /**
   * Returns the available cameras
   *
   * @return the cameras
   */
  @NotNull
  public List getStoredObjects() {
    lock.readLock().lock();
    try {
      return Collections.unmodifiableList( storedObjects );
    } finally {
      lock.readLock().unlock();
    }
  }

  @Nullable
  public T findStoredObject( @NotNull @NonNls Matcher matcher ) {
    lock.readLock().lock();
    try {
      for ( T object : storedObjects ) {
        if ( matcher.matches( object ) ) {
          return object;
        }
      }

      return null;
    } finally {
      lock.readLock().unlock();
    }
  }

  @NotNull
  public List findStoredObjects( @NotNull @NonNls Matcher matcher ) {

    lock.readLock().lock();
    try {
      List found = new ArrayList();
      for ( T object : storedObjects ) {
        if ( matcher.matches( object ) ) {
          found.add( object );
        }
      }

      return found;
    } finally {
      lock.readLock().unlock();
    }
  }

  /**
   * Stores the object within the registry
   *
   * @param object the object
   * @throws StillContainedException if a comparator is set and the object still exists within this registry
   */
  public void store( @NotNull T object ) throws StillContainedException {
    lock.writeLock().lock();
    try {
      if ( comparator != null ) {
        for ( T storedObject : storedObjects ) {
          if ( comparator.compare( storedObject, object ) == 0 ) {
            throw new StillContainedException( object );
          }
        }
      }

      storedObjects.add( object );
    } finally {
      lock.writeLock().unlock();
    }

    listenersLock.readLock().lock();
    try {
      for ( Listener listener : listeners ) {
        listener.objectAdded( object );
      }
    } finally {
      listenersLock.readLock().unlock();
    }
  }

  @Nullable
  public Comparator getComparator() {
    return comparator;
  }

  public boolean containsOnlyUniqueElements() {
    return comparator != null;
  }

  @NotNull
  protected final ReadWriteLock listenersLock = new ReentrantReadWriteLock();

  @NotNull
  protected final List> listeners = new ArrayList>();

  public void addListener( @NotNull Listener listener ) {
    listenersLock.writeLock().lock();
    try {
      this.listeners.add( listener );
    } finally {
      listenersLock.writeLock().unlock();
    }
  }

  /**
   * The listener that is notified about changes of the registry
   *
   * @param  the type
   */
  public interface Listener {
    /**
     * Is called if a new object has been stored
     *
     * @param object the object
     */
    void objectAdded( @NotNull T object );
  }

  public interface Matcher {
    boolean matches( @NotNull T object );
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy