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