Package net.xoetrope.xui.registry

Source Code of net.xoetrope.xui.registry.XRegistrationFactory

package net.xoetrope.xui.registry;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.TransferHandler;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.swing.XList;
import net.xoetrope.xml.XmlElement;
import net.xoetrope.xml.XmlSource;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.build.BuildProperties;

/**
* A factory for transfer handlers
* <p>Copyright (c) Xoetrope Ltd., 1998-2006. See license.txt for more details</p>
*/
public abstract class XRegistrationFactory
  /**
   * Match transfer handlers based on the target component class name
   */
  public static final int CLASS_MATCH = 0;

  /**
   * Match transfer handlers based on implementation of a particular interface
   */
  public static final int INTERFACE_MATCH = 1;

  /**
   * Match transfer handlers based on inheritance from a particular class
   */
  public static final int INSTANCE_MATCH = 2;
 
  /**
   * Match transfer handlers based on the results of a user defined comparison
   */
  public static final int INSPECTOR_MATCH = 3;
  private static final int NUM_MATCH_MODES = 4;
 
  /**
   * The register of transfer handler adapters for each component type
   */
  protected ArrayList[] handlerRegisters;

  /**
   * The config files used to build the set of component adapters. Stores the
   * file names
   */
  protected static Hashtable configFiles;

  /**
   * A counter for changes to the registry. Used to indicate if the registry
   * needs to be rebuilt
   */
  protected static int changeCounter;
 
  private String factoryObjectName;

  /**
   * Used for tracking changes to the registry spec.
   */
  protected int localChangeCounter = -1;
 
  private XProject currentProject;

  protected XRegistrationFactory( XProject project, String factoryName, String basicConfigFile, String startupKey, String defaultProjectConfigFile )
  {
    if ( BuildProperties.DEBUG )
        DebugLogger.trace( "Setting up XTransferHandlerFactory" );
   
    factoryObjectName = factoryName;

    addConfigFile( "XUI", basicConfigFile, false );
    currentProject = project;
    currentProject.setObject( factoryName, this );

    String handlerFile = currentProject.getStartupParam( startupKey );
    if ( ( handlerFile == null ) || ( handlerFile.length() == 0 ) )
     handlerFile = defaultProjectConfigFile;
    if ( handlerFile.indexOf( ".xml" ) < 0 )
      handlerFile += ".xml";

    URL url = currentProject.findResource( handlerFile );
    if ( url != null )
      addConfigFile( "Project", url, false );
  }

  /**
   * Get the name of this factory
   * @return the factory name e.g. XRegisteredDataBindingFactory
   */
  public abstract String getFactoryName();
 
  /**
   * Creates a new instance of TransferHandler for a particular type
   * @param comp the source component
   * @param instanceConfig the attributes of the instance
   * @return the new transfer handler
   */
  public Object getObject( Object comp, Hashtable instanceConfig )
  {
    checkRegistration();
   
    String className = comp.getClass().getName();
    for ( int mode = NUM_MATCH_MODES -1; mode >= 0; mode-- ) {
      int numRegistrations = handlerRegisters[ mode ].size();  
      for ( int i = 0; i < numRegistrations; i++ ) {
        XRegistrationEntry match = (XRegistrationEntry)handlerRegisters[ mode ].get( i );
        if ( match.matchMode == mode ) {
          if ( match.matches( mode, comp, match.registrationConfig, instanceConfig )) {
            try {
              XRegistrationSetup handler = (XRegistrationSetup)Class.forName( match.className.trim()).newInstance();
              handler.setup( currentProject, comp, match.registrationConfig, instanceConfig );
              return handler;
            }
            catch ( Exception ex )
            {
              ex.printStackTrace();
            }
          }
        }
      }
    }
    return null;
  }
 
  /**
   * Add a configuration file.
   * If the files have already been loaded then the new file will be loaded
   * @param key the name by which the configuration file is referenced
   * @param resource the name/path of the configuration file or the URL for the file
   * @param overwrite true to overwrite and existing entry matching the specified key
   */
  public static void addConfigFile( String key, Object resource, boolean overwrite )
  {
    if ( resource == null )
      return;

    if  ( configFiles == null )
      configFiles = new Hashtable();

    Object resourceObj = configFiles.get( key );
    // If the same file name is already used then ignore it.
    if (( resourceObj != null ) && resource.equals( resourceObj ))
      return;

    changeCounter++;
    if (( resourceObj != null ) || overwrite )
      configFiles.remove( key );

    configFiles.put( key, resource );
  }

  /**
   * Signal that the configuration has been updated.
   */
  public void updateConfig()
  {
    changeCounter++;
  }

  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   */
  protected void read()
  {
    handlerRegisters = new ArrayList[ NUM_MATCH_MODES ];
    for ( int i = 0; i < NUM_MATCH_MODES; i++ )
      handlerRegisters[ i ] = new ArrayList();

    Enumeration enumeration = configFiles.keys();
    while ( enumeration.hasMoreElements() ) {
      String key = ( String ) enumeration.nextElement();
      if ( !key.equals( "Project" ) )
        doRead( key, configFiles.get( key ) );
    }

    doRead( "Project", configFiles.get( "Project" ) );
  }

  /**
   * Read the component registry. The format is described in the components.xsd
   * schema. The config file is also registered.
   * @param configFile the name of the configuration file
   * @param key the name by which the configuration file is referenced
   */
  protected void read( String key, String configFile )
  {
    addConfigFile( key, configFile, true );
    doRead( key, configFile );
  }

  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   * @param configFile the name of the configuration file
   * @param key the name by which the configuration file is referenced
   */
  protected void doRead( String key, Object configFile )
  {
    if ( configFile == null )
      return;
    else if ( configFile instanceof URL )
      doRead( key, (URL)configFile );
    else
      doRead( key, (String)configFile );
  }

  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   * @param configFile the name of the configuration file
   * @param key the name by which the configuration file is referenced
   */
  protected void doRead( String key, String configFile )
  {
    if ( BuildProperties.DEBUG )
        DebugLogger.trace( getFactoryName() + " reading config file: " + configFile );

    try {
      String fileName = configFile;
      if ( fileName.indexOf( ".xml" ) < 0 )
        fileName += ".xml";
      Reader r = currentProject.getBufferedReader( fileName, null );
      if ( r != null )
        read( key, r );
    }
    catch ( Exception ex ) {
        ex.printStackTrace();
    }
  }

  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   * @param configFileURL the URL of the configuration file
   * @param key the name by which the configuration file is referenced
   */
  protected void doRead( String key, URL configFileURL )
  {
    if ( BuildProperties.DEBUG )
        DebugLogger.trace( "XRegisteredDatatransfer handlerFactory reading config file: " + configFileURL.toString() );

    try {
//      String file = configFileURL.getFile();
      Reader r = new BufferedReader( new InputStreamReader( configFileURL.openStream() ));
      if ( r != null )
        read( key, r );
    }
    catch ( Exception ex ) {
        ex.printStackTrace();
    }
  }


  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   * @param key the name by which the configuration file is referenced
   * @param reader the reader from which to read the file
   */
  public void read( String key, Reader reader )
  {
    try {
      XmlElement regRoot = XmlSource.read( reader );

      Vector registrationNodes = regRoot.getChildren();
      int numElements = registrationNodes.size();
      for ( int i = 0; i < numElements; i++ ) {
        XmlElement regElement = (XmlElement)registrationNodes.elementAt( i );
        String tag = regElement.getName();
        int mode = ( tag.equals( "InspectorTransferHandlers" ) ? INSPECTOR_MATCH :
                     tag.equals( "ClassTransferHandlers" ) ? CLASS_MATCH :
                     tag.equals( "InterfaceTransferHandlers" ) ? INTERFACE_MATCH :
                     INSTANCE_MATCH
                   );
        addRegistrationTypes( regElement, mode );
      }
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to setup the component registry" );
    }
  }
 
  /**
   * Read the component registry. The format is described in the components.xsd
   * schema.
   * @param regRoot the name by which the configuration file is referenced
   * @param mode the match mode for the new transfer handler types
   */
  protected void addRegistrationTypes( XmlElement regRoot, int mode )
  {
    try {
      Vector registrationNodes = regRoot.getChildren();
      int numElements = registrationNodes.size();
      for ( int i = 0; i < numElements; i++ ) {
        XmlElement regElement = (XmlElement)registrationNodes.elementAt( i );
        XRegistrationEntry registration;
        if ( mode == INSPECTOR_MATCH ) {
          registration = new XInspectorRegistrationEntry();
          try {
            String inspector = regElement.getAttribute( "inspector" );
            if ( inspector != null ) {
              Class inspectorClass = Class.forName( inspector );
              ((XInspectorRegistrationEntry)registration).inspector = (XInspector)inspectorClass.newInstance();
            }
          }
          catch ( Exception ex )
          {
            ex.printStackTrace();
          }
        }
        else 
          registration = new XRegistrationEntry();
       
        registration.matchMode = mode;
        registration.target = regElement.getAttribute( "target" );
        registration.className = regElement.getAttribute( "class" );
        handlerRegisters[ mode ].add( registration );
      }
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to setup the component registry" );
    }
  }

  /**
   * Check that all the registered components are loaded
   */
  public void checkRegistration()
  {
    if ( localChangeCounter != changeCounter ) {
      read();
      localChangeCounter = changeCounter;
    }
  } 
}
TOP

Related Classes of net.xoetrope.xui.registry.XRegistrationFactory

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.