Package net.xeoh.plugins.plugindoctor.analysis

Source Code of net.xeoh.plugins.plugindoctor.analysis.ClassClasspathElement

/*
* ClassAnalysis.java
*
* Copyright (c) 2009, Ralf Biedert All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. 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.
*
* Neither the name of the author nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* 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
* COPYRIGHT OWNER OR 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.
*
*/
package net.xeoh.plugins.plugindoctor.analysis;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;

import net.xeoh.plugins.base.impl.classpath.locator.AbstractClassPathLocation;

import org.gjt.jclasslib.io.ClassFileReader;
import org.gjt.jclasslib.structures.CPInfo;
import org.gjt.jclasslib.structures.ClassFile;
import org.gjt.jclasslib.structures.InvalidByteCodeException;
import org.gjt.jclasslib.structures.constants.ConstantClassInfo;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

/**
* Analyzes a class and stores the result.
*
* @author rb
*
*/
public class ClassClasspathElement extends AbstractClasspathElement {
    /** */
    final ClassFile classFile;

    /** */
    final ClassReader classReader;

    /** */
    final String className;

    /** */
    final Collection<String> nonSystemDepenencies = new ArrayList<String>();

    /** */
    final Collection<String> annotations = new ArrayList<String>();

    /**
     * @param location
     * @param name
     * @throws IOException
     * @throws InvalidByteCodeException
     */
    public ClassClasspathElement(AbstractClassPathLocation location, String name)
                                                                                 throws IOException,
                                                                                 InvalidByteCodeException {

        super(location, name);

        InputStream inputStream;

        // Use ASM
        inputStream = location.getInputStream(name);
        this.classReader = new ClassReader(inputStream);
        inputStream.close();

        // Use jClassLib
        inputStream = location.getInputStream(name);
        this.classFile = ClassFileReader.readFromInputStream(inputStream);
        inputStream.close();

        // Get base info
        this.className = this.classReader.getClassName().replaceAll("/", ".");

        // Get complex info
        detectDependencies();
        detectAnnotations();
    }

    /**
     *
     */
    private void detectAnnotations() {
        this.classReader.accept(new ClassVisitor() {

            public void visitSource(String arg0, String arg1) {
                // TODO Auto-generated method stub

            }

            public void visitOuterClass(String arg0, String arg1, String arg2) {
                // TODO Auto-generated method stub

            }

            public MethodVisitor visitMethod(int arg0, String arg1, String arg2,
                                             String arg3, String[] arg4) {
                // TODO Auto-generated method stub
                return null;
            }

            public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) {
                // TODO Auto-generated method stub

            }

            public FieldVisitor visitField(int arg0, String arg1, String arg2,
                                           String arg3, Object arg4) {
                // TODO Auto-generated method stub
                return null;
            }

            public void visitEnd() {
                // TODO Auto-generated method stub

            }

            public void visitAttribute(Attribute arg0) {
                // TODO Auto-generated method stub

            }

            public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
                if (arg0 == null) return null;
                ClassClasspathElement.this.annotations.add(arg0.substring(1).replaceAll(";", "").replaceAll("/", "."));

                return null;
            }

            public void visit(int arg0, int arg1, String arg2, String arg3, String arg4,
                              String[] arg5) {
                // TODO Auto-generated method stub

            }
        }, 0);

    }

    /**
     * Load all dependencies
     */
    private void detectDependencies() {

        final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        final CPInfo[] constantPool = this.classFile.getConstantPool();

        for (CPInfo cpInfo : constantPool) {
            if (cpInfo instanceof ConstantClassInfo) {

                final ConstantClassInfo i = (ConstantClassInfo) cpInfo;

                String dependencyName = null;
                boolean isIrrelevant = false;

                // Check found dependency
                try {
                    dependencyName = i.getName().replaceAll("/", ".");

                    if (dependencyName.startsWith("[")) continue;

                    // If this line returns the class was found and is probably irrelevant
                    // FIXME: Also classes of this application are found!
                    systemClassLoader.loadClass(dependencyName);

                    isIrrelevant = true;
                } catch (InvalidByteCodeException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    //
                } catch (NoClassDefFoundError e) {
                    //
                }

                // Add dependency
                if (!isIrrelevant && dependencyName != null && !dependencyName.equals(this.className)) {
                    this.nonSystemDepenencies.add(dependencyName);
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();

        sb.append("ClassElement {\n");
        sb.append("   name = " + this.className + "\n");

        for (String s : this.nonSystemDepenencies) {
            sb.append("   dependency = " + s + "\n");
        }
        for (String s : this.annotations) {
            sb.append("   annotation = " + s + "\n");
        }

       
        sb.append("}");
        return sb.toString();
    }
}
TOP

Related Classes of net.xeoh.plugins.plugindoctor.analysis.ClassClasspathElement

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.