Coverage Report - com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
HandlerFactory
83%
78/93
77%
14/18
4.143
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2014  Oliver Burn
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 package com.puppycrawl.tools.checkstyle.checks.indentation;
 20  
 
 21  
 import com.google.common.collect.Maps;
 22  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 23  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 24  
 import java.lang.reflect.Constructor;
 25  
 import java.lang.reflect.InvocationTargetException;
 26  
 import java.util.Map;
 27  
 import java.util.Set;
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 /**
 32  
  * Factory for handlers. Looks up constructor via reflection.
 33  
  *
 34  
  * @author jrichard
 35  
  */
 36  
 public class HandlerFactory
 37  
 {
 38  
     /** Logger for indentation check */
 39  1
     private static final Log LOG =
 40  
         LogFactory.getLog("com.puppycrawl.tools.checkstyle.checks.indentation");
 41  
 
 42  
     /**
 43  
      * Registered handlers.
 44  
      */
 45  33
     private final Map<Integer, Constructor<?>> mTypeHandlers =
 46  
         Maps.newHashMap();
 47  
 
 48  
     /**
 49  
      * registers a handler
 50  
      *
 51  
      * @param aType
 52  
      *                type from TokenTypes
 53  
      * @param aHandlerClass
 54  
      *                the handler to register
 55  
      */
 56  
     private void register(int aType, Class<?> aHandlerClass)
 57  
     {
 58  
         try {
 59  1287
             final Constructor<?> ctor = aHandlerClass
 60  
                     .getConstructor(new Class[] {IndentationCheck.class,
 61  
                         DetailAST.class, // current AST
 62  
                         ExpressionHandler.class, // parent
 63  
                     });
 64  1287
             mTypeHandlers.put(aType, ctor);
 65  
         }
 66  
         ///CLOVER:OFF
 67  0
         catch (final NoSuchMethodException e) {
 68  0
             throw new RuntimeException("couldn't find ctor for "
 69  
                                        + aHandlerClass);
 70  
         }
 71  0
         catch (final SecurityException e) {
 72  0
             LOG.debug("couldn't find ctor for " + aHandlerClass, e);
 73  0
             throw new RuntimeException("couldn't find ctor for "
 74  
                                        + aHandlerClass);
 75  1287
         }
 76  
         ///CLOVER:ON
 77  1287
     }
 78  
 
 79  
     /** Creates a HandlerFactory. */
 80  
     public HandlerFactory()
 81  33
     {
 82  33
         register(TokenTypes.CASE_GROUP, CaseHandler.class);
 83  33
         register(TokenTypes.LITERAL_SWITCH, SwitchHandler.class);
 84  33
         register(TokenTypes.SLIST, SlistHandler.class);
 85  33
         register(TokenTypes.PACKAGE_DEF, PackageDefHandler.class);
 86  33
         register(TokenTypes.LITERAL_ELSE, ElseHandler.class);
 87  33
         register(TokenTypes.LITERAL_IF, IfHandler.class);
 88  33
         register(TokenTypes.LITERAL_TRY, TryHandler.class);
 89  33
         register(TokenTypes.LITERAL_CATCH, CatchHandler.class);
 90  33
         register(TokenTypes.LITERAL_FINALLY, FinallyHandler.class);
 91  33
         register(TokenTypes.LITERAL_DO, DoWhileHandler.class);
 92  33
         register(TokenTypes.LITERAL_WHILE, WhileHandler.class);
 93  33
         register(TokenTypes.LITERAL_FOR, ForHandler.class);
 94  33
         register(TokenTypes.METHOD_DEF, MethodDefHandler.class);
 95  33
         register(TokenTypes.CTOR_DEF, MethodDefHandler.class);
 96  33
         register(TokenTypes.CLASS_DEF, ClassDefHandler.class);
 97  33
         register(TokenTypes.ENUM_DEF, ClassDefHandler.class);
 98  33
         register(TokenTypes.OBJBLOCK, ObjectBlockHandler.class);
 99  33
         register(TokenTypes.INTERFACE_DEF, ClassDefHandler.class);
 100  33
         register(TokenTypes.IMPORT, ImportHandler.class);
 101  33
         register(TokenTypes.ARRAY_INIT, ArrayInitHandler.class);
 102  33
         register(TokenTypes.METHOD_CALL, MethodCallHandler.class);
 103  33
         register(TokenTypes.CTOR_CALL, MethodCallHandler.class);
 104  33
         register(TokenTypes.LABELED_STAT, LabelHandler.class);
 105  33
         register(TokenTypes.STATIC_INIT, StaticInitHandler.class);
 106  33
         register(TokenTypes.INSTANCE_INIT, SlistHandler.class);
 107  33
         register(TokenTypes.ASSIGN, AssignHandler.class);
 108  33
         register(TokenTypes.PLUS_ASSIGN, AssignHandler.class);
 109  33
         register(TokenTypes.MINUS_ASSIGN, AssignHandler.class);
 110  33
         register(TokenTypes.STAR_ASSIGN, AssignHandler.class);
 111  33
         register(TokenTypes.DIV_ASSIGN, AssignHandler.class);
 112  33
         register(TokenTypes.MOD_ASSIGN, AssignHandler.class);
 113  33
         register(TokenTypes.SR_ASSIGN, AssignHandler.class);
 114  33
         register(TokenTypes.BSR_ASSIGN, AssignHandler.class);
 115  33
         register(TokenTypes.SL_ASSIGN, AssignHandler.class);
 116  33
         register(TokenTypes.BAND_ASSIGN, AssignHandler.class);
 117  33
         register(TokenTypes.BXOR_ASSIGN, AssignHandler.class);
 118  33
         register(TokenTypes.BOR_ASSIGN, AssignHandler.class);
 119  33
         register(TokenTypes.VARIABLE_DEF, MemberDefHandler.class);
 120  33
         register(TokenTypes.LITERAL_NEW, NewHandler.class);
 121  33
     }
 122  
 
 123  
     /**
 124  
      * Returns true if this type (form TokenTypes) is handled.
 125  
      *
 126  
      * @param aType type from TokenTypes
 127  
      * @return true if handler is registered, false otherwise
 128  
      */
 129  
     public boolean isHandledType(int aType)
 130  
     {
 131  6532
         final Set<Integer> typeSet = mTypeHandlers.keySet();
 132  6532
         return typeSet.contains(aType);
 133  
     }
 134  
 
 135  
     /**
 136  
      * Gets list of registered handler types.
 137  
      *
 138  
      * @return int[] of TokenType types
 139  
      */
 140  
     public int[] getHandledTypes()
 141  
     {
 142  33
         final Set<Integer> typeSet = mTypeHandlers.keySet();
 143  33
         final int[] types = new int[typeSet.size()];
 144  33
         int index = 0;
 145  33
         for (final Integer val : typeSet) {
 146  1287
             types[index++] = val;
 147  
         }
 148  
 
 149  33
         return types;
 150  
     }
 151  
 
 152  
     /**
 153  
      * Get the handler for an AST.
 154  
      *
 155  
      * @param aIndentCheck   the indentation check
 156  
      * @param aAst           ast to handle
 157  
      * @param aParent        the handler parent of this AST
 158  
      *
 159  
      * @return the ExpressionHandler for aAst
 160  
      */
 161  
     public ExpressionHandler getHandler(IndentationCheck aIndentCheck,
 162  
         DetailAST aAst, ExpressionHandler aParent)
 163  
     {
 164  1801
         final ExpressionHandler handler =
 165  
             mCreatedHandlers.get(aAst);
 166  1801
         if (handler != null) {
 167  25
             return handler;
 168  
         }
 169  
 
 170  1776
         if (aAst.getType() == TokenTypes.METHOD_CALL) {
 171  278
             return createMethodCallHandler(aIndentCheck, aAst, aParent);
 172  
         }
 173  
 
 174  1498
         ExpressionHandler expHandler = null;
 175  
         try {
 176  1498
             final Constructor<?> handlerCtor =
 177  
                 mTypeHandlers.get(aAst.getType());
 178  1498
             if (handlerCtor != null) {
 179  1498
                 expHandler = (ExpressionHandler) handlerCtor.newInstance(
 180  
                         aIndentCheck, aAst, aParent);
 181  
             }
 182  
         }
 183  
         ///CLOVER:OFF
 184  0
         catch (final InstantiationException e) {
 185  0
             LOG.debug("couldn't instantiate constructor for " + aAst, e);
 186  0
             throw new RuntimeException("couldn't instantiate constructor for "
 187  
                                        + aAst);
 188  
         }
 189  0
         catch (final IllegalAccessException e) {
 190  0
             LOG.debug("couldn't access constructor for " + aAst, e);
 191  0
             throw new RuntimeException("couldn't access constructor for "
 192  
                                        + aAst);
 193  
         }
 194  0
         catch (final InvocationTargetException e) {
 195  0
             LOG.debug("couldn't instantiate constructor for " + aAst, e);
 196  0
             throw new RuntimeException("couldn't instantiate constructor for "
 197  
                                        + aAst);
 198  1498
         }
 199  1498
         if (expHandler == null) {
 200  0
             throw new RuntimeException("no handler for type " + aAst.getType());
 201  
         }
 202  
         ///CLOVER:ON
 203  1498
         return expHandler;
 204  
     }
 205  
 
 206  
     /**
 207  
      * Create new instance of handler for METHOD_CALL.
 208  
      *
 209  
      * @param aIndentCheck   the indentation check
 210  
      * @param aAst           ast to handle
 211  
      * @param aParent        the handler parent of this AST
 212  
      *
 213  
      * @return new instance.
 214  
      */
 215  
     ExpressionHandler createMethodCallHandler(IndentationCheck aIndentCheck,
 216  
         DetailAST aAst, ExpressionHandler aParent)
 217  
     {
 218  278
         ExpressionHandler theParent = aParent;
 219  278
         DetailAST ast = aAst.getFirstChild();
 220  606
         while ((ast != null) && (ast.getType() == TokenTypes.DOT)) {
 221  328
             ast = ast.getFirstChild();
 222  
         }
 223  278
         if ((ast != null) && isHandledType(ast.getType())) {
 224  25
             theParent = getHandler(aIndentCheck, ast, theParent);
 225  25
             mCreatedHandlers.put(ast, theParent);
 226  
         }
 227  278
         return new MethodCallHandler(aIndentCheck, aAst, theParent);
 228  
     }
 229  
 
 230  
     /** Clears cache of created handlers. */
 231  
     void clearCreatedHandlers()
 232  
     {
 233  33
         mCreatedHandlers.clear();
 234  33
     }
 235  
 
 236  
     /** cache for created method call handlers */
 237  33
     private final Map<DetailAST, ExpressionHandler> mCreatedHandlers =
 238  
         Maps.newHashMap();
 239  
 }