Package com.lightcrafts.mediax.jai

Source Code of com.lightcrafts.mediax.jai.FactoryCache

/*
* $RCSfile: FactoryCache.java,v $
*
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* Use is subject to license terms.
*
* $Revision: 1.1 $
* $Date: 2005/02/11 04:57:08 $
* $State: Exp $
*/
package com.lightcrafts.mediax.jai;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import com.lightcrafts.mediax.jai.util.CaselessStringKey;

/**
  * A class to manage the various instances of a descriptor factory.
  * This also manages preferences between factory instances for
  * a specified descriptor/product.
  *
  * @since JAI 1.1
  */
class FactoryCache {

    /** * The registry mode name. */
    final String modeName;

    /**
     * Cache the RegistryMode since it is bound to get used
     * many, many times.
     */
    final RegistryMode mode;

    /** The Class corresponding to the factory. */
    final Class factoryClass;

    /**
     * The name of the method in this factory used to
     * do a "create"
     */
    final Method factoryMethod;

    /**
     * does the factory support preferences both among products
     * and among multiple instances of the factory within the
     * same product ?
     */
    final boolean arePreferencesSupported;

    /**
     * A Hashtable of all the instances, hashed by a filename that
     * uniquely identifies each registered factory.
     */
    private Hashtable instances;

    /**
     * A Hashtable of all the unique factory filenames, hashed by
     * the factory they represent.
     */
    private Hashtable instancesByName;

    /** A count to give a number to each registered factory. */
    private int count = 0;

    /**
     * A Hashtable of a Hashtable of all the factory preferences, hashed
     * by the descriptor name first and then the product name that the
     * factory belongs to. Each element of the per product Hashtable is
     * a Vector which contains a list of pairwise factory preferences
     * stored as Vectors.
     */
    private Hashtable prefs;

    /**
     * Constructor. Create a FactoryCache to hold factory objects
     * for a specific mode.
     *
     * @param modeName the registry mode name.
     */
    FactoryCache(String modeName) {

  this.modeName = modeName;

  mode      = RegistryMode.getMode(modeName);
  factoryClass    = mode.getFactoryClass();
  factoryMethod    = mode.getFactoryMethod();
  arePreferencesSupported = mode.arePreferencesSupported();

  instances = new Hashtable();

  if (arePreferencesSupported) {
      instancesByName = new Hashtable();
      prefs = new Hashtable();
  }
    }

    /**
      * Invoke the create method of the given factory instance
      *
      * @param factoryInstance an instance of this factory
      * @param parameterValues the parameterValues to be passed in to the
      *             the create method.
      *
      * @return the object created by the create method
      *
      * @throws IllegalArgumentException thrown by Method.invoke
      * @throws InvocationTargetException thrown by Method.invoke
      * @throws IllegalAccessException thrown by Method.invoke
      */
    Object invoke(Object factoryInstance, Object[] parameterValues)
        throws InvocationTargetException,
               IllegalAccessException {

  return factoryMethod.invoke(factoryInstance, parameterValues);
    }

    /**
      * Add a factory instance to this factory. If the factory has
      * NO preferences add it to a table hashed by just the operation name.
      * Otherwise add it to two tables, one hashed by a unique filename
      * (modeName + count) and the other hashed by the factory interface
      * name.
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName   product to which this factory instance belongs
      * @param factoryInstance the factory instance
      */
    void addFactory(String descriptorName, String productName,
        Object factoryInstance) {

  checkInstance(factoryInstance);

  if (arePreferencesSupported) {

      if (productName == null)
    throw new IllegalArgumentException(JaiI18N.getString("Generic0"));

      // Update structures to reflect the addition of
      // this factory instance.
      Vector v = new Vector();

      v.add(factoryInstance.getClass().getName());
      v.add(productName);
      v.add(descriptorName);

      CaselessStringKey fileName =
        new CaselessStringKey(modeName + count);

      instancesByName.put(factoryInstance, fileName);
      instances.put(fileName, v);
      count++;

  } else
      instances.put(
    new CaselessStringKey(descriptorName), factoryInstance);
    }

    /**
      * Remove a facory instance associated with the specified operation
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName product to which this factory instance belongs
      * @param factoryInstance the factory instance
      *
      */
    void removeFactory(String descriptorName, String productName,
           Object factoryInstance) {

  checkInstance(factoryInstance);
  checkRegistered(descriptorName, productName, factoryInstance);

  if (arePreferencesSupported) {

      // Update structures to reflect the removal of
      // this factoryInstance.
      CaselessStringKey fileName =
    (CaselessStringKey)instancesByName.get(factoryInstance);

      instancesByName.remove(factoryInstance);
      instances.remove(fileName);
      count--;
  } else {
      instances.remove(new CaselessStringKey(descriptorName));
  }
    }

    /**
      * Sets a preference between two factory instances for the given
      * operation and product.
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName   product to which this factory instance belongs
      * @param preferredOp the preferred factory instance
      * @param otherOp     the not-so preferred/other factory instance
      */
    void setPreference(String descriptorName,
           String productName,
           Object preferredOp,
           Object otherOp) {

  if (!arePreferencesSupported) {
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache1",
        new Object[] {modeName}));
  }

  if ((preferredOp == null) || (otherOp == null)) {
      throw new IllegalArgumentException(
      JaiI18N.getString("Generic0"));
  }

  checkRegistered(descriptorName, productName, preferredOp);
  checkRegistered(descriptorName, productName, otherOp);

  if (preferredOp == otherOp)
      return;

  checkInstance(preferredOp);
  checkInstance(otherOp);

  CaselessStringKey dn = new CaselessStringKey(descriptorName);
  CaselessStringKey pn = new CaselessStringKey(productName);

  Hashtable dht = (Hashtable)prefs.get(dn);

  if (dht == null) {
      prefs.put(dn, dht = new Hashtable());
  }

  Vector pv = (Vector)dht.get(pn);

  if (pv == null) {
      dht.put(pn, pv = new Vector());
  }

  pv.addElement(new Object[] { preferredOp, otherOp });
    }

    /**
      * Unets a preference between two factory instances for the given
      * operation and product.
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName   product to which this factory instance belongs
      * @param preferredOp the preferred factory instance
      * @param otherOp     the not-so preferred/other factory instance
      */
    void unsetPreference(String descriptorName,
             String productName,
             Object preferredOp,
             Object otherOp) {

  if (!arePreferencesSupported) {
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache1",
        new Object[] {modeName}));
  }

  if ((preferredOp == null) || (otherOp == null)) {
      throw new IllegalArgumentException(
      JaiI18N.getString("Generic0"));
  }

  checkRegistered(descriptorName, productName, preferredOp);
  checkRegistered(descriptorName, productName, otherOp);

  if (preferredOp == otherOp)
      return;

  checkInstance(preferredOp);
  checkInstance(otherOp);

  // Update structures to reflect removal of this pref.
  Hashtable dht = (Hashtable)prefs.get(
      new CaselessStringKey(descriptorName));

  boolean found = false;

  if (dht != null) {

      Vector pv = (Vector)dht.get(
      new CaselessStringKey(productName));

      if (pv != null) {
    Iterator it = pv.iterator();

    while(it.hasNext()) {
        Object[] objs = (Object[])it.next();

        if ((objs[0] == preferredOp) &&
      (objs[1] == otherOp)) {

      it.remove();
      found = true;
        }
    }

      }
  }

  if (!found)
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache2",
        new Object[] {
      preferredOp.getClass().getName(),
      otherOp.getClass().getName(),
      modeName, descriptorName, productName }));
    }

    /**
      * Gets an iterator over all preferences set between factory
      * instances for a given descriptor and product.
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName   product to which this factory instance belongs
      */
    Object[][] getPreferences(String descriptorName,
          String productName) {

  if (!arePreferencesSupported) {
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache1",
        new Object[] {modeName}));
  }

  if ((descriptorName == null) || (productName == null))
      throw new IllegalArgumentException(JaiI18N.getString("Generic0"));

  // Update structures to reflect removal of this pref.
  Hashtable dht = (Hashtable)prefs.get(
      new CaselessStringKey(descriptorName));

  if (dht != null) {

      Vector pv = (Vector)dht.get(
      new CaselessStringKey(productName));

      if (pv != null) {
    return (Object[][])pv.toArray(new Object[0][]);
      }
  }

  return null;
    }

    /**
      * Removes all preferences set between factory
      * instances for a given descriptor and product.
      *
      * @param descriptorName operation that this factory instance implements
      * @param productName   product to which this factory instance belongs
      */
    void clearPreferences(String descriptorName,
        String productName) {

  if (!arePreferencesSupported) {
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache1",
        new Object[] {modeName}));
  }

  // Update structures to reflect removal of this pref.
  Hashtable dht = (Hashtable)prefs.get(
      new CaselessStringKey(descriptorName));

  if (dht != null)
      dht.remove(new CaselessStringKey(productName));
    }

    /**
     * Get a list of factory objects registered under the descriptor
     * and the product (in no particular order).
     */
    List getFactoryList(String descriptorName, String productName) {

  if (arePreferencesSupported) {

      ArrayList list = new ArrayList();

      Enumeration keys = instancesByName.keys();

      while (keys.hasMoreElements()) {
    Object instance = keys.nextElement();
    CaselessStringKey fileName =
        (CaselessStringKey)instancesByName.get(instance);

    Vector v = (Vector)instances.get(fileName);

    String dn = (String)v.get(2);
    String pn = (String)v.get(1);

    if (descriptorName.equalsIgnoreCase(dn) &&
           productName.equalsIgnoreCase(pn))
        list.add(instance);
      }

      return list;

  } else {
      Object obj =
    instances.get(new CaselessStringKey(descriptorName));
     
      ArrayList list = new ArrayList(1);

      list.add(obj);
      return list;
  }
    }

    /**
     * Get the local name of a factoryInstance
     */
    String getLocalName(Object factoryInstance) {
  CaselessStringKey fileName =
      (CaselessStringKey)instancesByName.get(factoryInstance);

  if (fileName != null)
      return fileName.getName();

  return null;
    }

    /**
     * Check to see if the factoryInstance is valid object
     * of this registry mode.
     */
    private boolean checkInstance(Object factoryInstance) {

  if (!factoryClass.isInstance(factoryInstance))
      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache0",
        new Object[] {
      factoryInstance.getClass().getName(),
      modeName,
      factoryClass.getName()
        }));

  return true;
    }

    /**
     * Check to see if <code>factoryInstance</code> is registered against
     * the specified <code>descriptorName</code> and <code>productName</code>.
     */
    private void checkRegistered(String descriptorName, String productName,
               Object factoryInstance) {

  if (arePreferencesSupported) {

      if (productName == null)
    throw new IllegalArgumentException(
        "productName : " + JaiI18N.getString("Generic0"));

      CaselessStringKey fileName =
    (CaselessStringKey)instancesByName.get(factoryInstance);

      if (fileName != null) {

    Vector v = (Vector)instances.get(fileName);

    String pn = (String)v.get(1);
    String dn = (String)v.get(2);

    if ((dn != null) && dn.equalsIgnoreCase(descriptorName) &&
        (pn != null) && pn.equalsIgnoreCase(productName)) {
        return;
    }
      }

      throw new IllegalArgumentException(
    JaiI18N.formatMsg("FactoryCache3",
        new Object[] { factoryInstance.getClass().getName(),
           descriptorName, productName}));
  } else {

      CaselessStringKey key = new CaselessStringKey(descriptorName);

      if (factoryInstance != instances.get(key)) {
    throw new IllegalArgumentException(
        JaiI18N.formatMsg("FactoryCache4",
      new Object[] { factoryInstance.getClass().getName(),
               descriptorName}));
      }
  }
    }
}
TOP

Related Classes of com.lightcrafts.mediax.jai.FactoryCache

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.