Package com.acciente.commons.loader

Source Code of com.acciente.commons.loader.ClassFile

/*
* Copyright 2008-2011 Acciente, LLC
*
* Acciente, LLC licenses this file to you under the
* Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in
* writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.acciente.commons.loader;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.ConstantUtf8;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.Type;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
* This class has methods to read information from a class file.
*
* (this class makes heavy use of the Apache BCEL library)
*
* @created Jun 5, 2008
*
* @author Adinath Raveendra Raj
*/
public class ClassFile
{
   private JavaClass    _oJavaClass;
   private String       _sClassName;

   public ClassFile( File oByteCodeFile ) throws IOException
   {
      _oJavaClass = ( new ClassParser( new FileInputStream( oByteCodeFile ), "" ) ).parse();
      _sClassName = _oJavaClass.getClassName();
   }

   public ClassFile( byte[] ayClassByteCode ) throws IOException
   {
      _oJavaClass = ( new ClassParser( new ByteArrayInputStream( ayClassByteCode ), "" ) ).parse();
      _sClassName = _oJavaClass.getClassName();
   }

   /**
    * This method returns the names of classes referenced by this class, including
    * inner classes.
    * @return a set containing strings representing fully qualified class names
    */
   public Set getReferencedClasses()
   {
      Set            oReferences    = new HashSet();
      String         sClassName     = _oJavaClass.getClassName();

      // we determine the dependencies by looking at class references
      // from in the constant pool, method args (and return type), and
      // class fields

      // first look at the constant pool
      ConstantPool oConstantPool = _oJavaClass.getConstantPool();
      for ( int i = 0; i < oConstantPool.getLength(); i++ )
      {
         Constant oConstant = oConstantPool.getConstant( i );

         if ( oConstant instanceof ConstantClass )
         {
            ConstantUtf8 oConstantUtf8
               =  ( ConstantUtf8 )
                     oConstantPool
                        .getConstant( ( ( ConstantClass ) oConstant ).getNameIndex() );

            String sReferencedClassname = oConstantUtf8.getBytes().replace( '/', '.' );

            // only consider the class if it is not an array, since classloaders do not
            // handle arrays, the JVM does this directly
            if ( ! sReferencedClassname.startsWith( "[" ))
            {
               oReferences.add( sReferencedClassname );
            }
         }
      }

      // next look at the types used in the method signatures
      Method[] aoMethods = _oJavaClass.getMethods();
      for ( int i = 0; i < aoMethods.length; i++ )
      {
         Method oMethod = aoMethods[ i ];

         // look at the type of the method return type
         addReference( oReferences, oMethod.getReturnType() );

         // look at the types of the method arguments
         Type[] oTypes = oMethod.getArgumentTypes();
         for ( int j = 0; j < oTypes.length; j++ )
         {
            addReference( oReferences, oTypes[ j ] );
         }
      }

      // next look at the types of the any privates and publics in the class
      Field[] aoFields = _oJavaClass.getFields();
      for ( int i = 0; i < aoFields.length; i++ )
      {
         addReference( oReferences, aoFields[ i ].getType() );
      }

      // remove the self-reference that we collected (there is always one in the constant pool)
      oReferences.remove( _sClassName );

      return oReferences;
   }

   private void addReference( Set oReferences, Type oType )
   {
      if ( oType.getType() == Constants.T_OBJECT )
      {
         String   sSignature;
         String   sReferencedClassname;

         sSignature           = oType.getSignature();
         sReferencedClassname = sSignature.substring( 1, sSignature.length() - 1 ).replace( '/', '.' );

         oReferences.add( sReferencedClassname );
      }
   }
}

// EOF
TOP

Related Classes of com.acciente.commons.loader.ClassFile

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.