FileDocCategorySizeDatePackage
ClassFileSource.javaAPI DocGlassfish v2 API13355Fri May 04 22:34:38 BST 2007com.sun.jdo.api.persistence.enhancer.util

ClassFileSource

public class ClassFileSource extends Support
ClassFileSource provides a mechanism for associating a class with the source of that class. The source is currently either an ordinary .class file or a zip file 1 or more class files.

Fields Summary
private String
theOriginalExpectedClassName
private String
theExpectedClassName
private File
classFile
private ZipFile
zipFile
private InputStream
byteCodeStream
private ClassPathElement
sourceElement
private long
cachedModDate
Constructors Summary
public ClassFileSource(String className, File classFile)
Constructor

param
className The expected name of the class
param
classFile The file containing the class. This file should exist and be readable.

    //@olsen: added println() for debugging
    //System.out.println("ClassFileSource(): new class = " + className);
    theExpectedClassName = className;
    theOriginalExpectedClassName = className;
    this.classFile = classFile;
  
public ClassFileSource(String className, ZipFile zipFile)
Constructor

param
className The expected name of the class
param
classFile The zip file containing the class. This file should exist and be readable.

    //@olsen: added println() for debugging
    //System.out.println("ClassFileSource(): new class = " + className);
    theExpectedClassName = className;
    theOriginalExpectedClassName = className;
    this.zipFile = zipFile;
  
public ClassFileSource(String className, InputStream byteCodeStream)
Constructor

param
className The expected name of the class
param
classFile The zip file containing the class. This file should exist and be readable.

    //@olsen: added println() for debugging
    //System.out.println("ClassFileSource(): new class = " + className);
    theExpectedClassName = className;
    theOriginalExpectedClassName = className;
    this.byteCodeStream = byteCodeStream;
  
Methods Summary
public java.io.DataInputStreamclassFileContents()
Get a DataInputStream containing the class file. Restriction: containingFilePath() must be non-null.

/*
      //@yury: ArchiveEntry case sanity check
      if ( null != archiveEntry) {
	  return new DataInputStream(new BufferedInputStream(archiveEntry.createInputStream()));
      }
*/
    //@olsen: cosmetics
    if (isZipped()) {
      ZipEntry entry =
	zipFile.getEntry(ClassPath.zipFileNameOf(theExpectedClassName));
      if (entry == null)
	throw new FileNotFoundException(
	"The zip file member " + theExpectedClassName + " was not found.");
      return new DataInputStream(zipFile.getInputStream(entry));
    }
    //@olsen: added case
    if (isStreamed()) {
      return new DataInputStream(byteCodeStream);
    }
    return new DataInputStream(
      new BufferedInputStream(
	new FileInputStream(classFile)));
  
public java.io.FilecomputeDestination(java.io.File destDir)
Compute the destination file for the class. If destDir is non-null, use that as a destination location Restriction: if containingFilePath() is null, null is returned.

      if (destDir != null) {
	File finalDestDir = computeDestinationDir(destDir);
	String theFinalClassComponent = "";//NOI18N
	StringTokenizer parser =
            new StringTokenizer(theExpectedClassName, "/", false);//NOI18N
	while (parser.hasMoreTokens())
	  theFinalClassComponent = parser.nextToken();
	return new File(finalDestDir, theFinalClassComponent + ".class");//NOI18N
      }
      else
	/* Note: this is wrong when repackaging occurs but we currently
	   require a destination directory to be specified, so it doesn't
	   matter. */
	return classFile;
  
private java.io.FilecomputeDestinationDir(java.io.File rootDestDir)
Compute the destination directory for the class. rootDestDir must be non-null - use that as a destination location root, ensuring its existence.


    StringBuffer buf = new StringBuffer(rootDestDir.getPath());
    String prevToken = null;
    StringTokenizer parser
        = new StringTokenizer(theExpectedClassName, "/", false);//NOI18N
    while (parser.hasMoreTokens()) {
      if (prevToken != null) {
	buf.append(File.separatorChar);
	buf.append(prevToken);

	File currDir = new File(buf.toString());
	if (!currDir.isDirectory()) {
	  if (!currDir.mkdir())
            //@olsen: support for I18N
            throw new UserException(
                getI18N("enhancer.unable_to_create_dir",//NOI18N
                      currDir.getPath()));
	}
      }
      prevToken = parser.nextToken();
    }
    return new File(buf.toString());
  
public java.lang.StringcontainingFilePath()
Get the path of the File containing the class

    if (isZipped())
      return zipFile.getName();
    else if (classFile != null)
      return classFile.getPath();
    else
      return null;
  
public java.lang.StringexpectedClassName()
The expected name of the class contained in the class file. Returns null if the class name can not be intuited from the file name.

    return theExpectedClassName;
  
public com.sun.jdo.api.persistence.enhancer.util.ClassFileSourcefriendSource(java.lang.String className)
Build a "friend" source file specification for the class of the given name. That is, the new class file source should be in the same zip file if zipped or else the same directory. Restriction: containingFilePath() must be non-null.

/*
      //@yury: ArchiveEntry case sanity check
      if ( null != archiveEntry) {
	  throw new IllegalArgumentException("----- Not implemented yet");
      }
*/

    if (isZipped())
      return new ClassFileSource(className, zipFile);
    else {
      String fullPath = FilePath.getAbsolutePath(classFile);
      File dir = new File(fullPath.substring(
	   0, fullPath.lastIndexOf(File.separatorChar)+1));
      File f = new File(dir, unpackagedName(className) + ".class");//NOI18N
      return new ClassFileSource(className, f);
    }
  
public java.io.DataOutputStreamgetOutputStream(java.io.File dest)
Get a DataOutputStream to which a class file should be written. The caller must close the output stream when complete.

/*
      //@yury: ArchiveEntry case sanity check
      if ( null != archiveEntry) {
	  throw new IllegalArgumentException("----- Must never call here");
      }
*/

    /* If this were a zipped file we would need to do some fancy footwork */
    return new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
  
public booleanisStreamed()
Does this class originate in a zip file?

    return byteCodeStream != null;
  
public booleanisZipped()
Does this class originate in a zip file?

    return zipFile != null;
  
public longmodificationDate()
Get the modification date of the class file. The date format is that used by java.util.Date. Restriction: containingFilePath() must be non-null.

    if (cachedModDate == 0) {
/*
	//@yury: ArchiveEntry case sanity check
	if ( null != archiveEntry) {
	    throw new IllegalArgumentException("----- Not implemented yet");
	}
*/

      if (isZipped()) {
	ZipEntry entry =
	  zipFile.getEntry(ClassPath.zipFileNameOf(theOriginalExpectedClassName));
	if (entry == null)
	  throw new FileNotFoundException("The zip file member was not found.");
	cachedModDate = entry.getTime();
      }
      else if (classFile != null)
	cachedModDate = classFile.lastModified();
    }

    return cachedModDate;
  
public com.sun.jdo.api.persistence.enhancer.util.ClassFileSourcenextSource(java.lang.String className)
Attempt to find the next possible source of the class

    if (sourceElement != null && sourceElement.next() != null)
      return ClassPath.findClass(className, sourceElement.next());
    return null;
  
public booleansameAs(com.sun.jdo.api.persistence.enhancer.util.ClassFileSource other)
Does the other class file source refer to the same source location?

//  private ArchiveEntry archiveEntry; //@yury: added ability to get the class bytecode from the Forte4J archive entry

    //@yury archive entry getter
            
     /*
    public ArchiveEntry getArchiveEntry() {
	return archiveEntry;
    }
    */

  /* public access */

                 
      

/*
      //@yury: added ArchiveEntry processing [[[[
      if ((null == getArchiveEntry()) ^ (null == getArchiveEntry())) {
	  return false;
      }

      if (null != getArchiveEntry() ) {
	  return getArchiveEntry().getName().equals(other.getArchiveEntry().getName());
      }
      //@yury: added ArchiveEntry processing ]]]]]
*/

    //^olsen: simplify control flow
    if (isZipped())
      return (other.isZipped() &&
	      other.zipFile.getName().equals(zipFile.getName()));
    else if (other.isZipped())
      return false;
    else if (other.classFile != null && classFile != null)
      return other.classFile.getPath().equals(classFile.getPath());
    //@olsen: added test
    else if (byteCodeStream != null)
      return byteCodeStream.equals(other.byteCodeStream);
    return false;
  
public voidsetExpectedClassName(java.lang.String name)
Set the name of the class contained in the class file.

    theExpectedClassName = name;
  
public voidsetModificationDate(long date)
Set the cached modification date of the class file. This doesn't actually update the file.

    cachedModDate = date;
  
voidsetSourceElement(ClassPathElement cpathElement)
Set the ClassPathElement through which this was located

    sourceElement = cpathElement;
  
private java.lang.StringunpackagedName(java.lang.String className)
Return the name of the class, ignoring any leading package specification.

    int idx = className.lastIndexOf((int) '/");
    if (idx < 0)
      return className;
    return className.substring(idx+1);