Package com.cedarsoft.utils

Source Code of com.cedarsoft.utils.DefaultRegistry

package com.cedarsoft.utils;

import com.cedarsoft.NotFoundException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

/**
* @param <T> the type that is stored within this registry
*/
public class DefaultRegistry<T> implements Registry<T> {
  @NotNull
  @NonNls
  protected final List<T> storedObjects = new ArrayList<T>();
  @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<T> comparator;

  /**
   * Creates an empty registry
   */
  public DefaultRegistry() {
    comparator = null;
  }

  /**
   * Creates a registry with containing the given objects.
   * No comparator is set
   *
   * @param storedObjects the stored objects
   */
  public DefaultRegistry( @NotNull Collection<? extends T> storedObjects ) {
    this( storedObjects, null );
  }

  /**
   * Creates an empty registry with the given (optional) comparator
   *
   * @param comparator the comparator
   */
  public DefaultRegistry( @Nullable Comparator<T> comparator ) {
    this.comparator = comparator;
  }

  /**
   * Creates a new registry
   *
   * @param storedObjects the initially stored objects
   * @param comparator    the (optional) comparator
   */
  public DefaultRegistry( @NotNull Collection<? extends T> storedObjects, @Nullable Comparator<T> comparator ) throws StillContainedException {
    this.comparator = comparator;

    if ( comparator != null ) {
      Collection<T> set = new TreeSet<T>( comparator );
      set.addAll( storedObjects );
      if ( storedObjects.size() != set.size() ) {
        throw new StillContainedException( "The stored objects collections contains duplicate entries" );
      }
    }

    this.storedObjects.addAll( storedObjects );
  }

  @NotNull
  public List<? extends T> getStoredObjects() {
    lock.readLock().lock();
    try {
      return Collections.unmodifiableList( storedObjects );
    } finally {
      lock.readLock().unlock();
    }
  }

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

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

  @NotNull
  public T findStoredObject( @NotNull @NonNls Matcher<T> matcher, @NotNull @NonNls String notFoundMessage ) throws NotFoundException {
    T found = findStoredObject( matcher );
    if ( found == null ) {
      throw new NotFoundException( notFoundMessage );
    }

    return found;
  }

  @NotNull
  public List<? extends T> findStoredObjects( @NotNull @NonNls Matcher<T> matcher ) {
    lock.readLock().lock();
    try {
      List<T> found = new ArrayList<T>();
      for ( T object : storedObjects ) {
        if ( matcher.matches( object ) ) {
          found.add( object );
        }
      }

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

  @NotNull
  public <C> List<? extends C> findStoredObjects( @NotNull @NonNls Matcher<T> matcher, @NotNull Converter<T, C> converter ) {
    lock.readLock().lock();
    try {
      List<C> found = new ArrayList<C>();
      for ( T object : storedObjects ) {
        if ( matcher.matches( object ) ) {
          found.add( converter.convert( 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<T> listener : listeners ) {
        listener.objectStored( object );
      }
    } finally {
      listenersLock.readLock().unlock();
    }
  }

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

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

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

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

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

  public void removeListener( @NotNull Listener<T> listener ) {
    listenersLock.writeLock().lock();
    try {
      this.listeners.remove( listener );
    } finally {
      listenersLock.writeLock().unlock();
    }
  }
}
TOP

Related Classes of com.cedarsoft.utils.DefaultRegistry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.