View Javadoc
1   package org.apache.maven.shared.dependency.analyzer.asm;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.io.IOUtils;
23  import org.apache.maven.shared.dependency.analyzer.ClassFileVisitor;
24  import org.objectweb.asm.AnnotationVisitor;
25  import org.objectweb.asm.ClassReader;
26  import org.objectweb.asm.ClassVisitor;
27  import org.objectweb.asm.FieldVisitor;
28  import org.objectweb.asm.MethodVisitor;
29  import org.objectweb.asm.signature.SignatureVisitor;
30  
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.util.Set;
34  
35  /**
36   * Computes the set of classes referenced by visited class files, using
37   * <a href="DependencyVisitor.html">DependencyVisitor</a>.
38   *
39   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
40   * @version $Id$
41   * @see #getDependencies()
42   */
43  public class DependencyClassFileVisitor
44      implements ClassFileVisitor
45  {
46      // fields -----------------------------------------------------------------
47  
48      private final ResultCollector resultCollector = new ResultCollector();
49  
50      // constructors -----------------------------------------------------------
51  
52      public DependencyClassFileVisitor()
53      {
54      }
55  
56      // ClassFileVisitor methods -----------------------------------------------
57  
58      /*
59       * @see org.apache.maven.shared.dependency.analyzer.ClassFileVisitor#visitClass(java.lang.String,
60       *      java.io.InputStream)
61       */
62      public void visitClass( String className, InputStream in )
63      {
64          try
65          {
66              byte[] byteCode = IOUtils.toByteArray( in );
67              ClassReader reader = new ClassReader( byteCode );
68  
69              final Set<String> constantPoolClassRefs = ConstantPoolParser.getConstantPoolClassReferences( byteCode );
70              for ( String string : constantPoolClassRefs )
71              {
72                  resultCollector.addName( string );
73              }
74  
75              AnnotationVisitor annotationVisitor = new DefaultAnnotationVisitor( resultCollector );
76              SignatureVisitor signatureVisitor = new DefaultSignatureVisitor( resultCollector );
77              FieldVisitor fieldVisitor = new DefaultFieldVisitor( annotationVisitor, resultCollector );
78              MethodVisitor mv = new DefaultMethodVisitor( annotationVisitor, signatureVisitor, resultCollector );
79              ClassVisitor classVisitor =
80                  new DefaultClassVisitor( signatureVisitor, annotationVisitor, fieldVisitor, mv, resultCollector );
81  
82              reader.accept( classVisitor, 0 );
83          }
84          catch ( IOException exception )
85          {
86              exception.printStackTrace();
87          }
88          catch ( IndexOutOfBoundsException e )
89          {
90              // some bug inside ASM causes an IOB exception. Log it and move on?
91              // this happens when the class isn't valid.
92              System.out.println( "Unable to process: " + className );
93          }
94      }
95  
96      // public methods ---------------------------------------------------------
97  
98      /**
99       * @return the set of classes referenced by visited class files
100      */
101     public Set<String> getDependencies()
102     {
103         return resultCollector.getDependencies();
104     }
105 }