You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-dev@jakarta.apache.org by md...@apache.org on 2002/11/09 18:09:04 UTC

cvs commit: jakarta-bcel/src/java/org/apache/bcel/util ClassSet.java ClassQueue.java

mdahm       2002/11/09 09:09:04

  Modified:    src/java/org/apache/bcel/util ClassQueue.java
  Added:       examples TransitiveHull.java
               src/java/org/apache/bcel/util ClassSet.java
  Log:
  New TransitiveHull example, may be extended soon
  
  Revision  Changes    Path
  1.1                  jakarta-bcel/examples/TransitiveHull.java
  
  Index: TransitiveHull.java
  ===================================================================
  import org.apache.bcel.classfile.*;
  import org.apache.bcel.generic.*;
  import org.apache.bcel.util.*;
  import java.io.*;
  import java.util.*;
  import org.apache.bcel.Constants;
  import org.apache.bcel.Repository;
  
  /**
   * Find all classes referenced by given start class and all classes
   * referenced by tjose and so on. In other words: Compute the tranitive
   * hull of classes used by a given class. This is done by checking all
   * ConstantClass entries and all method and field signatures.<br> This
   * may be useful in order to put all class files of an application
   * into a single JAR file.
   * <p>
   * It fails however in the presence of reflection code.
   *
   * @version $Id: TransitiveHull.java,v 1.1 2002/11/09 17:09:03 mdahm Exp $
   * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
   */
  public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
    private JavaClass    _class;
    private ClassQueue   _queue;
    private ClassSet     _set;
    private ConstantPool _cp;
  
    private String[] _ignored = {
      "java[.].*",
      "javax[.].*",
      "com[.]sun[.].*"
    };
  
  
    public TransitiveHull(JavaClass clazz) {
      _queue = new ClassQueue();
      _queue.enqueue(clazz);
      _set = new ClassSet();
      _set.add(clazz);
    }
  
    public JavaClass[] getClasses() {
      return _set.toArray();
    }
  
    public String[] getClassNames() {
      return _set.getClassNames();
    }
  
    /**
     * Start traversal using DescendingVisitor pattern.
     */
    public void start() {
      while(!_queue.empty()) {
        JavaClass clazz = _queue.dequeue();
        _class = clazz;
        _cp = clazz.getConstantPool();
  
        new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit();
      }
    }
  
    private void add(String class_name) {
      class_name = class_name.replace('/', '.');
  
      for(int i = 0; i < _ignored.length; i++) {
        if(class_name.matches(_ignored[i])) {
  	return; // Ihh
        }
      }
  
      JavaClass clazz = Repository.lookupClass(class_name);
  
      if(clazz != null && _set.add(clazz)) {
        _queue.enqueue(clazz);
      }
    }
  
    public void visitConstantClass(ConstantClass cc) {
      String class_name = (String)cc.getConstantValue(_cp);
      add(class_name);
    }
  
    private void visitRef(ConstantCP ccp, boolean method) {
      String class_name = ccp.getClass(_cp);
      add(class_name);
  
      ConstantNameAndType cnat = (ConstantNameAndType)_cp.
        getConstant(ccp.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType);
  
      String signature = cnat.getSignature(_cp);
  
      if(method) {
        Type type = Type.getReturnType(signature);
  
        if(type instanceof ObjectType) {
  	add(((ObjectType)type).getClassName());
        }
  
        Type[] types = Type.getArgumentTypes(signature);
  
        for(int i = 0; i < types.length; i++) {
  	type = types[i];
  	if(type instanceof ObjectType) {
  	  add(((ObjectType)type).getClassName());
  	}
        }
      } else {
        Type type = Type.getType(signature);
        if(type instanceof ObjectType) {
  	add(((ObjectType)type).getClassName());
        }
      }
    }
  
    public void visitConstantMethodref(ConstantMethodref cmr) {
      visitRef(cmr, true);
    }
  
    public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref cimr) {
      visitRef(cimr, true);
    }
  
    public void visitConstantFieldref(ConstantFieldref cfr) {
      visitRef(cfr, false);
    }
  
    public static void main(String[] argv) { 
      ClassParser parser=null;
      JavaClass   java_class;
  
      try {
        if(argv.length == 0) {
  	System.err.println("transitive: No input files specified");
        }
        else {
  	if((java_class = Repository.lookupClass(argv[0])) == null) {
  	  java_class = new ClassParser(argv[0]).parse();
  	}
  
  	TransitiveHull hull = new TransitiveHull(java_class);
  
  	hull.start();
  	System.out.println(Arrays.asList(hull.getClassNames()));
        }	  
      } catch(Exception e) {
        e.printStackTrace();
      }
    }        
  }
  
  
  
  1.4       +3 -3      jakarta-bcel/src/java/org/apache/bcel/util/ClassQueue.java
  
  Index: ClassQueue.java
  ===================================================================
  RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/util/ClassQueue.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ClassQueue.java	11 Jul 2002 19:39:05 -0000	1.3
  +++ ClassQueue.java	9 Nov 2002 17:09:03 -0000	1.4
  @@ -53,7 +53,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    */
  -import java.util.ArrayList;
  +import java.util.LinkedList;
   import org.apache.bcel.classfile.JavaClass;
   
   /** 
  @@ -65,7 +65,7 @@
    * @see ClassVector
   */
   public class ClassQueue implements java.io.Serializable {
  -  protected ArrayList vec  = new ArrayList();
  +  protected LinkedList vec  = new LinkedList();
   
     public void enqueue(JavaClass clazz) { vec.add(clazz); }
   
  
  
  
  1.1                  jakarta-bcel/src/java/org/apache/bcel/util/ClassSet.java
  
  Index: ClassSet.java
  ===================================================================
  package org.apache.bcel.util;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache BCEL" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache BCEL", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
  import java.util.HashMap;
  import java.util.Collection;
  import org.apache.bcel.classfile.JavaClass;
  
  /** 
   * Utility class implementing a (typesafe) set of JavaClass objects.
   * Since JavaClass has no equals() method, the name of the class is
   * used for comparison.
   *
   * @version $Id: ClassSet.java,v 1.1 2002/11/09 17:09:03 mdahm Exp $
   * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 
   * @see Stack
  */
  public class ClassSet implements java.io.Serializable {
    private HashMap _map = new HashMap();
  
    public boolean add(JavaClass clazz) {
      boolean result = false;
  
      if(!_map.containsKey(clazz.getClassName())) {
        result = true;
        _map.put(clazz.getClassName(), clazz);
      }
  
      return result;
    }
  
    public void      remove(JavaClass clazz) { _map.remove(clazz.getClassName()); }
    public boolean   empty()                 { return _map.isEmpty(); }
  
    public JavaClass[] toArray() {
      Collection values = _map.values();
      JavaClass[] classes = new JavaClass[values.size()];
      values.toArray(classes);
      return classes;
    }
  
    public String[] getClassNames() {
      return (String[])_map.keySet().toArray(new String[_map.keySet().size()]);
    }
  }  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>