Coverage Report - org.apache.onami.test.reflection.ClassVisitor
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassVisitor
100%
20/20
92%
13/14
3.333
 
 1  
 package org.apache.onami.test.reflection;
 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 static com.google.common.base.Preconditions.checkArgument;
 23  
 
 24  
 import java.lang.annotation.Annotation;
 25  
 import java.lang.reflect.AnnotatedElement;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 
 29  
 import com.google.common.collect.ArrayListMultimap;
 30  
 import com.google.common.collect.Multimap;
 31  
 
 32  
 /**
 33  
  * <p>
 34  
  * Class visitor engine.
 35  
  * </p>
 36  
  * <p>
 37  
  * Visit the input class and all super classes and invokes handler to register annotations.
 38  
  * </p>
 39  
  */
 40  43
 public final class ClassVisitor
 41  
 {
 42  
 
 43  
     private static final String JAVA_PACKAGE = "java";
 44  
 
 45  1
     private static final Logger LOGGER = Logger.getLogger( ClassVisitor.class.getName() );
 46  
 
 47  43
     private final Multimap<Class<? extends Annotation>, AnnotationHandler<? extends Annotation, ? extends AnnotatedElement>> handlers =
 48  
         ArrayListMultimap.create();
 49  
 
 50  
     /**
 51  
      * Registers an annotation handler.
 52  
      *
 53  
      * @param <A> whatever annotation type
 54  
      * @param annotationType the annotation class to handle
 55  
      * @param handler the related annotation handler
 56  
      * @return the current {@code ClassVisitor} instance
 57  
      */
 58  
     public <A extends Annotation> ClassVisitor registerHandler( Class<A> annotationType,
 59  
                                                                 AnnotationHandler<A, ? extends AnnotatedElement> handler )
 60  
     {
 61  103
         handlers.put( annotationType, handler );
 62  103
         return this;
 63  
     }
 64  
 
 65  
     /**
 66  
      * Visits all fields, methods and super classes of the input class.
 67  
      *
 68  
      * @param <T> any type
 69  
      * @param type The type 
 70  
      * @throws HandleException when an error occurs.
 71  
      */
 72  
     public <T> void visit( final Class<? super T> type )
 73  
         throws HandleException
 74  
     {
 75  97
         checkArgument( type != null, "Type to be visited cannot be null" );
 76  
 
 77  97
         if ( LOGGER.isLoggable( Level.FINER ) )
 78  
         {
 79  58
             LOGGER.finer( "  Visit class: " + type );
 80  
         }
 81  
 
 82  97
         if ( type.getPackage() != null && type.getPackage().getName().startsWith( JAVA_PACKAGE ) )
 83  
         {
 84  43
             return;
 85  
         }
 86  
 
 87  54
         handle( type );
 88  54
         handle( type.getDeclaredFields() );
 89  54
         handle( type.getDeclaredMethods() );
 90  
 
 91  54
         visit( type.getSuperclass() );
 92  54
     }
 93  
 
 94  
     @SuppressWarnings( "unchecked" )
 95  
     private void handle( AnnotatedElement... elements )
 96  
         throws HandleException
 97  
     {
 98  602
         for ( AnnotatedElement element : elements )
 99  
         {
 100  588
             for ( Annotation annotation : element.getAnnotations() )
 101  
             {
 102  148
                 for ( AnnotationHandler<? extends Annotation, ? extends AnnotatedElement> handler : handlers.get( annotation.annotationType() ) )
 103  
                 {
 104  47
                     ( (AnnotationHandler<Annotation, AnnotatedElement>) handler ).handle( annotation, element );
 105  
                 }
 106  
             }
 107  
         }
 108  162
     }
 109  
 
 110  
 }