FileDocCategorySizeDatePackage
ClassControl.javaAPI DocGlassfish v2 API31255Fri May 04 22:34:38 BST 2007com.sun.jdo.api.persistence.enhancer.impl

ClassControl

public final class ClassControl extends com.sun.jdo.api.persistence.enhancer.util.Support
ClassControl acts as the primary handle for a class within the filter tool. ClassControl instances are typically accessed through various methods on Environment.

Fields Summary
public static final int
TransientOnly
public static final int
PersistUnknown
public static final int
PersistAware
public static final int
PersistCapable
public static final int
UpdateNotNeeded
public static final int
UpdateUnknown
public static final int
UpdateNew
public static final int
UpdateNewer
private final Environment
env
private final com.sun.jdo.api.persistence.enhancer.util.ClassFileSource
theClassSource
private com.sun.jdo.api.persistence.enhancer.classfile.ClassFile
theClass
private int
persistenceType
private int
updateType
private final ClassAction
classAction
private boolean
classUpdated
Constructors Summary
public ClassControl(com.sun.jdo.api.persistence.enhancer.util.ClassFileSource theSource, com.sun.jdo.api.persistence.enhancer.classfile.ClassFile theFile, Environment env)
Constructor

        theClassSource = theSource;
        theClass = theFile;
        theClassSource.setExpectedClassName(className());
        classAction = new ClassAction(this, env);
        this.env = env;

        if (false) {
            System.out.println("ClassControl(): new class = " + className());//NOI18N
        }
    
public ClassControl(com.sun.jdo.api.persistence.enhancer.util.ClassFileSource theSource, Environment env)
Constructor

        theClassSource = theSource;
        buildTheClass(true /* allowJDK12ClassFiles */);
        theClassSource.setExpectedClassName(className());
        classAction = new ClassAction(this, env);
        this.env = env;

        if (false) {
            System.out.println("ClassControl(): new class = " + className());//NOI18N
        }
    
Methods Summary
public ClassActionaction()
Get the ClassAction for this class

        return classAction;
    
public voidannotate()
perform necessary annotation actions on the class

        //@olsen: added support for timing statistics
        try{
            if (env.doTimingStatistics()) {
                Support.timer.push("ClassControl.annotate()");//NOI18N
            }
            if (annotateable()) {
                if (filterRequired()) {
                    classAction.annotate();
                } else {
                    env.message("skipping " + userClassName() + //NOI18N
                                " because it is already up to date.");//NOI18N
                }
            }
        } finally {
            if (env.doTimingStatistics()) {
                Support.timer.pop();
            }
        }
    
public booleanannotateable()
Return true if the class is one which should be a candidate for annotation.

//@olsen: disabled feature: isImplicitlyPersistent()
/*
        return (initialPersistenceType == PersistCapable ||
                initialPersistenceType == PersistAware ||
                isImplicitlyPersistent());
*/
        //@olsen: changed to check each class not explicitly known as transient
        return (persistenceType >= PersistUnknown);
    
public voidaugment()
Reparent class if needed

        //@olsen: added support for timing statistics
        try{
            if (env.doTimingStatistics()) {
                Support.timer.push("ClassControl.augment()");//NOI18N
            }
            if (annotateable()) {
                //@olsen: dropped argument: boolean filterRequired
                //classAction.augment(filterRequired());
                if (filterRequired()) {
                    classAction.augment();
                } else {
                    //@olsen: added output
                    env.message("skipping " + userClassName() + //NOI18N
                                " because it is already up to date.");//NOI18N
                }
            }
        } finally {
            if (env.doTimingStatistics()) {
                Support.timer.pop();
            }
        }
    
private voidbuildTheClass(boolean allowJDK12ClassFiles)
Constructs the ClassFile for the class

        if (false) {
            System.out.println("Reading class "//NOI18N
                               + theClassSource.expectedClassName());
        }

        //@olsen: cosmetics
        //try {
        //    try {
        //    } catch (FileNotFoundException e) {
        //    }
        //} catch (IOException e) {
        //}
        try {
            DataInputStream dis = theClassSource.classFileContents();
            theClass = new ClassFile(dis);
            dis.close();
        } catch (FileNotFoundException e) {
            // File should already have been tested for existence
            //@olsen: support for I18N
            throw new UserException(
                getI18N("enhancer.file_not_found",//NOI18N
                        sourceName()),
                e);
        } catch (IOException e) {
            //@olsen: support for I18N
            throw new UserException(
                getI18N("enhancer.io_error_while_reading_file",//NOI18N
                        sourceName()),
                e);
        }
    
private voidcheckUpdateType()
Check to see if output class for this class is up-to-date with respect to its input class. Set updateType to reflect what type of update of the output class is needed, if any.

        if (updateType == UpdateUnknown) {
            String lookupName;

            //@olsen: added inplace of disable featured
            lookupName = className();
//@olsen: disabled feature
/*
            // check to see if it exists in the updated form
            String pkg = pkg();
            String xlat = (String) env.translations().get(pkg);
            if (xlat != null) {
                if (xlat.length() == 0)
                    lookupName = unpackagedName();
                else
                    lookupName = xlat + "/" + unpackagedName();
            } else {
                lookupName = className();
            }
*/

            ClassFileSource annotatedSource;
            if (env.updateInPlace() && !theClassSource.isZipped())
                annotatedSource = theClassSource;
            else
                annotatedSource = env.lookupDestClass(lookupName);

            if (annotatedSource == null) {
                // No annotated class exists
                updateType = UpdateNew;
            } else {
                try {
                    long annModDate = annotatedSource.modificationDate();
                    long srcModDate = source().modificationDate();
                    if (annModDate < srcModDate) {
                        // An annotated class exists, but it is older than
                        // the input
                        updateType = UpdateNewer;
                    } else {
                        if (annotatedSource == theClassSource
                            && !action().hasAnnotatedAttribute()) {
                            // An unannotated class file to be updated
                            // in-place
                            if (persistenceType == PersistCapable
                                || persistenceType == PersistAware)
                                updateType = UpdateNewer;
                            else
                                updateType = UpdateNotNeeded;
                        } else {
                            //@olsen: an annotated class exists, which is
                            // newer than the input
                            updateType = UpdateNotNeeded;
                        }
                    }
                } catch (FileNotFoundException e) {
                    // shouldn't occur, but if it does, handle it
                    updateType = UpdateNew;
                }
            }
        }
    
public com.sun.jdo.api.persistence.enhancer.classfile.ClassFileclassFile()
Get the ClassFile data structure for the class

        return theClass;
    
public java.lang.StringclassName()
Return the class name in VM form

        ConstClass cname = theClass.className();
        return (cname == null) ? null : cname.asString();
    
public booleanfilterRequired()
Return true if filtering of the class is required. This checks only whether the filtered version of the class is up to date w.r.t. its input class.

        if (updateType == UpdateUnknown)
            checkUpdateType();
//@olsen: optimized code
        return (updateType > UpdateUnknown || env.forceOverwrite());
/*
        return (updateType == UpdateNew
                || updateType == UpdateNewer
                || env.forceOverwrite());
*/
    
public voidnoteUpdate()
Record a modification of the class

        classUpdated = true;
    
public static java.lang.StringpackageOf(java.lang.String vmName)
Return the vm package name for the vm class name

        int last = vmName.lastIndexOf('/");
        if (last < 0)
            return "";//NOI18N
        return vmName.substring(0, last);
    
public intpersistType()
Return the persistence type for this class

        return persistenceType;
    
public java.lang.Stringpkg()
Return the vm package name for this class

        return packageOf(className());
    
public voidrequireUpdate()
Mark the class as requiring update.

        updateType = UpdateNew;
    
public voidscan1()
Note the class characteristics

        //@olsen: added support for timing statistics
        try{
            if (env.doTimingStatistics()) {
                Support.timer.push("ClassControl.scan1()");//NOI18N
            }
            //@olsen: added: set the persistent type of class
            setPersistenceType();

//@olsen: disabled feature
/*
            if (annotateable() || implementsPersistenceCapable()) {
*/

            if (annotateable()) {
                //@olsen: dropped argument: boolean filterRequired
                //classAction.scan1(filterRequired());
                if (filterRequired()) {
                    classAction.scan1();
                } else {
                    //@olsen: added output
                    env.message("skipping " + userClassName() + //NOI18N
                                " because it is already up to date.");//NOI18N
                }
            }
        } finally {
            if (env.doTimingStatistics()) {
                Support.timer.pop();
            }
        }
    
private voidsetPersistenceType()
Sets the persistence type of a class by JDO meta-data.

        final JDOMetaData meta = env.getJDOMetaData();

        //@olsen: skip class if its persistence type is already known
        if (persistenceType != PersistUnknown) {
            return;
        }

        //@olsen: check whether class is an interface
        if (classFile().isInterface()) {
            persistenceType = TransientOnly;
            return;
        }

        //@olsen: check whether class is known to be transient
        final String className = className();
        if (meta.isTransientClass(className)) {
            persistenceType = TransientOnly;
            return;
        }

        //@olsen: check whether class is persistence-capable
        if (meta.isPersistenceCapableClass(className)) {
            persistenceType = PersistCapable;

            //@olsen: for Dogwood, check limitation on PC-inheritance
            affirm(meta.isPersistenceCapableRootClass(className),
                   ("Sorry, not supported yet: the persistent-capable class "//NOI18N
                    + userClassName()
                    + "cannot extend a persistent-capable super-class."));//NOI18N
        }
    
public com.sun.jdo.api.persistence.enhancer.util.ClassFileSourcesource()
Return the source of the class

        return theClassSource;
    
public java.lang.StringsourceName()
Return the name of the class source

        return theClassSource.containingFilePath();
    
public booleanupdated()
Return true if the classfile has been updated


    /* If true, this class was renamed via repackaging */
//@olsen: disabled feature
/*
    private boolean classRenamed;
*/

    // public accessors

                 
       
        return classUpdated;
    
public static java.lang.StringuserClassFromVMClass(java.lang.String vmName)
Return the class name in user ('.' delimited) form

        return vmName.replace('/", '.");
    
public java.lang.StringuserClassName()
Return the class name in user ('.' delimited) form

        return userClassFromVMClass(className());
    
public static java.lang.StringvmClassFromUserClass(java.lang.String userName)
Return the class name in VM ('/' delimited) form

        return userName.replace('.", '/");
    
public voidwrite(java.io.File destFile)
Write the file. If destination directory is non-null, write the file relative to that directory, else write it relative to its original location.

        DataOutputStream dos =
            theClassSource.getOutputStream(destFile);
        theClass.write(dos);
        dos.close();