Package org.xdoclet.plugin.ejb

Source Code of org.xdoclet.plugin.ejb.EjbJavaGeneratingPlugin$DynamicJavaClass

/*
* Copyright (c) 2005
* XDoclet Team
* All rights reserved.
*/
package org.xdoclet.plugin.ejb;

import java.io.File;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.generama.MergeableVelocityTemplateEngine;
import org.generama.QDoxCapableMetadataProvider;
import org.generama.WriterMapper;

import org.generama.defaults.JavaGeneratingPlugin;

import org.xdoclet.plugin.ejb.qtags.TagLibrary;

import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.BeanProperty;
import com.thoughtworks.qdox.model.ClassLibrary;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaClassCache;
import com.thoughtworks.qdox.model.JavaClassParent;
import com.thoughtworks.qdox.model.JavaSource;
import com.thoughtworks.qdox.model.Type;

/**
* Base JavaGeneratingPlugin for EjbRelated plugins<br>
* Contains code to override filename/classname creation for plugin to be
* able to be set using pattern/package/class tag values
*
* @qtags.ignore
*
* @author Diogo Quintela
* @version $Revision: 538 $
*/
public abstract class EjbJavaGeneratingPlugin extends JavaGeneratingPlugin implements EjbTypeResolver {
    /** The log object */
    protected final Log log;

    // For now, we are forcing to use velocity, maybe sometime, we may need to
    // pull down to a EjbVelocityJavaGeneratingPlugin, for example
    private final MergeableVelocityTemplateEngine templateEngine;
    /** Ejb Configuration object */
    protected final EjbConfig config;
    /** Ejb Utils */
    protected final EjbUtils ejbUtils;

    /** Directory of merge file(s) */
    protected File mergeDir;

    /** From Plugin#fileregex (private). Hacked to get a copy of */
    protected String fileregex;

    /** From Plugin#filereplace (private). Hacked to get a copy of */
    protected String filereplace;

    /** From Plugin#packageregex (private). Hacked to get a copy of */
    protected String packageregex;

    /** From Plugin#packagereplace (private). Hacked to get a copy of */
    protected String packagereplace;

    /** When false, files are only created when dirty. */
    protected boolean force;
   
    /** True if this plugin should explain what it's doing. */
    protected boolean verbose;
   
    public EjbJavaGeneratingPlugin(MergeableVelocityTemplateEngine templateEngine,
            WriterMapper writerMapper, EjbConfig config) {
        super(templateEngine, config.getMetadataProvider(), writerMapper);
        this.templateEngine = templateEngine;
        this.config = config;
        this.ejbUtils = new EjbUtils(config);
        this.log = getLog();
        registerTagLibraries(metadataProvider);

        if (log.isTraceEnabled()) {
            log.trace(getClass().getName() + " constructor was called.");
        }
    }

    protected void registerTagLibraries(QDoxCapableMetadataProvider provider) {
        new TagLibrary(provider);
    }

    public void setFileregex(String fileregex) {
        if (fileregex == null) {
            throw new NullPointerException();
        }

        this.fileregex = fileregex;
        super.setFileregex(fileregex);
    }

    protected void populateContextMap(Map map) {
        super.populateContextMap(map);
        map.put("util", getEjbUtils());
        map.put("version", getVersion());
    }

    public EjbVersion getVersion() {
        return getConfig().getEjbVersion();
    }

    public EjbUtils getEjbUtils() {
        return ejbUtils;
    }

    public EjbConfig getConfig() {
        return this.config;
    }

    public static Log getLog(Class clazz) {
        return LogFactory.getLog(clazz);
    }

    public Log getLog() {
        return getLog(getClass());
    }

    public Log getLogEx() {
        StackTraceElement[] stack = new Exception().getStackTrace();
        StackTraceElement callingMethod = stack[1];
        return LogFactory.getLog(callingMethod.getClassName() + '.' + callingMethod.getMethodName());
    }

    public void setFilereplace(String filereplace) {
        if (filereplace == null) {
            throw new NullPointerException();
        }

        this.filereplace = filereplace;
        super.setFilereplace(filereplace);
    }

    public void setPackageregex(String packageregex) {
        if (packageregex == null) {
            throw new NullPointerException();
        }

        this.packageregex = packageregex;
        super.setPackageregex(packageregex);
    }

    public void setPackagereplace(String packagereplace) {
        if (packagereplace == null) {
            throw new NullPointerException();
        }

        this.packagereplace = packagereplace;
        super.setPackagereplace(packagereplace);
    }

    protected String getLocalyDefinedFullClassName(JavaClass clazz) {
        // to be overriden if needed
        return null;
    }

    protected String getLocalyDefinedPackageName(JavaClass clazz) {
        // to be overriden if needed
        return null;
    }

    protected String getPatternBasedUnqualifiedName(JavaClass clazz) {
        // to be overriden if needed
        return null;
    }

    /**
     * The physical type for the generated java type
     *
     * @param clazz The source metadata class
     *
     * @return The type to use
     */
    public EjbJavaType getPhysicalType(JavaClass clazz) {
        EjbJavaType retType = null;
        String fullType = getLocalyDefinedFullClassName(clazz);

        if (fullType != null) {
            retType = new EjbJavaType(fullType);
        }

        if (retType == null) {
            String unqualifiedName = getPatternBasedUnqualifiedName(clazz);

            if (unqualifiedName == null) {
                unqualifiedName = clazz.getName();
                unqualifiedName = unqualifiedName.replaceAll(fileregex, filereplace);
            }

            String javaPackage = getLocalyDefinedPackageName(clazz);

            if (javaPackage == null) {
                javaPackage = clazz.getPackage();
                javaPackage = javaPackage.replaceAll(packageregex, packagereplace);
            }

            retType = new EjbJavaType(javaPackage, unqualifiedName);
        }

        return retType;
    }

    /**
     * The type to be referenced to, normally equals to physical generated type, this should be called when
     * some plugin tries to refer to the generate class by this plugin<br>
     * This supports a type that extends the physical type to be used.<br>
     *
     * See &#064;ejb.bean impl-class-name for example (not directly related ...)
     *
     * @param clazz The source metadata class
     *
     * @return The type to use
     */
    public EjbJavaType getVirtualType(JavaClass clazz) {
        return getPhysicalType(clazz);
    }

    public String getDestinationFilename(Object metadata) {
        return getPhysicalType((JavaClass) metadata).getName() + ".java";
    }

    public String getDestinationPackage(Object metadata) {
        return getPhysicalType((JavaClass) metadata).getPackage();
    }

    /**
     * A method called right before generation is called (one time if multiOutput is false, several otherwise).
     * Allows for late setting of directories for example in MergeableVelocityTemplateEngine
     *
     * @see MergeableVelocityTemplateEngine#addPath(String)
     */
    protected void preGenerate() {
        if ((mergeDir != null) && mergeDir.isDirectory()) {
            try {
                templateEngine.addPath(mergeDir.getPath());
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }

    public String getSetterName(BeanProperty prop) {
        StringBuffer retBuf = new StringBuffer(prop.getName());
        retBuf.setCharAt(0, Character.toUpperCase(retBuf.charAt(0)));
        retBuf.insert(0, "set");
        return retBuf.toString();
    }

    public String getGetterName(BeanProperty prop) {
        StringBuffer retBuf = new StringBuffer(prop.getName());
        retBuf.setCharAt(0, Character.toUpperCase(retBuf.charAt(0)));

        if (prop.getType().isA(new Type("boolean")) || prop.getType().isA(new Type("java.lang.Boolean"))) {
            retBuf.insert(0, "is");
        } else {
            retBuf.insert(0, "get");
        }

        return retBuf.toString();
    }

    /**
     * Setter for mergeDir property
     *
     * @param mergeDir The value for the property
     */
    public void setMergedir(File mergeDir) {
        this.mergeDir = mergeDir;
    }

    /**
     * Utility method called from script to resolve a mergeFile reference
     *
     * @param mergeFile The mergeFile to look for
     *
     * @return A File for mergeFile
     */
    public File getMergeFile(String mergeFile) {
        if ((mergeFile != null) && (mergeDir != null) && mergeDir.isDirectory()) {
            File retVal = new File(mergeDir, mergeFile);
            return isIn(retVal, mergeDir) ? retVal : null;
        }

//        if ((mergeFile != null) && (mergeDir != null) && mergeDir.isDirectory()) {
//            // The listing of mergeDir's files avoid possibly security issues in path resolving (paranoid?)
//            File[] files = mergeDir.listFiles();
//
//            for (int i = 0; i < files.length; i++) {
//                if (mergeFile.trim().equals(files[i].getName())) {
//                    return files[i];
//                }
//            }
//        }

        return null;
    }

    public String getPad(int depth) {
        StringBuffer retBuf = new StringBuffer();

        while (depth-- > 1) {
            retBuf.append("    ");
        }

        return retBuf.toString();
    }

    /**
     * Returns the force-flag.
     */
    public boolean isForce() {
        return force;
    }

    /**
     * Set the force flag. When false, the plugin will only generate target
     * files if the source file is newer.
     *
     * @param force
     */
    public void setForce(boolean force) {
        this.force = force;
    }
   
    /**
     * Returns whether or not this plugin is being ran in verbose mode.
     */
    public boolean isVerbose() {
        return verbose;
    }

    /**
     * Sets the verbose flag. When verbose = true, the plugin will explain
     * what it's doing, otherwise it will run silently.
     */
    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    /**
     * Returns true if the source file has been changed after the target file
     * has been generated.
     *
     * @param javaClass
     * @return
     */
    protected boolean isDestinationDirty(JavaClass javaClass) {
       
        if (force) return true;
       
        File destFile = getDestinationFile(javaClass);
        File sourceFile = getSourceFile(javaClass);

        return !(destFile.exists() &&
            sourceFile.lastModified() < destFile.lastModified());
    }
   
    /**
     * Returns a File object representing the Source File represented
     * by the given JavaClass
     * @param javaClass The source JavaClass
     * @return A File Object representing the source file.
     */
    protected File getSourceFile(JavaClass javaClass) {
        return new File(javaClass.getSource().getURL().getFile());       
    }

    /**
     * Returns a File object representing the destination File represented
     * by the given JavaClass
     *
     * @param javaClass The JavaClass for which to find the destination.
     * @return A File Object representing the destination file.
     */
    protected File getDestinationFile(JavaClass javaClass) {
        String packagePath = getDestinationPackage(javaClass).replace('.', '/');
        File dir = new File(getDestdirFile(), packagePath);
        String filename = getDestinationFilename(javaClass);
        return new File(dir, filename);
    }

    protected boolean isDynamicJavaClass(JavaClass clazz) {
        return clazz instanceof DynamicJavaClass;
    }

    protected JavaClass createDynamicJavaClass(String className, String packaze, String[] imports, QDoxCapableMetadataProvider metadataProvider) {
        JavaClass retVal = new DynamicJavaClass(className);
        JavaDocBuilder builder = new JavaDocBuilder(metadataProvider.getDocletTagFactory());
        retVal.setParent(createJavaClassParent(builder.getClassLibrary(), packaze, imports));
        retVal.setJavaClassCache(createJavaClassCache(builder, metadataProvider.getMetadata(), retVal));
        return retVal;
    }


    protected JavaClassParent createJavaClassParent(ClassLibrary classLibrary, String packaze, String[] importz) {
        JavaSource src = new JavaSource();
        src.setClassLibrary(classLibrary);
        for (int i = 0; importz != null && i < importz.length; i++) {
            src.addImport(importz[i]);
        }
        src.setPackage(packaze);
        return src;
    }

    protected JavaClassCache createJavaClassCache(final JavaClassCache classCache, Collection metadata, final JavaClass clz) {
        final Set javaClasses = new HashSet();
        javaClasses.addAll(metadata);
        javaClasses.add(clz);

        return new JavaClassCache() {
            public JavaClass[] getClasses() {
                log.trace("createJavaClassCache.getClasses()");
                return (JavaClass[])javaClasses.toArray(new JavaClass[0]);
            }

            public JavaClass getClassByName(final String name) {
                if (log.isTraceEnabled()) {
                    log.trace("createJavaClassCache.getClassByName() name="+name);
                }
                if (name == null) {
                    return null;
                }
                for (Iterator iter = javaClasses.iterator(); iter.hasNext();) {
                    JavaClass javaClass = (JavaClass)iter.next();
                    if (javaClass.getFullyQualifiedName().equals(name)) {
                        if (log.isTraceEnabled()) {
                            log.trace("createJavaClassCache.getClassByName() FOUND javaClass="+javaClass);
                        }
                        return javaClass;
                    }
                }
                if (log.isTraceEnabled()) {
                    log.trace("createJavaClassCache.getClassByName() NOT FOUND! Using  builder.getClassByName("+name+")");
                }
                // not found. Try to use JavaClassCache
                return classCache.getClassByName(name);
            }

        };
    }

    private static class DynamicJavaClass extends JavaClass {
        public DynamicJavaClass() {
            super();
        }
        public DynamicJavaClass(String name) {
            super(name);
        }
    }
}
TOP

Related Classes of org.xdoclet.plugin.ejb.EjbJavaGeneratingPlugin$DynamicJavaClass

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.