Package com.lightcrafts.mediax.jai

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

/*
* $RCSfile: RegistryFileParser.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:19 $
* $State: Exp $
*/
package com.lightcrafts.mediax.jai;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StreamTokenizer;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
import com.lightcrafts.mediax.jai.util.CaselessStringKey;

/**
* A class to parse the JAI registry file.
*
* @since JAI 1.1
*/
class RegistryFileParser {

    /**
     * Load the <code>OperationRegistry</code> with the descriptors,
     * factories and their preferences from the input stream.
     */
    static void loadOperationRegistry(OperationRegistry or,
        ClassLoader cl, InputStream is) throws IOException {

  (new RegistryFileParser(or, cl, is)).parseFile();
    }

    /**
     * Load the <code>OperationRegistry</code> with the descriptors,
     * factories and their preferences from the <code>URL</code>.
     */
    static void loadOperationRegistry(OperationRegistry or,
        ClassLoader cl, URL url) throws IOException {

  (new RegistryFileParser(or, cl, url)).parseFile();
    }

    private URL url;
    private InputStream is;
    private ClassLoader classLoader;

    // The OperationRegistry being read in.
    private OperationRegistry or;
    private StreamTokenizer st;

    // The current token - the one last returned by StreamTokenizer
    private int token;

    // The current line number being parsed in the registry file.
    private int lineno;

    // Table used to map local-factory names to factory instances
    // on a per mode basis.
    private Hashtable localNamesTable;

    /**
     * Create a JAI registry file parser from an <code>URL</code>
     */
    private RegistryFileParser(OperationRegistry or, ClassLoader cl, URL url)
      throws IOException {

  this(or, cl, url.openStream());
  this.url = url;
    }

    /**
     * Create a JAI registry file parser from the <code>InputStream</code>
     */
    private RegistryFileParser(OperationRegistry or, ClassLoader cl, InputStream is)
      throws IOException {

  if (or == null)
      or = JAI.getDefaultInstance().getOperationRegistry();

  this.is  = is;
  this.url = null;
  this.or  = or;
  this.classLoader  = cl;

  // Set up streamtokenizer
  BufferedReader reader =
      new BufferedReader(new InputStreamReader(is));

  st = new StreamTokenizer(reader);

  st.commentChar('#');
  st.eolIsSignificant(true);
  st.slashSlashComments(true);
  st.slashStarComments(true);

  token  = st.ttype;
  lineno = -1;

  // Initialize a table to map local names to factories.

  localNamesTable = new Hashtable();

  String modeNames[] = RegistryMode.getModeNames();

  for (int i = 0; i < modeNames.length; i++)
      localNamesTable.put(
    new CaselessStringKey(modeNames[i]), new Hashtable());
    }

    /**
     * Skip all the empty tokens generated due to empty lines
     * and comments.
     */
    private int skipEmptyTokens() throws IOException {

  while (st.sval == null) {
      if (token == StreamTokenizer.TT_EOF)
    return token;

      token = st.nextToken();
  }

  return token;
    }

    /**
     * Get an array of <code>String</code>s of words in the
     * next line after skipping over empty and comment lines.
     */
    private String[] getNextLine() throws IOException {

  if (skipEmptyTokens() == StreamTokenizer.TT_EOF)
      return null;

  Vector v = new Vector();

  lineno = st.lineno();

  while ((token != StreamTokenizer.TT_EOL) &&
         (token != StreamTokenizer.TT_EOF)) {

      if (st.sval != null)
    v.addElement(st.sval);

      token = st.nextToken();
  }

  if (v.size() == 0)
      return null;

  return (String[])v.toArray(new String[0]);
    }

    // Aliases for backward compatibility
    private static String[][] aliases = {
  { "odesc"   , "descriptor"  },
  { "rif"      , "rendered"    },
  { "crif"    , "renderable"  },
  { "cif"      , "collection"  },
    };

    /**
     * Map old keywords to the new keywords
     */
    private String mapName(String key) {
  for (int i = 0; i < aliases.length; i++)
      if (key.equalsIgnoreCase(aliases[i][0]))
    return aliases[i][1];

  return key;
    }

    /**
     * Create an instance given the class name.
     */
    private Object getInstance(String className) {

  try {
      Class descriptorClass = null;
      String errorMsg = null;

      // Since the classes listed in the registryFile can
      // reside anywhere (core, ext, classpath or the specified
      // classloader) we have to try every place.

      // First try the specified classloader
      if (classLoader != null) {
    try {
        descriptorClass = Class.forName(className,
          true, classLoader);
    } catch (Exception e) {
        errorMsg = e.getMessage();
    }
      }

      // Next try the callee classloader
      if (descriptorClass == null) {
    try {
        descriptorClass = Class.forName(className);
    } catch (Exception e) {
        errorMsg = e.getMessage();
    }
      }

      // Then try the System classloader (because the specified
      // classloader might be null and the callee classloader
      // might be an ancestor of the SystemClassLoader
      if (descriptorClass == null) {
    try {
        descriptorClass = Class.forName(className,
          true, ClassLoader.getSystemClassLoader());
    } catch (Exception e) {
        errorMsg = e.getMessage();
    }
      }

      if (descriptorClass == null) {
    registryFileError(errorMsg);
    return null;
      }

      return descriptorClass.newInstance();

  } catch (Exception e) {
      registryFileError(e.getMessage());
      e.printStackTrace();
  }

  return null;
    }

    /**
     * Parse the entire registry file and load internal structures
     * with the info.
     */
    boolean parseFile() throws IOException {

  // If the file has already been parsed do nothing.
  if (token == StreamTokenizer.TT_EOF)
      return true;

  String[] keys;

  token = st.nextToken();

  while (token != StreamTokenizer.TT_EOF) {

      if ((keys = getNextLine()) == null)
    break;

      RegistryMode mode;

      String key = mapName(keys[0]);

      // This indicates a new registry mode to be added.
      if (key.equalsIgnoreCase("registryMode")) {

    mode = (RegistryMode)getInstance(keys[1]);

    if (mode != null) {
        if (RegistryMode.addMode(mode) == false)
      registryFileError(
          JaiI18N.getString("RegistryFileParser10"));
    }

      // Old format operation-descriptor line OR
      // the new generic RegistryElementDescriptor line
      } else if (key.equalsIgnoreCase("descriptor")) {

    registerDescriptor(keys);

      // If it is a registry mode name, then register the
      // factory object.
      } else if ((mode = RegistryMode.getMode(key)) != null) {

    registerFactory(mode, keys);

      // If the line starts with a "pref" there are two options
      } else if (key.equalsIgnoreCase("pref")) {

    key = mapName(keys[1]);

    // If what follows is the keyword "product" then
    // it is assumed to be setting product preferences
    // for the "rendered" mode (old file format)
    if (key.equalsIgnoreCase("product")) {

        setProductPreference(
      RegistryMode.getMode("rendered"), keys);

    // If it is followed by a modeName then it is
    // for setting preferences between factory object.
    } else if ((mode = RegistryMode.getMode(key)) != null) {

        setFactoryPreference(mode, keys);

    } else {
        registryFileError(JaiI18N.getString("RegistryFileParser4"));
    }

      // For setting product preferences
      } else if (key.equalsIgnoreCase("productPref")) {

    key = mapName(keys[1]);

    // If it is followed by a modeName then it is
    // for setting preferences between products
    if ((mode = RegistryMode.getMode(key)) != null) {

        setProductPreference(mode, keys);

    } else {
        registryFileError(JaiI18N.getString("RegistryFileParser5"));
    }
      } else {
    registryFileError(JaiI18N.getString("RegistryFileParser6"));
      }
  }

  // If this was read in from an URL, we created the InputStream
  // and so we should close it.
  if (url != null)
      is.close();

  return true;
    }

    /**
     * Register a descriptor with operation registry.
     */
    private void registerDescriptor(String[] keys) {

  if (keys.length >= 2) {

      RegistryElementDescriptor red =
    (RegistryElementDescriptor)getInstance(keys[1]);

      if (red != null) {
    try {
        or.registerDescriptor(red);
    } catch (Exception e) {
        registryFileError(e.getMessage());
    }
      }

  } else {
      registryFileError(JaiI18N.getString("RegistryFileParser1"));
  }
    }

    /**
     * Register a factory instance against a registry mode
     * under given product and local-name.
     */
    private void registerFactory(RegistryMode mode, String[] keys) {

  Object factory;

  if (mode.arePreferencesSupported()) {

      if (keys.length >= 5) {

    if ((factory = getInstance(keys[1])) != null) {
        try {
      or.registerFactory(
          mode.getName(), keys[3], keys[2], factory);

      mapLocalNameToObject(mode.getName(), keys[4], factory);

        } catch (Exception e) {
      registryFileError(e.getMessage());
        }
    }

      } else {
    registryFileError(
        JaiI18N.getString("RegistryFileParser2"));
      }

  } else {
      if (keys.length >= 3) {

    if ((factory = getInstance(keys[1])) != null) {
        try {
      or.registerFactory(
          mode.getName(), keys[2], null, factory);

        } catch (Exception e) {
      registryFileError(e.getMessage());
        }
    }

      } else {
    registryFileError(
        JaiI18N.getString("RegistryFileParser3"));
      }
  }
    }

    /**
     * Register a factory instance against a registry mode
     * under given product and local-name.
     */
    private void setProductPreference(RegistryMode mode, String[] keys) {

  String modeName = mode.getName();

  if (mode.arePreferencesSupported()) {

      if (keys.length >= 5) {

    try {
        or.setProductPreference(
      modeName, keys[2], keys[3], keys[4]);

    } catch (Exception e) {
        registryFileError(e.getMessage());
    }

      } else {
    registryFileError(
        JaiI18N.getString("RegistryFileParser5"));
      }

  } else {
      registryFileError(JaiI18N.getString("RegistryFileParser9"));
  }
    }

    /**
     * Register a factory instance against a registry mode
     * under given product and local-name.
     */
    private void setFactoryPreference(RegistryMode mode, String[] keys) {

  String modeName = mode.getName();
  Object factory;

  if (mode.arePreferencesSupported()) {

      if (keys.length >= 6) {

    Object preferred = getObjectFromLocalName(modeName, keys[4]);
    Object other     = getObjectFromLocalName(modeName, keys[5]);

    if ((preferred != null) && (other != null)) {

        try {
      or.setFactoryPreference(
          modeName, keys[2], keys[3], preferred, other);

        } catch (Exception e) {
      registryFileError(e.getMessage());
        }
    }

      } else {
    registryFileError(
        JaiI18N.getString("RegistryFileParser4"));
      }

  } else {
      registryFileError(JaiI18N.getString("RegistryFileParser7"));
  }
    }

    /**
     * Map local names to factory instances, so that they can
     * be used to directly set preferences later.
     */
    private void mapLocalNameToObject(String modeName, String localName, Object factory) {

  Hashtable modeTable = (Hashtable)
      localNamesTable.get(new CaselessStringKey(modeName));

  modeTable.put(new CaselessStringKey(localName), factory);
    }

    /**
     * Get object registered under the local name for under the mode.
     */
    private Object getObjectFromLocalName(String modeName, String localName) {

  Hashtable modeTable = (Hashtable)
      localNamesTable.get(new CaselessStringKey(modeName));

  Object obj = modeTable.get(new CaselessStringKey(localName));

  if (obj == null)
      registryFileError(localName + ": " +
        JaiI18N.getString("RegistryFileParser8"));

  return obj;
    }

    private boolean headerLinePrinted = false;

    /**
     * Print the line number and then print the passed in message.
     */
    private void registryFileError(String msg) {

  if (!headerLinePrinted) {

      if (url != null) {
    errorMsg(JaiI18N.getString("RegistryFileParser11"),
        new Object[] { url.getPath() });
      }

      headerLinePrinted = true;
  }

  errorMsg(JaiI18N.getString("RegistryFileParser0"),
     new Object[] { new Integer(lineno) });

  if (msg != null)
      errorMsg(msg, null);
    }

    /**
     * Creates a <code>MessageFormat</code> object and set the
     * <code>Locale</code> to default and formats the message
     */
    private void errorMsg(String key, Object[] args) {
        MessageFormat mf = new MessageFormat(key);
        mf.setLocale(Locale.getDefault());

  if (System.err != null)
      System.err.println(mf.format(args));
    }

    /**
     * Write the OperationRegistry out to the output stream.
     */
    static void writeOperationRegistry(OperationRegistry or,
         OutputStream os) throws IOException {

  writeOperationRegistry(or,
      new BufferedWriter(new OutputStreamWriter(os)));
    }

    /**
     * Write the OperationRegistry out to the output stream.
     */
    static void writeOperationRegistry(OperationRegistry or,
         BufferedWriter bw) throws IOException {

  // First cycle through all the descriptor classes
  Iterator dcit = RegistryMode.getDescriptorClasses().iterator();

  String tab = "  ";

  while (dcit.hasNext()) {

      Class descriptorClass = (Class)dcit.next();

      List descriptors = or.getDescriptors(descriptorClass);

      // First write all the descriptors corresponding
      // to this descriptorClass
      bw.write("#"); bw.newLine();
      bw.write("# Descriptors corresponding to class : " + descriptorClass.getName()); bw.newLine();
      bw.write("#"); bw.newLine();

      if ((descriptors == null) || (descriptors.size() <= 0)) {
    bw.write("# <EMPTY>"); bw.newLine();
      } else {
   
    Iterator it = descriptors.iterator();

    while (it.hasNext()) {
        bw.write("descriptor" + tab);
        bw.write(it.next().getClass().getName());
        bw.newLine();
    }
      }
      bw.newLine();

      // Now cycle through all registry modes associated
      // with this descriptorClass and write out the
      // factories and their preferences

      String modeNames[] = RegistryMode.getModeNames(descriptorClass);

      boolean empty;
      int i, j, k, l;

      for (i = 0; i < modeNames.length; i++) {
    bw.write("#"); bw.newLine();
    bw.write("# Factories registered under mode : " + modeNames[i]); bw.newLine();
    bw.write("#"); bw.newLine();

    RegistryMode mode = RegistryMode.getMode(modeNames[i]);

    boolean prefs = mode.arePreferencesSupported();

    String[] descriptorNames =
          or.getDescriptorNames(modeNames[i]);

    // Over all descriptor names for this mode.
    for (j = 0, empty = true; j < descriptorNames.length; j++) {

        if (prefs) {
      Vector productVector =
          or.getOrderedProductList(modeNames[i],
                 descriptorNames[j]);

      if (productVector == null)
          continue;

      String[] productNames =
          (String[])productVector.toArray(new String[0]);

      // Over all products under which there are
      // factories registered under this descriptor name
      for (k = 0; k < productNames.length; k++) {

          List factoryList =
        or.getOrderedFactoryList(modeNames[i],
               descriptorNames[j],
               productNames[k]);

          Iterator fit = factoryList.iterator();

          while (fit.hasNext()) {
        Object instance = fit.next();

        if (instance == null)
            continue;

        bw.write(modeNames[i] + tab);
        bw.write(instance.getClass().getName() + tab);
        bw.write(productNames[k] + tab);
        bw.write(descriptorNames[j] + tab);
        bw.write(or.getLocalName(modeNames[i], instance));
        bw.newLine();

        empty = false;
          }
      }
        } else {
      Iterator fit = or.getFactoryIterator(
          modeNames[i], descriptorNames[j]);

      while (fit.hasNext()) {
          Object instance = fit.next();

          if (instance == null)
        continue;

          bw.write(modeNames[i] + tab);
          bw.write(instance.getClass().getName() + tab);
          bw.write(descriptorNames[j]);
          bw.newLine();

          empty = false;
      }
        }
    }

    if (empty) {
        bw.write("# <EMPTY>"); bw.newLine();
    }
    bw.newLine();

    // If the mode does not support preferences
    // then just continue
    if (!prefs) {
        bw.write("#"); bw.newLine();
        bw.write("# Preferences not supported for mode : " + modeNames[i]); bw.newLine();
        bw.write("#"); bw.newLine();
        bw.newLine();
        continue;
    }

    // Next, write the product preferences for this mode
    bw.write("#"); bw.newLine();
    bw.write("# Product preferences for mode : " + modeNames[i]); bw.newLine();
    bw.write("#"); bw.newLine();

    for (j = 0, empty = true; j < descriptorNames.length; j++) {

        String[][] productPrefs =
          or.getProductPreferences(modeNames[i],
                 descriptorNames[j]);
        if (productPrefs == null)
      continue;

        for (k = 0; k < productPrefs.length; k++) {
      bw.write("productPref" + tab);
      bw.write(modeNames[i] + tab);
      bw.write(descriptorNames[j] + tab);
      bw.write(productPrefs[k][0] + tab);
      bw.write(productPrefs[k][1]);
      bw.newLine();

      empty = false;
        }
    }

    if (empty) {
        bw.write("# <EMPTY>"); bw.newLine();
    }
    bw.newLine();

    // Next, write the factory preferences for this mode
    bw.write("#"); bw.newLine();
    bw.write("# Factory preferences for mode : " + modeNames[i]); bw.newLine();
    bw.write("#"); bw.newLine();

    // Over all descriptor names for this mode.
    for (j = 0, empty = true; j < descriptorNames.length; j++) {

        if (prefs) {
      Vector productVector =
          or.getOrderedProductList(modeNames[i],
                 descriptorNames[j]);

      if (productVector == null)
          continue;

      String[] productNames =
          (String[])productVector.toArray(new String[0]);

      // Over all products under which there are
      // factories registered under this descriptor name
      for (k = 0; k < productNames.length; k++) {

          Object fprefs[][] = or.getFactoryPreferences(
        modeNames[i], descriptorNames[j], productNames[k]);

          if (fprefs == null)
        continue;

          for (l = 0; l < fprefs.length; l++) {
        bw.write("pref" + tab);
        bw.write(modeNames[i] + tab);
        bw.write(descriptorNames[j] + tab);
        bw.write(productNames[k] + tab);
        bw.write(or.getLocalName(modeNames[i], fprefs[l][0]) + tab);
        bw.write(or.getLocalName(modeNames[i], fprefs[l][1]));
        bw.newLine();

        empty = false;
          }
      }
        }
    }

    if (empty) {
        bw.write("# <EMPTY>"); bw.newLine();
    }
    bw.newLine();
      }
  }

  bw.flush();
    }
}
TOP

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

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.