Coverage Report - org.apache.onami.test.handler.MockHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
MockHandler
75%
33/44
75%
15/20
6.5
 
 1  
 package org.apache.onami.test.handler;
 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 java.lang.reflect.Field;
 23  
 import java.lang.reflect.Method;
 24  
 import java.lang.reflect.Modifier;
 25  
 import java.util.HashMap;
 26  
 import java.util.Map.Entry;
 27  
 import java.util.logging.Level;
 28  
 import java.util.logging.Logger;
 29  
 
 30  
 import org.apache.onami.test.annotation.Mock;
 31  
 import org.apache.onami.test.mock.MockEngine;
 32  
 import org.apache.onami.test.reflection.FieldHandler;
 33  
 import org.apache.onami.test.reflection.HandleException;
 34  
 
 35  
 /**
 36  
  * Handler class to handle all {@link Mock} annotations.
 37  
  *
 38  
  * @see org.apache.onami.test.reflection.ClassVisitor
 39  
  * @see Mock
 40  
  */
 41  23
 public final class MockHandler
 42  
     implements FieldHandler<Mock>
 43  
 {
 44  
 
 45  1
     private static final Logger LOGGER = Logger.getLogger( MockHandler.class.getName() );
 46  
 
 47  12
     private final HashMap<Field, Object> mockedObjects = new HashMap<Field, Object>( 1 );
 48  
 
 49  
     /**
 50  
      * Return the mocked objects.
 51  
      * 
 52  
      * @param engine the {@link MockEngine}
 53  
      * @return the map of mocked objects
 54  
      */
 55  
     public HashMap<Field, Object> getMockedObject( MockEngine engine )
 56  
     {
 57  12
         createMockedObjectBymockFramekork( engine );
 58  12
         return mockedObjects;
 59  
     }
 60  
 
 61  
     private void createMockedObjectBymockFramekork( MockEngine engine )
 62  
     {
 63  12
         for ( Entry<Field, Object> entry : mockedObjects.entrySet() )
 64  
         {
 65  11
             if ( entry.getValue() instanceof Class<?> )
 66  
             {
 67  8
                 Field field = entry.getKey();
 68  8
                 Mock mock = field.getAnnotation( Mock.class );
 69  8
                 mockedObjects.put( entry.getKey(), engine.createMock( (Class<?>) entry.getValue(), mock.type() ) );
 70  11
             }
 71  
         }
 72  12
     }
 73  
 
 74  
     
 75  
     /**
 76  
      * Invoked when the visitor founds an element with a {@link Mock} annotation.
 77  
      * @param annotation The {@link Mock} annotation type
 78  
      * @param element the {@link Mock} annotated fiels 
 79  
      * @throws HandleException when an error occurs.    
 80  
      */
 81  
     @SuppressWarnings( "unchecked" )
 82  
     public void handle( final Mock annotation, final Field element )
 83  
         throws HandleException
 84  
     {
 85  11
         final Class<? super Object> type = (Class<? super Object>) element.getDeclaringClass();
 86  
 
 87  11
         if ( LOGGER.isLoggable( Level.FINER ) )
 88  
         {
 89  6
             LOGGER.finer( "      Found annotated field: " + element );
 90  
         }
 91  11
         if ( annotation.providedBy().length() > 0 )
 92  
         {
 93  3
             Class<?> providedClass = type;
 94  3
             if ( annotation.providerClass() != Object.class )
 95  
             {
 96  1
                 providedClass = annotation.providerClass();
 97  
             }
 98  
             try
 99  
             {
 100  3
                 Method method = providedClass.getMethod( annotation.providedBy() );
 101  
 
 102  3
                 if ( !element.getType().isAssignableFrom( method.getReturnType() ) )
 103  
                 {
 104  0
                     throw new HandleException( "Impossible to mock %s due to compatibility type, method provider %s#%s returns %s",
 105  
                                                element.getDeclaringClass().getName(),
 106  
                                                providedClass.getName(),
 107  
                                                annotation.providedBy(),
 108  
                                                method.getReturnType().getName() );
 109  
                 }
 110  
                 try
 111  
                 {
 112  3
                     Object mocked = getMockProviderForType( element.getType(), method, type );
 113  3
                     mockedObjects.put( element, mocked );
 114  
                 }
 115  0
                 catch ( Throwable t )
 116  
                 {
 117  0
                     throw new HandleException( "Impossible to mock %s, method provider %s#%s raised an error: %s",
 118  
                                                element.getDeclaringClass().getName(),
 119  
                                                providedClass.getName(),
 120  
                                                annotation.providedBy(),
 121  
                                                t );
 122  3
                 }
 123  
             }
 124  0
             catch ( SecurityException e )
 125  
             {
 126  0
                 throw new HandleException( "Impossible to mock %s, impossible to access to method provider %s#%s: %s",
 127  
                                            element.getDeclaringClass().getName(),
 128  
                                            providedClass.getName(),
 129  
                                            annotation.providedBy(),
 130  
                                            e );
 131  
             }
 132  0
             catch ( NoSuchMethodException e )
 133  
             {
 134  0
                 throw new HandleException( "Impossible to mock %s, the method provider %s#%s doesn't exist.",
 135  
                                            element.getDeclaringClass().getName(),
 136  
                                            providedClass.getName(),
 137  
                                            annotation.providedBy() );
 138  3
             }
 139  3
         }
 140  
         else
 141  
         {
 142  8
             mockedObjects.put( element, element.getType() );
 143  
         }
 144  11
     }
 145  
 
 146  
     @SuppressWarnings( "unchecked" )
 147  
     private <T> T getMockProviderForType( T t, Method method, Class<?> cls )
 148  
         throws HandleException
 149  
     {
 150  3
         if ( method.getReturnType() == t )
 151  
         {
 152  
             try
 153  
             {
 154  3
                 if ( LOGGER.isLoggable( Level.FINER ) )
 155  
                 {
 156  3
                     LOGGER.finer( "        ...invoke Provider method for Mock: " + method.getName() );
 157  
                 }
 158  3
                 if ( !Modifier.isPublic( method.getModifiers() ) || !Modifier.isStatic( method.getModifiers() ) )
 159  
                 {
 160  0
                     throw new HandleException( "Impossible to invoke method %s#%s. The method shuld be 'static public %s %s()",
 161  
                                                cls.getName(),
 162  
                                                method.getName(),
 163  
                                                method.getReturnType().getName(),
 164  
                                                method.getName() );
 165  
                 }
 166  
 
 167  3
                 return (T) method.invoke( cls );
 168  
             }
 169  0
             catch ( Exception e )
 170  
             {
 171  0
                 throw new RuntimeException( e );
 172  
             }
 173  
         }
 174  0
         throw new HandleException( "The method: %s should return type %s", method, t );
 175  
     }
 176  
 
 177  
 }