Package org.pf.file

Source Code of org.pf.file.FileLocator

// ===========================================================================
// CONTENT  : CLASS FileLocator
// AUTHOR   : Manfred Duchrow
// VERSION  : 1.3 - 14/03/2003
// HISTORY  :
//  17/05/2002  duma  CREATED
//  24/05/2002  duma  added    ->  toURL(), isFile(), isDirectory(), getAbsolutePath()
//  21/06/2002  duma  added    ->  realFile()
//  14/03/2003  duma  added    ->  getStandardizedPath(), getStandardizedAbsolutePath()
//
// Copyright (c) 2002-2003, by Manfred Duchrow. All rights reserved.
// ===========================================================================
package org.pf.file ;

// ===========================================================================
// IMPORTS
// ===========================================================================
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.pf.text.StringUtil;

/**
* This class mainly supports access to files which can be in the normal
* file directory structure or inside zip archives.
* The main purpose is to provide methods that transparently treat files
* the same way whether they are in the normal directory structure or
* inside archives.
* The syntax is simply to allow archive names in a path name at any place
* where a sub-directory name can be. <br>
* Examples: <br>
* <ul>
*   <li>d:\temp\archive.zip\config\nls.properties</li>
*   <li>/usr/java/jdk1.3/src.jar/java/io/File.java</li>
* </ul>
* @author Manfred Duchrow
* @version 1.3
*/
public class FileLocator
{
  // =========================================================================
  // CONSTANTS
  // =========================================================================
  private static final boolean DEBUG = false ;
  private static final String FILE_PROTOCOL_INDICATOR = "file:" + File.separator ;
  private static final String ARCHIVE_INDICATOR        = "!" + File.separator ;

  // =========================================================================
  // INSTANCE VARIABLES
  // =========================================================================
  private FileLocator parent = null ;
  protected FileLocator getParent() { return parent ; }
  protected void setParent( FileLocator newValue ) { parent = newValue ; }

  private File file = null ;
  protected File getFile() { return file ; }
  protected void setFile( File newValue ) { file = newValue ; }
 
  private ZipFile zipFile = null ;
  protected ZipFile getZipFile() { return zipFile ; }
  protected void setZipFile( ZipFile newValue ) { zipFile = newValue ;
  
  private boolean exists = true ;
  protected boolean getExists() { return exists ; }
  protected void setExists( boolean newValue ) { exists = newValue ; }
     
  private Exception exception = null ;
  protected Exception getException() { return exception ; }
  protected void setException( Exception newValue ) { exception = newValue ; }
     
  // =========================================================================
  // CLASS METHODS
  // =========================================================================
  /**
   * Create a file locator that corresponds to the given file name.
   */
  public static FileLocator create( File file )
  {
    FileLocator locator = new FileLocator() ;
   
    return locator.createFrom( file ) ;
  } // create()

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

  /**
   * Create a file locator that corresponds to the given file name.
   */
  public static FileLocator create( String filename )
  {
    return create( new File( filename ) ) ;
  } // create()

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

  private static FileLocator newWith( FileLocator aParent, String[] pathElements )
    throws Exception
  {
    FileLocator locator = new FileLocator() ;
   
    return locator.createFrom( aParent, pathElements ) ;
  } // newWith()

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

  // =========================================================================
  // CONSTRUCTORS
  // =========================================================================
  /**
   * Initialize the new instance with default values.
   */
  private FileLocator()
  {
    super() ;
  } // FileLocator()

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

  // =========================================================================
  // PUBLIC INSTANCE METHODS
  // =========================================================================

  /**
   * Returns the file that contains the data the locator points to.
   * If the locator points to a normal file in a directory, than
   * this file will be returned.
   * If the locator points to a file inside an archive, the file
   * will be unzipped into the <i><b>temp</i></b> directory and this
   * temp file will be returned.
   * If the locator points to a none existing file, this method
   * returns false.
   */
  public File realFile()
  {
    File aFile ;
    try
    {
      aFile = this.fileRef() ;
    }
    catch (Exception e)
    {
      aFile = null ;
    }
    return aFile ;
  } // realFile()

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

  /**
   * Returns whether or not the file specified by this locator exists.
   */
  public boolean exists()
  {
    return this.getExists() ;
  } // exists()

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

  /**
   * Returns whether or not the name specified by this locator
   * points to a file.
   */
  public boolean isFile()
  {
    try
    {
      if ( this.exists() )
        return this.isFileElement( this.getFile() ) ;
      else
        return false ;
    }
    catch(Exception e)
    {
      return false ;
    }
  } // isFile()

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

  /**
   * Returns whether or not the name specified by this locator
   * points to a directory.
   */
  public boolean isDirectory()
  {
    try
    {
      if ( this.exists() )
        return ! this.isFileElement( this.getFile() ) ;
      else
        return false ;
    }
    catch(Exception e)
    {
      return false ;
    }
  } // isDirectory()

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

  /**
   * Returns the size of the file or 0 if it does not exist.
   */
  public long size()
  {
    ZipEntry entry ;
   
    try
    {
      if ( this.isInArchive() )
      {
        entry = this.archiveEntry() ;
        // if ( DEBUG ) com.mdcs.joi.Inspector.inspectWait( entry ) ;
        return entry.getSize() ;
      }
      else
      {
        return this.getFile().length() ;
      }
    }
    catch(Exception ex)
    {
      if ( DEBUG ) ex.printStackTrace() ;
      return 0L ;
    }
  } // size()

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

  /**
   * Returns the timestamp of when the file was last modified
   * or 0 in any case of error.
   */
  public long lastModified()
  {
    ZipEntry entry ;
   
    try
    {
      if ( this.isInArchive() )
      {
        entry = this.archiveEntry() ;
        return entry.getTime() ;
      }
      else
      {
        return this.getFile().lastModified() ;
      }
    }
    catch(Exception ex)
    {
      if ( DEBUG ) ex.printStackTrace() ;
      return 0L ;
    }
  } // lastModified()

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

  /**
   * Returns an opened input stream on the file defined by this locator.
   */
  public InputStream getInputStream()
    throws Exception
  {
    ZipEntry entry ;
   
    if ( this.isInArchive() )
    {
      entry = this.archiveEntry() ;
      return this.container().getInputStream( entry ) ;
    }
    else
    {
      return new FileInputStream( this.getFile() ) ;
    }
  } // getInputStream()

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

  /**
   * Returns whether or not the file specified by this locator
   * is inside an archive.
   */
  public boolean isInArchive()
  {
    return this.getParent() != null ;
  } // isInArchive()

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

  /**
   * Returns the full pathname.
   */
  public String getPath()
  {
    return this.fullFilePath( false ).getPath() ;
  } // getPath()

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

  /**
   * Returns the full absolute pathname.
   */
  public String getAbsolutePath()
  {
    return this.fullFilePath( true ).getPath() ;
  } // getAbsolutePath()

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

  /**
   * Returns the full pathname in a standardized for.
   * That is all ".." and "." elements are removed and forward slashes are
   * used as separators of the remaining elements.
   */
  public String getStandardizedPath()
  {
    return this.fileUtil().standardize( this.getPath() ) ;
  } // getStandardizedPath()

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

  /**
   * Returns the full absolute pathname in a standardized form.
   * That is all ".." and "." elements are removed and forward slashes are
   * used as separators of the remaining elements.
   */
  public String getStandardizedAbsolutePath()
  {
    return this.fileUtil().standardize( this.getAbsolutePath() ) ;
  } // getStandardizedAbsolutePath()

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

  /**
   * Returns the last exception that occured while using this locator
   * or null, if no exception was thrown at all.
   */
  public Exception exception()
  {
    return this.getException() ;
  } // exception()

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

  /**
   * Returns the name of the file as an URL.
   */
  public URL toURL()
    throws MalformedURLException
  {
    StringBuffer buffer = new StringBuffer( 128 ) ;
   
    this.urlPath( buffer ) ;
    return new URL( buffer.toString() ) ;
  } // toURL()

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

  // =========================================================================
  // PROTECTED INSTANCE METHODS
  // =========================================================================

  protected FileLocator createFrom( File filePath )
  {
    FileLocator locator  = null ;
    String[] parts       = null ;
    File path            = filePath ;
   
    if ( path.getPath().startsWith( FILE_PROTOCOL_INDICATOR ) )
      path = this.convertFromURLSyntax( path ) ;
     
    parts = str().parts( path.getPath(), File.separator ) ;
    try
    {
       locator = this.initFromPath( parts, path.getPath().startsWith( File.separator ) ) ;
    }
    catch ( Exception ex )
    {
      this.setException( ex ) ;
      this.doesNotExist( path ) ;
      locator = this ;
    }
    return locator ;
  } // createFrom()

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

  private FileLocator createFrom( FileLocator aParent, String[] pathElements )
    throws Exception
  {
    this.setParent( aParent ) ;
    return this.initFromPath( pathElements, false ) ;
  } // createFrom()

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

  protected FileLocator initFromPath( String[] parts, boolean startsFromRoot )
    throws Exception
  {
    FileLocator locator      = this ;
    File pathElement         = null ;
    String[] rest            = null ;
    boolean elementExists    = false ;
   
    if ( startsFromRoot )
      pathElement = new File( File.separator ) ;
   
    for ( int i = 0 ; i < parts.length ; i++ )
    {
      if ( pathElement == null )
        pathElement = new File( parts[i] ) ;
      else
        pathElement = new File( pathElement, parts[i] ) ;

      elementExists = this.doesElementExist( pathElement ) ;
     
      if ( elementExists )
      { 
        this.setFile( pathElement ) ;
        if ( this.isFileElement( pathElement ) )
        {
          if ( DEBUG ) System.out.println( "Locator(" + pathElement + ")" ) ;
          if ( i < ( parts.length - 1 ) )  // Is not last element ?
          {
            rest = str().copyFrom( parts, i + 1 ) ;
            // if (DEBUG) com.mdcs.joi.Inspector.inspect( "SubLocator", rest ) ;
            locator = FileLocator.newWith( this, rest ) ;
          }
          break ;
        }
      }
      else
      {
        if ( this.isInArchive() )
        {
          if ( i < ( parts.length - 1 ) )  // Is not last element ?
          {
            // Directories are not always identifiable individually in zip archives.
            // Therefore it must be accepted that they are not found.
            // So in such case no exception will be thrown.
          }
          else
          {
            throw new Exception( "\"" + pathElement.getPath() + "\" does not exist" );
          }
        }
        else
        {
          throw new Exception( "\"" + pathElement.getPath() + "\" does not exist" );
        }
      }
    }
    return locator ;
  } // initFromPath()

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

  protected boolean doesElementExist( File element )
    throws Exception
  {
    if ( this.isInArchive() )
    {
      return doesElementExistInArchive( element.getPath() ) ;     
    }
    else
    {
      return element.exists() ;
    }
  } // doesElementExist()

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

  protected boolean isFileElement( File element )
    throws Exception
  {
    if ( this.isInArchive() )
    {
      return isFileInArchive( element.getPath() ) ;     
    }
    else
    {
      return element.isFile() ;
    }
  } // isFileElement()

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

  protected boolean doesElementExistInArchive( String elementName )
    throws Exception
  {
    ZipEntry entry ;

    entry = this.entryFromArchive( elementName ) ;
       
    return ( entry != null ) ;
  } // doesElementExistInArchive()

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

  protected boolean isFileInArchive( String elementName )
    throws Exception
  {
    ZipEntry entry ;
    entry = this.entryFromArchive( elementName ) ;
   
    // Unfortunately entry.isDirectory() returns false even for
    // pure directory entries inside a zip archive, so it can't be used here.
    // The trick below is problematic, because apart from
    // directories it will also not recognize files with size 0.
   
    return ( entry != null ) && ( entry.getSize() > 0 ) ;
  } // isFileInArchive()

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

  protected ZipEntry entryFromArchive( String elementName )
    throws Exception
  {
    ZipEntry entry ;
    ZipFile archive ;
    String name ;
   
    name = str().replaceAll( elementName, "\\", "/" ) ;
    archive = this.container() ;
    entry = archive.getEntry( name ) ;

    if (DEBUG)
    {
      // if ( entry == null ) com.mdcs.joi.Inspector.inspect( name ) ;
      System.out.print( archive.getName() + "::" + name + " --- "
                + ( entry != null ) ) ;
      if ( entry == null )
      {
        System.out.println() ;       
      }
      else
      {
        System.out.print( " (" + entry.getSize()  + ")" ) ;
        System.out.print( " (T:" + entry.getTime()  + ")" ) ;
        System.out.println( " (" + ( entry.isDirectory() ? "Dir" : "File" ) + ")" ) ;
      }
    }
   
    return entry ;
  } // entryFromArchive()

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

  protected ZipEntry archiveEntry()
    throws Exception
  {
    return this.entryFromArchive( this.getFile().getPath() ) ;
  } // archiveEntry()

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

  protected void doesNotExist( File file )
  {
    this.setExists( false ) ;
    this.setFile( file ) ;
  } // doesNoTExist()

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

  protected File fullFilePath( boolean absolute )
  {
    File full ;
   
    if ( this.isInArchive() )
    {
      full = new File(   this.getParent().fullFilePath( absolute ),
                        this.getFile().getPath() ) ;
    }
    else
    {
      if ( absolute )
        full = this.getFile().getAbsoluteFile() ;
      else
        full = this.getFile() ;
    }
   
    return full ;
  } // fullFilePath()

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

  protected void urlPath( StringBuffer buffer )
  {
    if ( this.isInArchive() )
    {
      this.getParent().urlPath( buffer ) ;
      buffer.append( ARCHIVE_INDICATOR ) ;
    }
    else
    {
      buffer.append( FILE_PROTOCOL_INDICATOR ) ;
    }   
    buffer.append( this.getFile().getPath() ) ;
  } // urlPath()

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

  protected File fileRef()
    throws Exception
  {
    InputStream archiveStream ;
    FileOutputStream fileStream ;
    ZipEntry entry ;
    File tempFile ;
   
    if ( this.isInArchive() )
    {
      entry = this.archiveEntry() ;
      archiveStream = this.container().getInputStream( entry ) ;
      tempFile = File.createTempFile( "FLOC_", ".xtr" ) ;
      tempFile.deleteOnExit() ;
      fileStream = new FileOutputStream( tempFile ) ;
      fileUtil().copyStream( archiveStream, fileStream ) ;
      return tempFile ;
    }
    else
    {
      return this.getFile() ;
    }
  } // fileRef()

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

  /**
   * Returns the file this locator presents as opened zip file or
   * null in any case of error.
   */
  protected ZipFile archive()
    throws Exception
  {
    if ( this.getZipFile() == null )
    {
      this.setZipFile( new ZipFile( this.fileRef() ) ) ;
    }
    return this.getZipFile() ;
  } // archive()

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

  /**
   * Returns the zip file which is presented by the parent container
   * or null in any case of error.
   */
  protected ZipFile container()
    throws Exception
  {
    if ( this.isInArchive() )
      return this.getParent().archive() ;
    else
      return null ;
  } // container()

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

  protected File convertFromURLSyntax( File file)
  {
    String newStr ;
   
    newStr = file.getPath().substring( FILE_PROTOCOL_INDICATOR.length() ) ;
    newStr = str().replaceAll( newStr, ARCHIVE_INDICATOR, File.separator ) ;
   
    return new File( newStr ) ;
  } // convertFromURLSyntax()
 
  // -------------------------------------------------------------------------

  protected StringUtil str()
  {
    return StringUtil.current() ;
  } // str()
 
  // -------------------------------------------------------------------------

  protected FileUtil fileUtil()
  {
    return FileUtil.current() ;
  } // fileUtil()
 
  // -------------------------------------------------------------------------

} // class FileLocator
TOP

Related Classes of org.pf.file.FileLocator

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.