Coverage Report - org.mule.util.scan.annotations.AnnotationsScanner
 
Classes in this File Line Coverage Branch Coverage Complexity
AnnotationsScanner
0%
0/73
0%
0/26
0
 
 1  
 /*
 2  
  * $Id: AnnotationsScanner.java 19191 2010-08-25 21:05:23Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 package org.mule.util.scan.annotations;
 11  
 
 12  
 import org.mule.util.scan.ClassScanner;
 13  
 
 14  
 import java.util.ArrayList;
 15  
 import java.util.BitSet;
 16  
 import java.util.List;
 17  
 
 18  
 import org.apache.commons.logging.Log;
 19  
 import org.apache.commons.logging.LogFactory;
 20  
 import org.objectweb.asm.AnnotationVisitor;
 21  
 import org.objectweb.asm.FieldVisitor;
 22  
 import org.objectweb.asm.MethodVisitor;
 23  
 import org.objectweb.asm.commons.EmptyVisitor;
 24  
 
 25  
 /**
 26  
  * Scans a single class and registers all annotations on the class in four collections; class annotations, field annotations
 27  
  * method annotations and parameter annotations.
 28  
  *
 29  
  * This scanner can process interfaces, implementation classes and annotation classes.  The scanner uses ASM to read the class
 30  
  * bytecode, removing the need to actally load the class which would be expensive.
 31  
  */
 32  
 public class AnnotationsScanner extends EmptyVisitor implements ClassScanner
 33  
 {
 34  0
     protected final Log log = LogFactory.getLog(getClass());
 35  
 
 36  0
     private List<AnnotationInfo> classAnnotations = new ArrayList<AnnotationInfo>();
 37  0
     private List<AnnotationInfo> fieldAnnotations = new ArrayList<AnnotationInfo>();
 38  0
     private List<AnnotationInfo> methodAnnotations = new ArrayList<AnnotationInfo>();
 39  0
     private List<AnnotationInfo> paramAnnotations = new ArrayList<AnnotationInfo>();
 40  
 
 41  
     protected AnnotationInfo currentAnnotation;
 42  
 
 43  
     protected static final int PROCESSING_FIELD = 1;
 44  
     protected static final int PROCESSING_METHOD = 2;
 45  
     protected static final int PROCESSING_CLASS = 3;
 46  
     protected static final int PROCESSING_PARAM = 4;
 47  
 
 48  0
     protected BitSet currentlyProcessing = new BitSet(4);
 49  
 
 50  
     private AnnotationFilter filter;
 51  
 
 52  0
     private BitSet lastProcessing = null;
 53  
 
 54  
     private String className;
 55  
 
 56  
     private boolean match;
 57  
 
 58  
     public AnnotationsScanner()
 59  
     {
 60  0
         super();
 61  0
     }
 62  
 
 63  
     public AnnotationsScanner(AnnotationFilter filter)
 64  0
     {
 65  0
         this.filter = filter;
 66  0
     }
 67  
 
 68  
     @Override
 69  
     public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible)
 70  
     {
 71  0
         currentAnnotation = new AnnotationInfo();
 72  0
         currentAnnotation.setClassName(getAnnotationClassName(desc));
 73  0
         currentlyProcessing.set(PROCESSING_PARAM);
 74  0
         if (log.isDebugEnabled())
 75  
         {
 76  0
             log.debug("Parameter Annotation: " + getAnnotationClassName(desc));
 77  
         }
 78  0
         return this;
 79  
     }
 80  
 
 81  
     @Override
 82  
     public AnnotationVisitor visitAnnotation(final String desc, final boolean visible)
 83  
     {
 84  
         // are we processing anything currently? If not w'ere looking at another annotation on the same class element
 85  0
         if (currentlyProcessing.nextSetBit(0) < 0)
 86  
         {
 87  0
             if(lastProcessing!=null)
 88  
             {
 89  0
                 currentlyProcessing = lastProcessing;
 90  
             }
 91  
             else
 92  
             {
 93  0
                 return this;
 94  
             }
 95  
         }
 96  
 
 97  0
         currentAnnotation = new AnnotationInfo();
 98  0
         currentAnnotation.setClassName(getAnnotationClassName(desc));
 99  0
         if (log.isDebugEnabled())
 100  
         {
 101  0
             log.debug("Annotation: " + getAnnotationClassName(desc));
 102  
         }
 103  
 
 104  0
         return this;
 105  
     }
 106  
 
 107  
 
 108  
     /**
 109  
      * This is the class entry.
 110  
      */
 111  
     @Override
 112  
     public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)
 113  
     {
 114  0
         currentlyProcessing.set(PROCESSING_CLASS);
 115  0
         className = name;
 116  0
     }
 117  
 
 118  
     /**
 119  
      * We get annotation values in this method, but have to track the current context.
 120  
      */
 121  
     @Override
 122  
     public void visit(String name, Object value)
 123  
     {
 124  0
         if (currentAnnotation != null)
 125  
         {
 126  0
             currentAnnotation.getParams().add(new AnnotationInfo.NameValue(name, value));
 127  
         }
 128  0
         if (log.isDebugEnabled())
 129  
         {
 130  
             // won't really output nicely with multithreaded parsing
 131  0
             log.debug("          : " + name + "=" + value);
 132  
         }
 133  0
     }
 134  
 
 135  
     @Override
 136  
     public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value)
 137  
     {
 138  0
         currentlyProcessing.set(PROCESSING_FIELD);
 139  0
         return this;
 140  
     }
 141  
 
 142  
     @Override
 143  
     public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)
 144  
     {
 145  0
         currentlyProcessing.set(PROCESSING_METHOD);
 146  0
         return this;
 147  
     }
 148  
 
 149  
 
 150  
     @Override
 151  
     public void visitEnd()
 152  
     {
 153  0
         if (currentAnnotation != null)
 154  
         {
 155  
 
 156  0
             if(filter!=null && !filter.accept(currentAnnotation))
 157  
             {
 158  0
                 currentlyProcessing.clear();
 159  0
                 currentAnnotation = null;
 160  0
                 return;
 161  
             }
 162  0
             if (currentlyProcessing.get(PROCESSING_CLASS))
 163  
             {
 164  0
                 classAnnotations.add(currentAnnotation);
 165  0
                 match = true;
 166  
             }
 167  0
             if (currentlyProcessing.get(PROCESSING_FIELD))
 168  
             {
 169  0
                 fieldAnnotations.add(currentAnnotation);
 170  0
                 match = true;
 171  
             }
 172  0
             else if (currentlyProcessing.get(PROCESSING_PARAM))
 173  
             {
 174  0
                 paramAnnotations.add(currentAnnotation);
 175  0
                 match = true;
 176  
             }
 177  0
             else if (currentlyProcessing.get(PROCESSING_METHOD))
 178  
             {
 179  0
                 methodAnnotations.add(currentAnnotation);
 180  0
                 match = true;                
 181  
             }
 182  0
             currentAnnotation = null;
 183  
         }
 184  0
         lastProcessing = (BitSet)currentlyProcessing.clone();
 185  0
         currentlyProcessing.clear();
 186  
 
 187  0
     }
 188  
 
 189  
     public String getAnnotationClassName(String rawName)
 190  
     {
 191  0
         return rawName.substring(1, rawName.length() - 1).replace('/', '.');
 192  
     }
 193  
 
 194  
     public List<AnnotationInfo> getClassAnnotations()
 195  
     {
 196  0
         return classAnnotations;
 197  
     }
 198  
 
 199  
     public List<AnnotationInfo> getFieldAnnotations()
 200  
     {
 201  0
         return fieldAnnotations;
 202  
     }
 203  
 
 204  
     public List<AnnotationInfo> getMethodAnnotations()
 205  
     {
 206  0
         return methodAnnotations;
 207  
     }
 208  
 
 209  
     public List<AnnotationInfo> getParamAnnotations()
 210  
     {
 211  0
         return paramAnnotations;
 212  
     }
 213  
 
 214  
     public List<AnnotationInfo> getAllAnnotations()
 215  
     {
 216  0
         List<AnnotationInfo> list = new ArrayList<AnnotationInfo>();
 217  0
         list.addAll(classAnnotations);
 218  0
         list.addAll(fieldAnnotations);
 219  0
         list.addAll(methodAnnotations);
 220  0
         list.addAll(paramAnnotations);
 221  0
         return list;
 222  
     }
 223  
 
 224  
     public boolean isMatch()
 225  
     {
 226  0
         return match;
 227  
     }
 228  
 
 229  
     public String getClassName()
 230  
     {
 231  0
         return className;
 232  
     }
 233  
 }