Package net.xoetrope.xui

Source Code of net.xoetrope.xui.XProject

package net.xoetrope.xui;

import java.applet.Applet;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import java.util.Hashtable;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xml.XmlParserFactory;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.xui.data.XDataBindingFactory;
import net.xoetrope.xui.data.XModel;
import net.xoetrope.xui.events.XuiEventHandler;
import net.xoetrope.xui.exception.XExceptionHandler;
import net.xoetrope.xui.helper.MessageHelper;
import net.xoetrope.xui.helper.ReflectionHelper;
import net.xoetrope.xui.helper.ResourceBundleLoader;
import net.xoetrope.xui.helper.SwingWorker;
import net.xoetrope.xui.helper.XLayoutHelper;
import net.xoetrope.xui.helper.XTranslator;
import net.xoetrope.xui.helper.XuiUtilities;
import net.xoetrope.xui.style.XStyleManager;

/**
* A holder for references to the objects and resources used by a Xui project
* <p> Copyright (c) Xoetrope Ltd., 2002-2003</p>
* <p> $Revision: 2.40 $</p>
* <p> License: see License.txt</p>
*/
public class XProject
{
  public static final int UNKNOWN = 0;
  public static final int CREATED = 1;
  public static final int INITIALIZED = 2;
  public static final int STARTED = 3;
  public static final int CLOSING = 4;
  public static final int TERMINATED = 5;
  public static final int RESTARTING = 6;
 
  /**
   * The XStyleManager for this XProject instance
   */
  protected XStyleManager styleManager;

  /**
   * The XPageManager for this XProject instance
   */
  protected XPageManager pageManager;

  /**
   * The root XModel for this XProject instance
   */
  protected XModel modelRoot;

  /**
   * The XmlParserFactory to be used by this XProject instance
   */
  protected XmlParserFactory xmlParserFactory;

  /**
   * Store a reference to the MessageHelper utility class
   */
  protected MessageHelper messageHelper;

  /**
   * Stores a Vector of XDataBindingFactory Object for this XProject instance
   */
  protected Vector bindingFactories;

  /**
   * The name of the startup file for this XProject instance
   */
  protected String startupFile;

  /**
   * Properties Object created from the statup properties
   */
  protected Properties startSettings;

  /**
   * The path to the startup directory for this XProject instance
   */
  protected URL documentBase;

  /**
   * Hashtable for storing other non-XUI object such as Routes and Services
   */
  protected Hashtable managerObjects;

  /**
   * The default XModel based class to be used in this XProject instance. Defaulted
   * to XBaseModel
   */
  protected Class defaultModelClass = net.xoetrope.xui.data.XBaseModel.class;

  /**
   * The name of the event handler class which is to be used
   */
  protected String eventHandlerClassName = "net.xoetrope.xui.XEventHandler";

  // Former XResourceManager members
  protected String defaultFile;

  /**
   * Encoding with which to read and write XML files. Defaulted to UTF-8
   */
  protected String defaultEncoding;

  /**
   * The package where event hadlers can be found
   */
  protected String basePackageName = XPage.XUI_AWT_PACKAGE;

  /**
   * The package name of the components to be used (AWT or Swing)
   */
  protected String widgetPackageName = XPage.XUI_AWT_PACKAGE;

  /**
   * The XProject XApplet Object
   */
  protected Applet app;

  /**
   * The XProject Window Object
   */
  protected Window appWindow;

  /**
   * The XProject Frame Object
   */
  protected Frame appFrame;

  protected XStartupObject startupObject;
 
  /**
   * Vector of
   * s used to locate resources for this XProject instance
   */
  protected Vector customClassLoaders;

  /**
   * ResourceBundleLoader used to load ResourceBundles
   */
  protected ResourceBundleLoader resourceBundleLoader;

  /**
   * Hashtable of images already accessed
   */
  protected Hashtable imageCache;

  /**
   * A generic handler for exceptions
   */
  protected XExceptionHandler exceptionHandler;

  /*
   * Project status
   */ 
  protected int status; 
 
  /**
   * Create a new project
   */
  protected XProject()
  {
    styleManager = null;
    pageManager = null;
    modelRoot = null;
    xmlParserFactory = null;
    bindingFactories = new Vector();
    managerObjects = new Hashtable();

    customClassLoaders = new Vector();
    defaultEncoding = "UTF8";
    status = CREATED;
   
    setObject( "LayoutHelper", new XLayoutHelper());
    XProjectManager.addProject( null, this );
  }

  /**
   * Setup the project and configure its resources
   * @param startFile the startup file
   */
  public void initialise( String startFile )
  {
    if ( status < INITIALIZED ) {
      setStartupFile( startFile );
      pageManager = new XPageManager( this );
      DebugLogger.setDebugLevel( getStartupParam( "LogLevel" ));
      DebugLogger.readLoggerZones( this );
      setDefaultModel( getStartupParam( "DefaultModelClass" ));
      styleManager = createStyleManager();
      status = INITIALIZED;
    }
  }


  private XStyleManager createStyleManager()
  {
    XStyleManager mgr = null;
    String defStyleManager = getStartupParam( "DefaultStyleManager" );
    if ( defStyleManager != null && defStyleManager.length() > 0 ) {
      try {
        Class c = Class.forName( defStyleManager.trim());
        mgr = (XStyleManager) c.newInstance();
      }
      catch ( Exception ex ) {
        if ( BuildProperties.DEBUG )
          DebugLogger.logError( "StyleManager NOT found: " + defStyleManager );
      }
    }
    if ( mgr == null ) {
      mgr = new XStyleManager( this, 10 );
    }
    return mgr;
  }
  //----------------------------------------------------------------------------

  /**
   * Get a reference to the XStyleManager. A new instance is created if required
   * @return the style manager
   * @since 1.03
   */
  public XStyleManager getStyleManager()
  {
    if ( styleManager == null )
      DebugLogger.logError( "No XStyleManager instantiated, please check the startup sequence" );

    return styleManager;
  }

  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Gets an instance of the page manager. A new instance is created if required
   * @return the XPageManager instance
   * @since 1.03
   */
  public XPageManager getPageManager()
  {
    if ( pageManager == null ) {
      // This code should not be executed, so an exception is deliberately
      // thrown to provide an early warning.
      DebugLogger.logError( "No XPageManager instantiated, please check the startup sequence" );
      if ( !BuildProperties.BUILD_JDK_118 ) {
        throw new java.lang.UnsupportedOperationException();
      }
    }

    return pageManager;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Gets the application context for this project
   * @return the XApplicationContext instance
   * @since 3.0
   */
  public XApplicationContext getApplicationContext()
  {
    Object o = getObject( "AppContext" );
    return (XApplicationContext)o;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get the root instance of the model. This class is unique to the project so it
   * should be unique. If no instance has been created then a new one is
   * constructed.
   * @return the root XModel instance.
   */
  public XModel getModel()
  {
    if ( modelRoot == null ) {
      try {
        modelRoot = ( XModel ) defaultModelClass.newInstance();
      }
      catch ( IllegalAccessException ex ) {
        ex.printStackTrace();
      }
      catch ( InstantiationException ex ) {
        ex.printStackTrace();
      }
      modelRoot.setId( "base" );
    }
    return modelRoot;
  }

  /**
   * Sets the default model class. By default the XBaseModel is
   * used. An instance is not constructed till the first call to getInstance().
   * If an instance has been constructed then this method will have no effect.
   * @param className the name of the model class e.g. net.xoetrope.xui.data.XBaseModel
   */
  public void setDefaultModel( String className )
  {
    try {
      if ( className != null )
        defaultModelClass = Class.forName( className.trim());
    }
    catch ( ClassNotFoundException ex ) {
    }
  }

  /**
   * Reset the model to its initial state. Discard all the child nodess
   */
  public void resetModel()
  {
    modelRoot = null;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get the XML parser factory
   * @return the parser factory
   */
  public XmlParserFactory getXmlParserFactory()
  {
    if ( xmlParserFactory == null )
      xmlParserFactory = new XmlParserFactory();

    return xmlParserFactory;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Create the XuiEventHandler for the passed owner (XPage) and set it's
   * XValidationHandler
   * @param owner The XPage for which the passed XValidationHandler is working
   * @param validationHandler The XValidationHandler for this XProject instance
   * @return The created XuiEventHandler
   */
  public XuiEventHandler createEventHandler( Object owner, net.xoetrope.xui.validation.XValidationHandler validationHandler )
  {
    try {
      Class clazz = Class.forName( eventHandlerClassName.trim());
      Class[] parameterTypes = new Class[ 3 ];
      parameterTypes[ 0 ] = XProject.class;
      parameterTypes[ 1 ] = Object.class;
      parameterTypes[ 2 ] = net.xoetrope.xui.validation.XValidationHandler.class;
      Constructor ctor = clazz.getConstructor( parameterTypes );
      Object[] args = new Object[ 3 ];
      args[ 0 ] = this;
      args[ 1 ] = owner;
      args[ 2 ] = validationHandler;
      return (XuiEventHandler)ctor.newInstance( args );
    }
    catch( Exception e ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to create event handler." );
      e.printStackTrace();
    }
    return null;
  }

  /**
   * Set the name of the class which will handle events for this XProject instance
   * @param className The name of the event handler class
   */
  public void setEventHandlerClass( String className )
  {
    eventHandlerClassName = className;
  }

  /**
   * Set an exception handler for unhandled errors during method response method
   * invocation
   * @return the exception handler
   */
  public XExceptionHandler getExceptionHandler()
  {
    return exceptionHandler;
  }


  /**
   * Set an exception handler for unhandled errors during method response method
   * invocation
   * @param eh the exception handler
   */
  public void setExceptionHandler( XExceptionHandler eh )
  {
    exceptionHandler = eh;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get the message helper (for formatting messages)
   * @return the message helper
   */
  public MessageHelper getMessageHelper()
  {
    if ( messageHelper == null )
      messageHelper = new MessageHelper();

    return messageHelper;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get the binding factories. The binding factories are requested to create
   * component data bindings when a page is loaded from XML.
   * @return the registered binding factories
   */
  public Vector getBindingsFactories()
  {
    if ( bindingFactories == null )
      bindingFactories = new Vector();

    return bindingFactories;
  }

  /**
   * Register a binding factory with the project. The factories
   * are used to add bindings in the order in which they appear in the array of
   * bindings and the iteration of factories stops once a binding is created.
   *
   * @param fact the new factory
   * @param pos the postion in the array at which to add the factory.
   */
  public void registerBindingFactory( XDataBindingFactory fact, int pos )
  {
    String newFactoryClassName = fact.getClass().getName();
    int numFactories = bindingFactories.size();
    for ( int i = 0; i < numFactories; i++ ) {
      if ( bindingFactories.elementAt( i ).getClass().getName().equals( newFactoryClassName ))
        return;
    }

    // The factory isn't already in use so add it.
    if ( !BuildProperties.BUILD_JDK_118 )
      bindingFactories.add( Math.min( Math.max( pos, 0 ), bindingFactories.size()), fact );
    else
      bindingFactories.addElement( fact );
  }

  /**
   * Register a data binding factory. An add-on library or plug-in may wish to
   * customize the data bindings, particularly if it provides extended model
   * node types. Such extended nodes may need adapters to be useful for some or
   * all widgets and other binding contexts. Registration of the binding factory
   * allows the necessary adapters and bindings to be created on request.
   * @param fact the new binding factory
   */
  public void registerBindingFactory( XDataBindingFactory fact )
  {
    registerBindingFactory( fact, -1 );
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get the name of the startup file.
   * @return the startup file name, normally startup.properties
   */
  public String getStartupFile()
  {
    return startupFile;
  }
 
  /**
   * Sets the startup file and loads the associated resource.
   * @param fileName the name of the startup resource file.
   */
  public void setStartupFile( String fileName )
  {
    startupFile = fileName;
    int pos = fileName.lastIndexOf( File.separatorChar );
    try {
      if ( pos > 0 ) {
        if ( BuildProperties.DEBUG ) {
          DebugLogger.trace( "Startup file: " + fileName );
          DebugLogger.trace( "-- Document base: " + "file://" + fileName.substring( 0, pos+1 ));
          DebugLogger.trace( "-- Startup file: " + fileName.substring( pos + 1 ) );
        }
//        URL url = findResource( fileName );
        documentBase = new URL( "file", "", slashify( fileName.substring( 0, pos+1 ), true ));
        startupFile = fileName.substring( pos + 1 );
      }
    }
    catch ( Exception ex ) {
      ex.printStackTrace();
    }

    try {
      URL suUrl = findResource( startupFile );
      startSettings = new Properties();
      if ( suUrl != null ) {
        if ( documentBase == null ) {
          String s = suUrl.toString();
          s = s.substring( 0, s.lastIndexOf( "/" ) + 1 );
          documentBase = new URL( s );
        }
       
        InputStream is = suUrl.openStream();
        startSettings.load( is );
        String encoding = getStartupParam( "DefaultEncoding" );
        if ( encoding != null )
          defaultEncoding = encoding;

        String antiAlias = getStartupParam( "AntiAlias" );
        if ( antiAlias != null )
          XPage.antiAlias = antiAlias.equals( "true" );

        String startupPath = suUrl.getFile();
        if ( startupPath.charAt( 0 ) == '/' )
          startupPath = startupPath.substring( 1 );
        // This is a URL reference so the path separator is always "/"
        if ( ( pos = startupPath.indexOf( "/" + "resources" ) ) > 0 )
          startupPath = startupPath.substring( 0, pos );
        else if ( ( pos = startupPath.lastIndexOf( "/" ) ) > 0 )
          startupPath = startupPath.substring( 0, pos );
       
        startSettings.put( "ProjectPath", startupPath );
      }
    }
    catch ( Exception e ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to load startup file: " + fileName );
      else
        System.err.println( e.getMessage());
    }

    try {
      String ncl = getStartupParam( "NumClassLoaders" );
      if ( ncl != null ) {
        int numClassLoaders = new Integer( ncl ).intValue();
        for ( int i = 0; i < numClassLoaders; i++ ) {
          ClassLoader cl = ( ClassLoader )Class.forName( getStartupParam( "ClassLoader" + ( i + 1 )).trim()).newInstance();
          customClassLoaders.addElement( cl );
        }
      }
    }
    catch ( Exception e ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to load class loader: " + e.getMessage() );
      else
        System.err.println( e.getMessage());
    }

    try {
      String helper = getStartupParam( "LayoutHelper" );
      if ( helper != null ) {
          LayoutHelper layoutHelper = (LayoutHelper)Class.forName( helper.trim()).newInstance();
          XComponentFactory.setLayoutHelper( layoutHelper );
      }
    }
    catch ( Exception e ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to set the layout helper: " + e.getMessage() );
    }

    String sp = getStartupParam( "CacheImages" );
    if (( sp != null ) && !sp.equals( "false" ))
      imageCache = new Hashtable();
  }

  /**
   * Gets a startup parameter
   * @param name the paramenter name
   * @return the value
   */
  public String getStartupParam( String name )
  {
    if ( startSettings == null ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logWarning( "No startup file available: param '" + name + "' not found" );
      return null;
    }

    return startSettings.getProperty( name );
  }

  /**
   * Sets a startup parameter
   * @param name the paramenter name
   * @param value the new value
   * @return true if the value is new or different from the old value
   */
  public boolean setStartupParam( String name, String value )
  {
    if (( name != null ) && ( value != null )) {
      Object obj = startSettings.get( name );     
      String oldValue = obj == null ? null : obj.toString();
      if (( oldValue == null ) || !oldValue.equals( value )) {
        startSettings.setProperty( name, value );
        return true;
      }
    }
   
    return false;
  }

  /**
   * Gets a startup parameter
   * @param name the paramenter name
   * @return the value
   */
  public int getStartupParamAsInt( String name )
  {
    String p = startSettings.getProperty( name );
    if ( p != null )
      return Integer.parseInt( p );
   
    return 0;
  }
 
  /**
   * Get the project status
   * @return the current status
   */
  public int getStatus()
  {
    return status;
  }
 
  /**
   * Set the application status
   * @param newStatus the new status
   */
  public void setStatus( int newStatus )
  {
    status = newStatus;
  }
  //----------------------------------------------------------------------------

  //----------------------------------------------------------------------------
  /**
   * Get a manager object
   * @param key the name of the object e.g. "Routes", "Services"
   * @return the object instance or null if it hasn't been added
   */
  public Object getObject( String key )
  {
    return managerObjects.get( key );
  }

  /**
   * Set an manager object value
   * @param key the name of the object e.g. "Routes", "Services"
   * @param obj the object instance
   */
  public void setObject( String key, Object obj )
  {
    Object o = managerObjects.get( key );
    if ( o != null )
      managerObjects.remove( key );
   
    if ( obj != null )
      managerObjects.put( key, obj );
  }

  /**
   * Remove a manager object value
   * @param key the name of the object e.g. "Routes", "Services"
   */
  public void removeObject( String key )
  {
    Object obj = managerObjects.get( key );
    if ( obj != null )
      managerObjects.remove( obj );
  //----------------------------------------------------------------------------





  //-Former XResourceManager methods--------------------------------------------
  /**
   * Loads an image icon
   * @param name the image resource name
   * @return the image
   */
  public Object getIcon( String name )
  {
    try {
      Image img = getImage( name );
      Class imageIconClazz = Class.forName( "javax.swing.ImageIcon" );
      Constructor ctor = imageIconClazz.getConstructor( new Class[] { Image.class } );
      Object imageIcon = ctor.newInstance(new Object[]{ img });
      return imageIcon;
    }
    catch ( Exception e )
    {
      return null;
    }
  }

  /**
   * Loads an image resource
   * @param name the image resource name
   * @return the image
   */
  public Image getImage( String name )
  {
    if ( name == null )
      return null;

    URL jarSource = XuiUtilities.checkUrl( getUrl( name ));
    Image result = null;
    if ( jarSource != null )
      result = Toolkit.getDefaultToolkit().getImage( jarSource );

    try {
      if ( result == null ) {
        URL url = XuiUtilities.checkUrl( new URL( documentBase, name ));
        if ( url != null )
          result = Toolkit.getDefaultToolkit().getImage( url );
      }
    }
    catch ( MalformedURLException ex ) {
      URL url = XuiUtilities.checkUrl( ClassLoader.getSystemResource( name ));
      if ( url != null )
        result = Toolkit.getDefaultToolkit().getImage( url );
    }
    finally {
      if ( BuildProperties.DEBUG ) {
        if ( result == null )
          DebugLogger.logWarning( "Cannot load image: " + name );
      }
    }

    return result;
  }

  /**
   * Loads an image resource in a background thread
   * @param holder the component containing to display the image
   * @param name the image resource name
   */
  public synchronized void getImage( XImageHolder holder, String name )
  {
    if ( name == null )
      return;

    final String imageName = name;
    final SwingWorker worker = new SwingWorker()
    {
      Image result = null;

      public Object construct()
      {
        if ( imageCache != null )
          result = (Image)imageCache.get( imageName );

        if ( result == null )
          result = createImage( getBufferedInputStream( imageName ) );

        if (( result != null ) && ( imageCache != null ))
          imageCache.put( imageName, result );

        return result; //return value not used by this program
      }

      //Runs on the event-dispatching thread.
      public void finished()
      {
        Object holder = getExtraValue();
        if ( holder != null )
          ((XImageHolder)holder).setImage( result );
      }
    };
    worker.setExtraValue( holder );
    worker.start();
  }

  /**
   * Gets a stream for a resource
   * @param fileName the resource file name
   * @return the InputStream
   */
  public InputStream getInputStream( String fileName )
  {
    // Try a file stream
    if ( BuildProperties.DEBUG )
      DebugLogger.trace( "RESOURCES", "Opening file:" + fileName );
    InputStream result = null;
    try {
      ClassLoader cl = getClass().getClassLoader();
      if ( cl != null ) {
        try {
          int numClassLoaders = customClassLoaders.size();
          if ( numClassLoaders > 0 ) {
            for ( int i = 0; i < numClassLoaders; i++ ) {
              ClassLoader classLoader = ((ClassLoader)customClassLoaders.elementAt( i ));
              if ( canAccessDefaultPackage( classLoader, fileName ))
                result = classLoader.getResourceAsStream( fileName );

              if ( result != null )
                break;
            }
          }
         
          if ( result == null ) {
            // This check causes a problem where files are contained in a jar in the
            // default package. The file will not load.
            //if ( new File( fileName ).getParent() != null )
            if ( fileName.indexOf( "http" ) == 0 ) {
              try {
                URL url = new URL( fileName );
                result = url.openStream();
              }
              catch( Exception e ) {
                if ( BuildProperties.DEBUG )
                  e.printStackTrace();
                result = null;
              }
            }
            else if ( canAccessDefaultPackage( cl, fileName ))
              result = cl.getResourceAsStream( fileName );         
          }         
        }
        catch ( Exception ex1 ) {
          result = null;
          if ( BuildProperties.DEBUG )
            ex1.printStackTrace();
        }
      }

      if ( result == null ) {
        try {
          result = new FileInputStream( fileName );
        }
        catch ( Exception ex ) {
          try {
            result = new FileInputStream( new URL( documentBase, fileName ).getFile() );
          }
          catch ( Exception ex2 ) {
            try {
              result = ClassLoader.getSystemResourceAsStream( fileName );
            }
            catch ( Exception ex4 ) {
              result = null;
            }
          }
        }
      }
    }
    finally {
      if ( BuildProperties.DEBUG ) {
        if ( result == null )
          DebugLogger.logWarning( "File not loaded:" + fileName );
      }
    }
    return result;
  }

  /**
   * Find a resource and get its filename (unencoded)
   * @param fileName the resource file name
   * @return the complete filename
   */
  public String findResourceAsString( String fileName )
  {
    URL resUrl = findResource( fileName );
    if ( resUrl != null ) {
      String docfileName = resUrl.getFile();
      if ( !BuildProperties.BUILD_JDK_118 )
        docfileName = URLDecoder.decode( docfileName );
      if ( docfileName.charAt( 0 ) == '/' )
        docfileName = docfileName.substring( 1 );
      return docfileName;
    }

    return null;
  }

  /**
   * Find a resource
   * @param fileName the resource file name
   * @return the resource URL or null if it is not found
   */
  public URL findResource( String fileName )
  {
    URL result = null;
    ClassLoader cl = getClass().getClassLoader();
    if ( cl != null ) {
      try {
        int numClassLoaders = customClassLoaders.size();
        if ( numClassLoaders > 0 ) {
          for ( int i = 0; i < numClassLoaders; i++ ) {
            ClassLoader classLoader = ((ClassLoader)customClassLoaders.elementAt( i ));
            if ( canAccessDefaultPackage( classLoader, fileName ))
              result = classLoader.getResource( fileName );
           
            if ( result != null )
              return result;
          }
        }
       
        try {
          if ( canAccessDefaultPackage( cl, fileName ))
            result = cl.getResource( fileName );
         
          if ( result != null )
            return result;
        }
        catch ( Exception ex3 ) {
        }
      }
      catch ( Exception ex1 ) {
        ex1.printStackTrace();
      }
    }

    // Try the sytsem
    try {
      return ClassLoader.getSystemResource( fileName );
    }
    catch ( Exception ex ) {
    }

    return null;
  }

  /**
   * Gets a buffered stream for a resource
   * @param s the resource name
   * @return the input stream
   */
  public BufferedInputStream getBufferedInputStream( String s )
  {
    return new BufferedInputStream( getInputStream( s ) );
  }

  /**
   * Gets a URL for a resource
   * @param fileName the resource file name
   * @return the InputStream
   */
  public URL getUrl( String fileName )
  {
    ClassLoader cl = getClass().getClassLoader();
    URL resUrl =  null;
    if ( cl != null ) {
      try {
        int numClassLoaders = customClassLoaders.size();
        for ( int i = 0; i < numClassLoaders; i++ ) {
          ClassLoader classLoader = ((ClassLoader)customClassLoaders.elementAt( i ));
          if ( canAccessDefaultPackage( classLoader, fileName ))
            resUrl = classLoader.getResource( fileName );
         
          if ( resUrl != null )
            break;
        }
        if ( resUrl == null )
          resUrl = cl.getResource( fileName );

        if ( BuildProperties.DEBUG ) {
          if ( resUrl == null )
            DebugLogger.logWarning( "File not loaded from classpath: " + fileName );
        }
      }
      catch ( Exception ex1 ) {
        ex1.printStackTrace();
      }
    }

    try {
      if ( resUrl == null )
        resUrl = new URL( documentBase, fileName );
    }
    catch ( Exception ex ) {}

    return resUrl;
  }

  /**
   * Add a custom class loader. Customer class loaders are sometimes added to
   * help locate resources in file structures, jars, remote locations etc...
   * @param c the classloader
   */
  public void addCustomClassLoader( ClassLoader c )
  {
    if ( c != null )
      customClassLoaders.addElement( c );
  }
 
  /**
   * Get the custom classloaders
   * @return the class loaders or null if none or specified
   */
  public Vector getCustomerClassLoaders()
  {
    return customClassLoaders;
  }
 
  /**
   * Gets the <code>XProjectClassLoader</code> object. If any instance of
   * <code>XProjectClassLoader</code> class was created, it is registered in
   * this <code>XProject</code> object.
   * @return <code>XProjectClassLoader</code> object.
   */
  public ClassLoader getProjectClassLoader()
  {
    ClassLoader classLoader = null;
    Enumeration enumClassLoaders = customClassLoaders.elements();
    while ( ( enumClassLoaders.hasMoreElements() ) && ( classLoader == null ) ) {
      Object o = enumClassLoaders.nextElement();
      if ( o.getClass().getName().equals( "net.xoetrope.optional.resources.XProjectClassLoader" ))
        classLoader = (ClassLoader)o;
    }
    return classLoader;
  }

  /**
   * Gets a stream for a file
   * @param file the file
   * @return the input stream
   */
  public InputStream getInputStream( File file )
  {
    FileInputStream result = null;
    try {
      if ( BuildProperties.DEBUG )
        DebugLogger.trace( "RESOURCES", "Opening file:" + file.getAbsolutePath() + ", exists:" + file.exists() );

      result = new FileInputStream( file );
    }
    catch ( FileNotFoundException ex ) {
      result = null;
    }
    finally {
      if ( BuildProperties.DEBUG ) {
        if ( result == null )
          DebugLogger.logWarning( "File open failed:" + file.getAbsolutePath());
      }
    }
    return result;
  }

  /**
   * Gets a buffered stream for a file
   * @param file the file
   * @return the input stream
   */
  public BufferedInputStream getBufferedInputStream( File file )
  {
    return new BufferedInputStream( getInputStream( file ) );
  }

  /**
   * Gets a BufferedReader for a resource
   * @return the BufferedReader
   * @param file the resource file name
   * @throws java.lang.Exception throw an exception if there's a problem
   */
  public BufferedReader getBufferedReader( String file ) throws Exception
  {
    InputStream is;
    BufferedReader r = null;
    try {
      is = getInputStream( file );
      if ( is != null )
        r = new BufferedReader( new InputStreamReader( is ) );
    }
    catch ( Exception ex ) {
      throw( ex );
    }
    return r;
  }

  /**
   * Gets a BufferedReader for a resource
   * @return the BufferedReader
   * @param file the resource file name
   * @param encoding the input encoding e.g. "UTF8" or null for the default
   * encoding (UTF8 unless it has been changed)
   * @throws java.lang.Exception throw an exception if there's a problem
   */
  public BufferedReader getBufferedReader( String file, String encoding ) throws Exception
  {
    if ( encoding == null )
      encoding = defaultEncoding;

    InputStream is;
    BufferedReader r = null;
    try {
      is = getInputStream( file );
      if ( is != null ) {
        InputStreamReader isr = new InputStreamReader( is, encoding );
        r = new BufferedReader( isr );
      }
    }
    catch ( UnsupportedEncodingException ex ) {
      throw new Exception( "Encoding " + encoding + " not supported for file '" + file + "'" );
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG )
        ex.printStackTrace();
      throw new Exception( "Could not access file '" + file + "'" );
    }
    return r;
  }

  /**
   * Gets a BufferedReader for a resource
   * @return the BufferedReader
   * @param file the resource file
   * @param encoding the input encoding e.g. "UTF8" or null for the default
   * encoding (UTF8 unless it has been changed)
   * @throws java.lang.Exception throw an exception if there a problem
   */
  public BufferedReader getBufferedReader( File file, String encoding ) throws Exception
  {
    if ( encoding == null )
      encoding = defaultEncoding;

    InputStream is;
    BufferedReader r = null;
    try {
      is = getInputStream( file );
      InputStreamReader isr = new InputStreamReader( is, encoding );
      r = new BufferedReader( isr );
    }
    catch ( UnsupportedEncodingException ex ) {
      throw new Exception( "Encoding " + encoding + " not supported for file '" + file + "'" );
    }
    catch ( Exception ex ) {
      throw new Exception( "Could not access file '" + file + "'" );
    }
    return r;
  }

  /**
   * Gets a stream for a file
   * @param file the file
   * @return the output stream
   */
  public OutputStream getOutputStream( String file )
  {
    return getOutputStream( file, true );
  }

  /**
   * Gets a buffered stream for a file
   * @param file the file
   * @return the output stream
   */
  public BufferedOutputStream getBufferedOutputStream( String file )
  {
    return new BufferedOutputStream( getOutputStream( file ));
  }

  /**
   * Gets a stream for a file
   * @param file the file
   * @param useProjectParent use the projects default file specification to locate the file
   * @return the output stream
   */
  public OutputStream getOutputStream( String file, boolean useProjectParent )
  {
    try {
      if ( getClass().getClassLoader() == null ) {
        return new FileOutputStream( file );
      }
      else {
        if ( useProjectParent ) {
          File f = new File( defaultFile );
          return new FileOutputStream( new File( f, file ) );
        }
        else
          return new FileOutputStream( new File( file ) );
      }
    }
    catch ( Exception ex ) {
      ex.printStackTrace();
      return null;
    }
  }

  /**
   * Gets a buffered stream for a file
   * @param file the file
   * @param useProjectParent use the projects default file specification to locate the file
   * @return the output stream
   */
  public BufferedOutputStream getBufferedOutputStream( String file, boolean useProjectParent )
  {
    return new BufferedOutputStream( getOutputStream( file, useProjectParent ));
  }

  /**
   * Set the default package name. The default package when accessing user event
   * handlers.
   * @param pn The name of the package to be used
   */
  public void setPackageName( String pn )
  {
    basePackageName = pn;
  }

  /**
   * Get the default package name
   * @return the default package name
   */
  public String getPackageName()
  {
    return basePackageName;
  }

  /**
   * Set the default widget package name. The default package name is used when
   * constructing widgets.
   * @param pn The name of the widget package to be used
   */
  public void setWidgetPackageName( String pn )
  {
    widgetPackageName = pn;
  }

  /**
   * Get the default widget package name
   * @return the default widget package name
   */
  public String getWidgetPackageName()
  {
    return widgetPackageName;
  }

  /**
   * Get the applet document base.
   * @return the url
   */
  public URL getDocumentBase()
  {
    return documentBase;
  }

  /**
   * Set/Record the URL from which the applet was loaded
   * @param u The path to the start directory
   */
  public void setDocumentBase( URL u )
  {
    documentBase = u;
  }

  /**
   * Set tbe applet reference
   * @param applet The XApplet
   */
  public void setApplet( Applet applet )
  {
    app = applet;
  }

  /**
   * Set tbe startup object reference
   * @param so the XStartupObject
   */
  public void setStartupObject( XStartupObject so )
  {
    startupObject = so;
  }

  /**
   * Set the main Frame reference
   * @param frame The main application frame
   */
  public void setAppFrame( Frame frame )
  {
    appFrame = frame;
  }

  /**
   * Set the main Window reference
   * @param window The main application window
   */
  public void setAppWindow( Window window )
  {
    appWindow = window;
  }

  /**
   * Get a reference to the applet object
   * @return a reference to the applet
   */
  public Applet getApplet()
  {
    return app;
  }

  /**
   * Get the startup object
   * @return the startup object
   */
  public XStartupObject getStartupObject()
  {
    return startupObject;
  }
 
  /**
   * Get a areference to the applet's Frame
   * @return a reference to the frame
   */
  public Frame getAppFrame()
  {
    return appFrame;
  }

  /**
   * Get a reference to the application's main Window
   * @return a reference to the Window
   */
  public Window getAppWindow()
  {
    return appWindow;
  }

  /**
   * Taken from java.io.File in JDK 1.4
   * @param path The path to be corrected
   * @param isDirectory Does the path lead to a directory?
   * @return The corrected path String
   */
  protected String slashify( String path, boolean isDirectory )
  {
    String p = path;
    if ( File.separatorChar != '/' )
      p = p.replace( File.separatorChar, '/' );
    if ( !p.startsWith( "/" ) )
      p = "/" + p;
    if ( !p.endsWith( "/" ) && isDirectory )
      p = p + "/";
    return p;
  }

  /**
   * Returns an Image, or null if the path was invalid.
   * @param imgStream The InputStream from which the image is to be read
   * @return The Image created from the InputStream
   */
  protected Image createImage( InputStream imgStream )
  {
    int MAX_IMAGE_SIZE = 75000; //Change this to the size of
    //your biggest image, in bytes.
    int count = 0;
    if ( imgStream != null ) {
      byte buf[] = new byte[ MAX_IMAGE_SIZE ];
      try {
        count = imgStream.read( buf );
      }
      catch ( IOException ieo ) {
        System.err.println( "Couldn't read stream from file" );
      }

      try {
        imgStream.close();
      }
      catch ( IOException ieo ) {
        System.err.println( "Can't close file" );
      }

      if ( count <= 0 ) {
        System.err.println( "Empty file" );
        return null;
      }
      return Toolkit.getDefaultToolkit().createImage( buf );
    }
    return null;
  }

  /**
   * Get the default file encoding (UTF8 unless modified)
   * @return the encoding
   */
  public String getDefaultEncoding()
  {
    return defaultEncoding;
  }

  /**
   * Set the default file encoding (UTF8 unless modified)
   * see http://java.sun.com/j2se/1.4.2/docs/guide/intl/encoding.doc.html
   * @param encoding the encoding e.g. "UTF8" or "ISO-8859-1"
   */
  public void setDefaultEncoding( String encoding )
  {
    if ( encoding != null )
      defaultEncoding = encoding;
  }

  /**
   * Set the object to load language resource bundles
   * @param loader the new loader
   */
  public void setResourceBundleLoader( ResourceBundleLoader loader )
  {
    resourceBundleLoader = loader;
  }

  /**
   * Get the resource bundle loader
   * @return the loader
   */
  public ResourceBundleLoader getResourceBundleLoader()
  {
    return resourceBundleLoader;
  }

  /**
   * Get a resource bundle
   * @param name the unqualified name of the resource bundle
   * @return The ResourceBundle created from the passed name
   */
  public ResourceBundle getResourceBundle( String name )
  {
    Hashtable bundles = (Hashtable)getObject( "ResourceBundles" );   
    if ( bundles == null ) {
      bundles = new Hashtable();
      setObject( "ResourceBundles", bundles );
    }

    if ( name == null )
      name = "unnamed";

    Object res = bundles.get( name );
    if ( res == null ) {
      try {
        if ( resourceBundleLoader != null )
          res = resourceBundleLoader.getResourceBundle( name );
        else  
          res = new PropertyResourceBundle( getInputStream( name + ".properties" ) );
      }
      catch ( Exception ex ) {
        if ( BuildProperties.DEBUG )
          DebugLogger.logWarning( "Could not load the ResourceBundle: " + name );
        return null;
      }
      bundles.put( name, res );
    }
    return (ResourceBundle)res;
  }
 
  /**
   * Get the default translation object
   * @return the translation object that operates on the resource bundle
   */
  public XTranslator getTranslator()
  {
    return getTranslator( "" );
  }
 
  /**
   * Get the translation object for the named bundle.
   * @param name the name of the resource used for translation
   * @return the translation object that operates on the resource bundle
   */
  public XTranslator getTranslator( String name )
  {
    XTranslator translator = (XTranslator)getObject( "Translator" + name );
    if ( translator == null ) {
      String translatorClass = getStartupParam( "Translator" );
      if (( translatorClass == null ) || ( translatorClass.length() == 0 ))
        translatorClass = "net.xoetrope.xui.helper.XDefaultTranslator";
      try {
        translator = (XTranslator)ReflectionHelper.constructViaReflection( null, translatorClass, XProject.class, this );
        setObject( "Translator" + name, translator );
      }
      catch( Exception e )
      {
        if ( BuildProperties.DEBUG )
          e.getCause().printStackTrace();
      }
    }
    return translator;
  }

  /**
   * Set the default file/directory specification used to locate files by the
   * getOutputStream( String file, boolean useProjectParent ) method
   * @param file the file or directory specification
   */
  public void setDefaultFile( String file )
  {
    defaultFile = file;
  }
  //-End of Former XResourceManager methods-------------------------------------

  /**
   * Attempt to fix an error when running a XUI application
   * @param errorName the name of the error, this should correzpond to a fully
   * qualified class name or a class within the net.xoetrope.selfhealing package
   * @param sourceObj the instance of the class from which the error handler was
   * invoked, or the object being repaired
   * @param t throwable the exception that was trapped, or null
   */
  public boolean fixError( String errorName, Object sourceObj, Throwable t )
  {   
    return fixError( getClass(), errorName, sourceObj, t );
  }

  /**
   * Attempt to fix an error when running a XUI application
   * @param klass the class through which the healer wiull be loader
   * @param errorName the name of the error, this should correzpond to a fully
   * qualified class name or a class within the net.xoetrope.selfhealing package
   * @param sourceObj the instance of the class from which the error handler was
   * invoked, or the object being repaired
   * @param t throwable the exception that was trapped, or null
   */
  public boolean fixError( Class klass, String errorName, Object sourceObj, Throwable t )
  {
    if ( BuildProperties.DEBUG ) {
      try {
        String healer = errorName.trim();
        if ( healer.indexOf( "." ) < 0 )
          healer = "net.xoetrope.debug.selfhealing." + healer;
       
        Class cls = klass.getClassLoader().loadClass( healer );
        Object errorObj = cls.newInstance();
        Class[] argTypes = { XProject.class, Object.class, Throwable.class };
        Object[] args = new Object[ 3 ];
        args[ 0 ] = this;
        args[ 1 ] = sourceObj;
        args[ 2 ] = t;
        Method repairMethod = cls.getMethod( "fixError", argTypes );
        Object rc = repairMethod.invoke( errorObj, args );
        return true;
      }
      catch ( Exception e ) {
        Throwable cause = e.getCause();
        if ( cause != null )
          cause.printStackTrace();
        else
          e.printStackTrace();
      }
    }
   
    return false;
  }
  /**
   * Can the project access the default package. Within the editor the NetBeans
   * classloader causes problems if the default package is accessed!
   */
  public boolean canAccessDefaultPackage( ClassLoader cl, String path )
  {
    return true;
  }
}
TOP

Related Classes of net.xoetrope.xui.XProject

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.