Package org.dmd.dmw

Source Code of org.dmd.dmw.DmwNamedObjectIndexer

package org.dmd.dmw;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.dmd.dmc.DmcClassInfo;
import org.dmd.dmc.DmcObjectName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The DmwNamedObjectIndexer will maintain indices for named objects based on object class.
* This is a useful utility mechanism for things like caches that may want to allow for the
* retrieval of objects of a particular class.
* <p/>
* The indexer allows for the creation of indices for both concrete and abstract classes.
* <p/>
* If indices have been added for a base class and for classes derived from it, adding an
* object to the indexer will result in its inclusion in multiple indices. So be careful about
* which indices you add and how you use them.
* <p/>
* Update operations against the indexer are thread safe.
*/
public class DmwNamedObjectIndexer {

    private HashMap<DmcClassInfo, HashMap<DmcObjectName, DmwNamedObjectWrapper>> indices;

    private Logger  logger = LoggerFactory.getLogger(getClass());

    /**
     * Constructs a new indexer.
     */
    public DmwNamedObjectIndexer(){
    indices = new HashMap<DmcClassInfo, HashMap<DmcObjectName,DmwNamedObjectWrapper>>();
  }
   
    /**
     * @param dci The class for which you're checking.
     * @return true if there's an index for the class and false otherwise.
     */
    public boolean hasIndex(DmcClassInfo dci){
    synchronized (indices) {
      HashMap<DmcObjectName, DmwNamedObjectWrapper> index = indices.get(dci);
      if (index == null)
        return(false);
      return(true);
    }
    }
   
    /**
     * @param ci The class for which you want the index size.
     * @return The size of the index or 0 if no objects of that type exist.
     */
    public int getIndexSize(DmcClassInfo ci){
    synchronized (indices) {
      HashMap<DmcObjectName, DmwNamedObjectWrapper> index = indices.get(ci);
     
      if (index == null)
        return(0);
     
      return(index.size());
    }
    }
   
    /**
     * @param ci The class for which you want the index.
     * @return An iterator over the set of objects in the index. It will be an empty iterator
     * if there are no objects of the specified type.
     */
    @SuppressWarnings("unchecked")
  public Collection<DmwNamedObjectWrapper> getIndex(DmcClassInfo ci){
    synchronized (indices) {
      LinkedList<DmwNamedObjectWrapper> values = new LinkedList<DmwNamedObjectWrapper>();
     
      HashMap<DmcObjectName, DmwNamedObjectWrapper> index = indices.get(ci);
     
      if (index == null)
        return(((List<DmwNamedObjectWrapper>) Collections.EMPTY_LIST));
      else{
        for(DmwNamedObjectWrapper value: index.values())
          values.add(value);
      }
     
      return (values);
    }
    }
   
    /**
     * Indicates that an index should be maintained for the specified class of object. All
     * objects of the specified class or classes derived from it will be added to the index.
     * @param ci The class information.
     */
  public void maintainIndex(DmcClassInfo ci) {
    HashMap<DmcObjectName, DmwNamedObjectWrapper> index = null;
    synchronized (indices) {
      index = indices.get(ci);
     
      if (index != null)
        return;
     
      index = new HashMap<DmcObjectName, DmwNamedObjectWrapper>();
      indices.put(ci, index);
     
      logger.trace("Added indexing for class: " + ci.name);
    }
   
  }
   
  /**
   * This method will add the specified object to the appropriate indices based
   * on its DmcClassInfo. This applies not just for its construction class but
   * also for any classes from which it is derived.
   * @param obj The object to be added.
   */
  public void addToIndices(DmwNamedObjectWrapper obj){
    synchronized (indices) {
      DmcClassInfo currentClass = obj.getConstructionClassInfo();
      HashMap<DmcObjectName, DmwNamedObjectWrapper> index = null;
     
      while(currentClass != null){
        index = indices.get(currentClass);
        if (index != null){
          index.put(obj.getObjectName(),obj);
          logger.trace("Object: " + obj.getObjectName().getNameString() + " added to index for class: " + currentClass.name);
        }
        currentClass = currentClass.derivedFrom;
      }
    }
  }
 
  /**
   * This method will remove the specified object from all indices to which it
   * had been previously added.
   * @param obj
   */
  public void deleteFromIndices(DmwNamedObjectWrapper obj){
    synchronized (indices) {
      DmcClassInfo currentClass = obj.getConstructionClassInfo();
      HashMap<DmcObjectName, DmwNamedObjectWrapper> index = null;
     
      while(currentClass != null){
        index = indices.get(currentClass);
        if (index != null){
          index.remove(obj.getObjectName());
          logger.trace("Object: " + obj.getObjectName().getNameString() + " removed from index for class: " + currentClass.name);
        }
        currentClass = currentClass.derivedFrom;
      }
    }
  }

   
}
TOP

Related Classes of org.dmd.dmw.DmwNamedObjectIndexer

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.