Now there is a GenIC-Task for ant
which checks dependencys.

So if you develop client-apps for Jonas
and are bored about waiting for
redundant GenIC-runs then this
task for ant is for you !

simply compile this included java-file
(be sure to have RMI_jonas.jar and ant.jar
in your classpath before compiling).
put this new Genic.class in your classpath

include 
    <taskdef name="GenIC" classname="mytaskdefs.Genic" />
in your build file

and now you can use
    <GenIC base="${build}" xmlfile="${ejbsrc}/ejb-jar.xml" /> 
to start a GenIC-run.

GenIC will only run, when the XML-file specified
is newer than any of the generated class files !

comments and questions welcome.

--
markus
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package mytaskdefs;

import org.apache.tools.ant.*;
import java.io.*;
import java.util.StringTokenizer;
import org.objectweb.jonas.tools.GenIC;
import org.objectweb.jonas.tools.GenICException;
import org.objectweb.jonas.lib.BeanNaming;
import org.objectweb.jonas.deployment.api.DeploymentDesc;
import org.objectweb.jonas.deployment.api.BeanDesc;
import org.objectweb.jonas.deployment.api.SessionDesc;
import org.objectweb.jonas.deployment.api.DeploymentDescException;
import org.objectweb.jonas.lib.BeanNaming;

/**
 * Task to compile XML-DeploymentDescriptors with GenIC from Jonas
 *
 * following arguments are possible :
 * <ul>
 * <li>base: The base directory for the compiled stubs and skeletons
 * <li>xmlfile: The XML-file that contains the Deployment Desc
 * <li>clientstubs: Flag to generated the files for a client only (test)
 * </ul>
 * Of these arguments, the <b>base</b> and <b>xmlfile</b> are required.
 * <p>
 *
 * @author [EMAIL PROTECTED]
 * @author [EMAIL PROTECTED]
 * @author [EMAIL PROTECTED]
 */

public class Genic extends Task {

    private String base;
    private String xmlfilename;
                private String compileClasspath;
                private boolean clientstubs = false;

    public void setBase(String base) {
        this.base = base;
    }

    public void setXmlfile(String xmlfile) {
        this.xmlfilename = xmlfile;
    }

    public void setClientstubs(String clientstubs) {
        this.clientstubs = Project.toBoolean(clientstubs);
    }

    /**
     * Set the classpath to be used for this compilation.
     */
    public void setClasspath(String classpath) {
        compileClasspath = project.translatePath(classpath);
    }

    public void execute() throws BuildException {
        File xmlFile = project.resolveFile(xmlfilename);
        File baseFile = project.resolveFile(base);
            String absolutexmlfilename = xmlFile.getAbsolutePath(); 
        String classpath = getCompileClasspath(baseFile);
        boolean  isHelp          = false;
        boolean  isVerbose       = false;
        boolean  isKeepGenerated = false;
        boolean  isImplPropag    = true;
        boolean  isCompil        = true;
        boolean  isWithError     = false;
        String   nameJavaC     = new String("javac");
        String   optionsJavaC  = new String("-classpath " + classpath);
        String   optionsRmiC   = new String("-classpath " + classpath);

                // Parts of the following code are copied from GenIC.java (jonas)
                try {
                        DeploymentDesc ejbJarDD = null;
                        ejbJarDD = DeploymentDesc.getInstance(absolutexmlfilename,
                BeanNaming.getJonasXmlName(absolutexmlfilename));
                        BeanDesc[] beansDD = ejbJarDD.getBeanDesc();
                        project.log("Deployment Descriptor: "+ xmlfilename);
            boolean mustdo = false;
            for (int i=0; i<beansDD.length; i++) {
                if (dependencyCheck(beansDD[i],baseFile.getAbsolutePath(),xmlFile)) {
                    project.log("Bean Descriptor "+i+" needs to be done");
                        mustdo=true;
                }    
            }   

                if (mustdo) {
            for (int i=0; i<beansDD.length; i++) {
                GenIC gwc = new GenIC(beansDD[i], baseFile.getAbsolutePath(), 
isImplPropag);
                gwc.genImplRemoteClass(isWithError);
                gwc.genImplHomeClass(isWithError);
                gwc.genImplHandleClass(isWithError);
                if (isCompil) {
                    gwc.compilImplClasses(nameJavaC, optionsJavaC, optionsRmiC);
                }
                if (!isKeepGenerated) {
                    gwc.clean();
                }
                gwc = null;     // parano
            }
            }
        } catch (GenICException e) {
            throw new BuildException("GenIC ERROR: " + e.getMessage());
        } catch (DeploymentDescException e) {
                                                throw new BuildException("GenIC ERROR: 
When reading the Deployment Descriptors for "+xmlfilename + "\n" + e.getMessage());
        }
    }

    private boolean dependencyCheck(BeanDesc bd, String dirname, File xmlFile) {
        // again, parts of this code are copied from GenIC.java from jonas
            BeanNaming bn     = new BeanNaming(bd);
            String wrpRemoteBaseName = bn.getWrpRemoteName();
            String wrpRemoteName     = bn.getFullWrpRemoteName();
            String wrpHomeBaseName   = bn.getWrpHomeName();
            String wrpHomeName       = bn.getFullWrpHomeName();
            String wrpHandleBaseName = bn.getWrpHandleName();
            String wrpHandleName     = bn.getFullWrpHandleName();
        String wrpRemoteFileName = null;
        String wrpHomeFileName = null;
        String wrpHandleFileName = null;
        if (dirname.equals("")) {
            wrpRemoteFileName = new String(wrpRemoteBaseName + ".class");
            wrpHomeFileName   = new String(wrpHomeBaseName + ".class");
            wrpHandleFileName = new String(wrpHandleBaseName + ".class");
        } else {
            // FileName = directoryOutputName + '/' + packageName + '/' + 
wrpXxBaseName + ".java"
            String sDir;
            sDir = BeanNaming.getPackageName(wrpRemoteName);
            if (! sDir.equals("")) {
                sDir = sDir.replace('.', File.separatorChar);
                sDir = sDir + File.separatorChar;
            }
            wrpRemoteFileName = new String(dirname + File.separatorChar + sDir +
                                           wrpRemoteBaseName + ".class");
            sDir = BeanNaming.getPackageName(wrpHomeName);
            if (! sDir.equals("")) {
                sDir = sDir.replace('.', File.separatorChar);
                sDir = sDir + File.separatorChar;
            }
            wrpHomeFileName   = new String(dirname + File.separatorChar + sDir +
                                           wrpHomeBaseName + ".class");
            sDir = BeanNaming.getPackageName(wrpHandleName);
            if (! sDir.equals("")) {
                sDir = sDir.replace('.', File.separatorChar);
                sDir = sDir + File.separatorChar;
            }
            wrpHandleFileName   = new String(dirname + File.separatorChar + sDir +
                                           wrpHandleBaseName + ".class");
        }

        boolean check = false;
    File remoteFile = project.resolveFile(wrpRemoteFileName);
    File homeFile = project.resolveFile(wrpHomeFileName);
        if (bd instanceof SessionDesc) {
            // Session
        project.log("Dependency: " + wrpHomeFileName);
        if (xmlFile.lastModified() > homeFile.lastModified()) {
                project.log("--- todo");
            check = true;
        }
        project.log("Dependency: " + wrpRemoteFileName);
        if (xmlFile.lastModified() > remoteFile.lastModified()) {
                project.log("--- todo");
            check = true;
        }
        } else {
        File handleFile = project.resolveFile(wrpHandleFileName);
        project.log("Dependency: " + wrpHandleFileName);
        if (xmlFile.lastModified() > handleFile.lastModified()) {
                project.log("--- todo");
            check = true;
        }
        project.log("Dependency: " + wrpHomeFileName);
        if (xmlFile.lastModified() > homeFile.lastModified()) {
                project.log("--- todo");
            check = true;
        }
        project.log("Dependency: " + wrpRemoteFileName);
        if (xmlFile.lastModified() > remoteFile.lastModified()) {
                project.log("--- todo");
            check = true;
        }
        }
        return check;               
    }

    /**
     * Builds the compilation classpath.
     */

    // XXX
    // we need a way to not use the current classpath.

    private String getCompileClasspath(File baseFile) {
        StringBuffer classpath = new StringBuffer();

        // add dest dir to classpath so that previously compiled and
        // untouched classes are on classpath
        classpath.append(baseFile.getAbsolutePath());

        // add our classpath to the mix

        if (compileClasspath != null) {
            addExistingToClasspath(classpath,compileClasspath);
        }

        // add the system classpath

        addExistingToClasspath(classpath,System.getProperty("java.class.path"));
        // in jdk 1.2, the system classes are not on the visible classpath.

        if (Project.getJavaVersion().startsWith("1.2")) {
            String bootcp = System.getProperty("sun.boot.class.path");
            if (bootcp != null) {
                addExistingToClasspath(classpath, bootcp);
            }
        }
        return classpath.toString();
    }

     /**
     * Takes a classpath-like string, and adds each element of
     * this string to a new classpath, if the components exist.
     * Components that don't exist, aren't added.
     * We do this, because jikes issues warnings for non-existant
     * files/dirs in his classpath, and these warnings are pretty
     * annoying.
     * @param target - target classpath
     * @param source - source classpath
     * to get file objects.
     */
    private void addExistingToClasspath(StringBuffer target,String source) {
       StringTokenizer tok = new StringTokenizer(source,
                             System.getProperty("path.separator"), false);
       while (tok.hasMoreTokens()) {
           File f = project.resolveFile(tok.nextToken());

           if (f.exists()) {
               target.append(File.pathSeparator);
               target.append(f.getAbsolutePath());
           } else {
               project.log("Dropping from classpath: "+
                   f.getAbsolutePath(),project.MSG_VERBOSE);
           }
       }

    }
}

Reply via email to