SessionBeanGenerator.java :  » J2EE » panther » org » lateralnz » panther » deploy » Java Open Source

Java Open Source » J2EE » panther 
panther » org » lateralnz » panther » deploy » SessionBeanGenerator.java
/* ====================================================================
 * The LateralNZ Software License, Version 1.0
 *
 * Copyright (c) 2003 LateralNZ.  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 acknowledgment:
 *       "This product includes software developed by 
 *        LateralNZ (http://www.lateralnz.org/) and other third parties."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "LateralNZ" must not be used to endorse or promote 
 *    products derived from this software without prior written 
 *    permission. For written permission, please 
 *    contact oss@lateralnz.org.
 *
 * 5. Products derived from this software may not be called "Panther", 
 *    or "Lateral" or "LateralNZ", nor may "PANTHER" or "LATERAL" or 
 *    "LATERALNZ" appear in their name, without prior written 
 *    permission of LateralNZ.
 *
 * 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 LateralNZ.  For more
 * information on Lateral, please see http://www.lateralnz.com/ or
 * http://www.lateralnz.org
 *
 */
package org.lateralnz.panther.deploy;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

import org.w3c.dom.Document;

import org.lateralnz.common.util.Constants;
import org.lateralnz.common.util.ObjectUtils;
import org.lateralnz.common.util.StringUtils;
import org.lateralnz.common.util.XMLUtils;

import org.lateralnz.panther.util.EJBConstants;

/**
 * @author J R Briggs
 */
public class SessionBeanGenerator implements Constants, Serializable {
  private String ejbjarXML;
  private String tempdir;
  private String classesdir;
  private String wrapperTemplate;
  private String homeWrapperTemplate;
  private String wrapperTemplateDir;
  private String logfile;

 /**
  * set the EJBJarXML property
  */
  public void setEJBJarXML(String ejbjarXML) {
    this.ejbjarXML = ejbjarXML;
  }
  
 /**
  * set the temporary/working directory
  */
  public void setTempDir(String tempdir) {
    this.tempdir = StringUtils.toDirectory(tempdir);
  }
  
 /**
  * set the directory where classes can be found
  */
  public void setClassesDir(String classesdir) {
    this.classesdir = StringUtils.toDirectory(classesdir);
  }

 /**
  * set the name of the sessionbean wrapper template
  */
  public void setWrapperTemplate(String wrapperTemplate) {
    this.wrapperTemplate = wrapperTemplate; 
  }
  
  public void setHomeWrapperTemplate(String homeWrapperTemplate) {
    this.homeWrapperTemplate = homeWrapperTemplate;
  }
  
 /**
  * set the directory where we can find the template
  */
  public void setWrapperTemplateDir(String wrapperTemplateDir) {
    this.wrapperTemplateDir = wrapperTemplateDir; 
  }
  
  public void setLogFile(String logfile) {
    this.logfile = logfile;
  }

 /**
  * execute this task
  */
  public void execute() throws Exception {
    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, wrapperTemplateDir);
    if (!StringUtils.isEmpty(logfile)) {
      ve.setProperty(VelocityEngine.RUNTIME_LOG, logfile);
    }
    ve.init();

    Template ejbWrapper = ve.getTemplate(wrapperTemplate);
    Template homeWrapper = ve.getTemplate(homeWrapperTemplate);

    File f = new File(ejbjarXML);
    String xml = StringUtils.readFromFile(ejbjarXML);
    Document doc = XMLUtils.parse(xml);

    File fworkingDir = new File(tempdir);    

    // various lists needed during the parse
    List ejbwrappers = new ArrayList();

    // work through the session descriptors
    List l = EJBJarUtils.getSessionDescriptors(doc);
    Iterator iter = l.iterator();
    while (iter.hasNext()) {
      SessionDescriptor sd = (SessionDescriptor)iter.next(); 
      if (sd.getSessionType().equalsIgnoreCase(EJBConstants.STATEFUL)) {
        iter.remove();
        
        System.out.println("note: stateful bean " + sd.getEJBName() + " is not supported");
        continue;
      }

      // get the remote, ejb and home classes
      Class remote = Class.forName(sd.getEJBRemoteClass());
      Class home   = Class.forName(sd.getEJBHomeClass());
      Class ejb    = Class.forName(sd.getEJBClass());

      String packageName = sd.getEJBRemoteClass().substring(0, sd.getEJBRemoteClass().lastIndexOf('.'));
      String packageDir  = StringUtils.replace(packageName, DOT, FILE_SEPARATOR);
      checkDirStructure(tempdir, packageDir);
      String[] tmp       = StringUtils.toArray(remote.getName(), DOT);

      // this is what we'll call our ejb wrapper
      String wrapperName     = tmp[tmp.length - 1] + "Impl";
      String homeName        = tmp[tmp.length - 1] + "HomeImpl";
      String wrapperFullName = StringUtils.replace(sd.getEJBName(), FILE_SEPARATOR, UNDERSCORE);

      // this is the classname and class signature file
      String className       = classesdir + packageDir + FILE_SEPARATOR + wrapperName + ".class";
      String signatureFile   = tempdir + packageDir + FILE_SEPARATOR + wrapperName + ".sig";

      // get signatures for comparison (if they're not the same, we'll need to regenerate)
      String oldsig  = StringUtils.readFromFile(signatureFile);
      String newsig = ObjectUtils.getMD5Signature(remote);

      // check if we have already generated the class or if the signatures are different
      File tst = new File(className);

      String logtmp = EMPTY + (tst.exists() ? ONE : ZERO) + (tst.canRead() ? ONE : ZERO) + (newsig.equals(oldsig) ? ONE : ZERO);
      if (!tst.exists() || !tst.canRead() || !newsig.equals(oldsig)) {
        // get all remote methods and add to a list
        Method[] methods = remote.getDeclaredMethods();
        ArrayList methodList = new ArrayList();
        for (int i = 0; i < methods.length; i++) {
          if (!ObjectUtils.containsObject(methods[i].getExceptionTypes(), java.rmi.RemoteException.class)) {
            continue;
          }
          boolean trans = false;
          String tt = sd.getTransEntry(methods[i].getName());
          if (tt.equalsIgnoreCase(REQUIRED)
           || tt.equalsIgnoreCase(REQUIRES_NEW)) {
            trans = true;
          }
          methodList.add(new MethodDescriptor(methods[i], trans, tt));
        }

        // velocity generation of java code
        VelocityContext ctx = new VelocityContext();
        ctx.put("ejbpackage", packageName);
        ctx.put("ejbname", wrapperFullName);
        ctx.put("ejbwrapper", wrapperName);
        ctx.put("ejbhomewrapper", homeName);
        ctx.put("ejb", ejb.getName());
        ctx.put("ejbremote", remote.getName());
        ctx.put("ejbhome", home.getName());
        ctx.put("methods", methodList);
        ctx.put("generator", this);

        System.out.println("note: generating source for " + remote.getName() + " [" + logtmp + "]");

        // write to file
        FileWriter fw = new FileWriter(tempdir + packageDir + FILE_SEPARATOR + wrapperName + ".java");
        ejbWrapper.merge(ctx, fw);
        fw.flush();
        fw.close();

        fw = new FileWriter(tempdir + packageDir + FILE_SEPARATOR + homeName + ".java");
        homeWrapper.merge(ctx, fw);
        fw.flush();
        fw.close();

        // write the new signature
        tst = new File(signatureFile);
        tst.delete();
        fw = new FileWriter(signatureFile);
        fw.write(newsig);
        fw.flush();
        fw.close();

      }
    }
  }
  
 /**
  * check the directory structure for a package in a working directory, and if it 
  * doesn't exist, then create it.  For example, the call: <br />
  * checkDirStructure("test", "org/lateralnz/whatever");<br/>
  * will create:<br/>
  * test/org/lateralnz/whatever<br/>
  * if it does not already exist
  */
  protected void checkDirStructure(String workingDir, String packageDir) throws IOException {
    File f = new File(workingDir + packageDir);
    if (f.exists()) {
      return; 
    }
    StringBuffer sb = new StringBuffer(workingDir);
    StringTokenizer st = new StringTokenizer(packageDir, FILE_SEPARATOR);
    while (st.hasMoreTokens()) {
      String next = st.nextToken();
      sb.append(next).append(FILE_SEPARATOR);
      f = new File(sb.toString());
      if (!f.exists()) {
        if (!f.mkdir()) {
          throw new IOException("error creating directory : " + sb.toString()); 
        }
      }
    }    
  }
  
 /**
  * returns the length of an object if it is a List or Array. <br/>
  * NOTE: needs to be public otherwise the velocity engine can't get access
  * to it
  * @param an object that is a list or an array
  * @return the length of the list or array
  */
  public int getLength(Object obj) {
    try {
      if (obj instanceof List) {
        return ((List)obj).size();
      }
      else {
        return java.lang.reflect.Array.getLength(obj);
      }
    }
    catch (Exception e) {
      e.printStackTrace(); 
      return 0; 
    }
  }
  
 /**
  * so this task can be called standalone
  */
  public static final void main(String[] args) throws Exception {
    SessionBeanGenerator sbg = new SessionBeanGenerator();
    sbg.setEJBJarXML(args[0]);
    sbg.setTempDir(args[1]);
    sbg.setClassesDir(args[2]);
    sbg.setWrapperTemplate(args[3]);
    sbg.setHomeWrapperTemplate(args[4]);
    sbg.setWrapperTemplateDir(args[5]);
    sbg.setLogFile(args[6]);
    
    sbg.execute();
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.