Coverage Report - com.puppycrawl.tools.checkstyle.checks.indentation.HandlerFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
HandlerFactory
100%
68/68
100%
10/10
1.714
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 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  
 
 20  
 package com.puppycrawl.tools.checkstyle.checks.indentation;
 21  
 
 22  
 import java.lang.reflect.Constructor;
 23  
 import java.util.HashMap;
 24  
 import java.util.Map;
 25  
 import java.util.Set;
 26  
 
 27  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 28  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 29  
 import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
 30  
 
 31  
 /**
 32  
  * Factory for handlers. Looks up constructor via reflection.
 33  
  *
 34  
  * @author jrichard
 35  
  */
 36  
 public class HandlerFactory {
 37  
     /**
 38  
      * Registered handlers.
 39  
      */
 40  91
     private final Map<Integer, Constructor<?>> typeHandlers = new HashMap<>();
 41  
 
 42  
     /** Cache for created method call handlers. */
 43  91
     private final Map<DetailAST, AbstractExpressionHandler> createdHandlers = new HashMap<>();
 44  
 
 45  
     /** Creates a HandlerFactory. */
 46  91
     public HandlerFactory() {
 47  91
         register(TokenTypes.CASE_GROUP, CaseHandler.class);
 48  91
         register(TokenTypes.LITERAL_SWITCH, SwitchHandler.class);
 49  91
         register(TokenTypes.SLIST, SlistHandler.class);
 50  91
         register(TokenTypes.PACKAGE_DEF, PackageDefHandler.class);
 51  91
         register(TokenTypes.LITERAL_ELSE, ElseHandler.class);
 52  91
         register(TokenTypes.LITERAL_IF, IfHandler.class);
 53  91
         register(TokenTypes.LITERAL_TRY, TryHandler.class);
 54  91
         register(TokenTypes.LITERAL_CATCH, CatchHandler.class);
 55  91
         register(TokenTypes.LITERAL_FINALLY, FinallyHandler.class);
 56  91
         register(TokenTypes.LITERAL_DO, DoWhileHandler.class);
 57  91
         register(TokenTypes.LITERAL_WHILE, WhileHandler.class);
 58  91
         register(TokenTypes.LITERAL_FOR, ForHandler.class);
 59  91
         register(TokenTypes.METHOD_DEF, MethodDefHandler.class);
 60  91
         register(TokenTypes.CTOR_DEF, MethodDefHandler.class);
 61  91
         register(TokenTypes.CLASS_DEF, ClassDefHandler.class);
 62  91
         register(TokenTypes.ENUM_DEF, ClassDefHandler.class);
 63  91
         register(TokenTypes.OBJBLOCK, ObjectBlockHandler.class);
 64  91
         register(TokenTypes.INTERFACE_DEF, ClassDefHandler.class);
 65  91
         register(TokenTypes.IMPORT, ImportHandler.class);
 66  91
         register(TokenTypes.ARRAY_INIT, ArrayInitHandler.class);
 67  91
         register(TokenTypes.METHOD_CALL, MethodCallHandler.class);
 68  91
         register(TokenTypes.CTOR_CALL, MethodCallHandler.class);
 69  91
         register(TokenTypes.LABELED_STAT, LabelHandler.class);
 70  91
         register(TokenTypes.STATIC_INIT, StaticInitHandler.class);
 71  91
         register(TokenTypes.INSTANCE_INIT, SlistHandler.class);
 72  91
         register(TokenTypes.VARIABLE_DEF, MemberDefHandler.class);
 73  91
         register(TokenTypes.LITERAL_NEW, NewHandler.class);
 74  91
         register(TokenTypes.INDEX_OP, IndexHandler.class);
 75  91
         register(TokenTypes.LITERAL_SYNCHRONIZED, SynchronizedHandler.class);
 76  91
         register(TokenTypes.LAMBDA, LambdaHandler.class);
 77  91
         register(TokenTypes.ANNOTATION_DEF, ClassDefHandler.class);
 78  91
         register(TokenTypes.ANNOTATION_FIELD_DEF, MethodDefHandler.class);
 79  91
     }
 80  
 
 81  
     /**
 82  
      * Registers a handler.
 83  
      *
 84  
      * @param type
 85  
      *                type from TokenTypes
 86  
      * @param handlerClass
 87  
      *                the handler to register
 88  
      * @param <T> type of the handler class object.
 89  
      */
 90  
     private <T> void register(int type, Class<T> handlerClass) {
 91  2912
         final Constructor<T> ctor = CommonUtils.getConstructor(handlerClass,
 92  
                 IndentationCheck.class,
 93  
                 // current AST
 94  
                 DetailAST.class,
 95  
                 // parent
 96  
                 AbstractExpressionHandler.class
 97  
         );
 98  2912
         typeHandlers.put(type, ctor);
 99  2912
     }
 100  
 
 101  
     /**
 102  
      * Returns true if this type (form TokenTypes) is handled.
 103  
      *
 104  
      * @param type type from TokenTypes
 105  
      * @return true if handler is registered, false otherwise
 106  
      */
 107  
     public boolean isHandledType(int type) {
 108  6559
         final Set<Integer> typeSet = typeHandlers.keySet();
 109  6559
         return typeSet.contains(type);
 110  
     }
 111  
 
 112  
     /**
 113  
      * Gets list of registered handler types.
 114  
      *
 115  
      * @return int[] of TokenType types
 116  
      */
 117  
     public int[] getHandledTypes() {
 118  339
         final Set<Integer> typeSet = typeHandlers.keySet();
 119  339
         final int[] types = new int[typeSet.size()];
 120  339
         int index = 0;
 121  339
         for (final Integer val : typeSet) {
 122  10848
             types[index] = val;
 123  10848
             index++;
 124  10848
         }
 125  
 
 126  339
         return types;
 127  
     }
 128  
 
 129  
     /**
 130  
      * Get the handler for an AST.
 131  
      *
 132  
      * @param indentCheck   the indentation check
 133  
      * @param ast           ast to handle
 134  
      * @param parent        the handler parent of this AST
 135  
      *
 136  
      * @return the ExpressionHandler for ast
 137  
      */
 138  
     public AbstractExpressionHandler getHandler(IndentationCheck indentCheck,
 139  
         DetailAST ast, AbstractExpressionHandler parent) {
 140  
         final AbstractExpressionHandler resultHandler;
 141  3737
         final AbstractExpressionHandler handler =
 142  3737
             createdHandlers.get(ast);
 143  3737
         if (handler != null) {
 144  78
             resultHandler = handler;
 145  
         }
 146  3659
         else if (ast.getType() == TokenTypes.METHOD_CALL) {
 147  556
             resultHandler = createMethodCallHandler(indentCheck, ast, parent);
 148  
         }
 149  
         else {
 150  3103
             final Constructor<?> handlerCtor = typeHandlers.get(ast.getType());
 151  3103
             resultHandler = (AbstractExpressionHandler) CommonUtils.invokeConstructor(
 152  
                 handlerCtor, indentCheck, ast, parent);
 153  
         }
 154  3737
         return resultHandler;
 155  
     }
 156  
 
 157  
     /**
 158  
      * Create new instance of handler for METHOD_CALL.
 159  
      *
 160  
      * @param indentCheck   the indentation check
 161  
      * @param ast           ast to handle
 162  
      * @param parent        the handler parent of this AST
 163  
      *
 164  
      * @return new instance.
 165  
      */
 166  
     private AbstractExpressionHandler createMethodCallHandler(IndentationCheck indentCheck,
 167  
         DetailAST ast, AbstractExpressionHandler parent) {
 168  556
         DetailAST astNode = ast.getFirstChild();
 169  1035
         while (astNode.getType() == TokenTypes.DOT) {
 170  479
             astNode = astNode.getFirstChild();
 171  
         }
 172  556
         AbstractExpressionHandler theParent = parent;
 173  556
         if (isHandledType(astNode.getType())) {
 174  78
             theParent = getHandler(indentCheck, astNode, theParent);
 175  78
             createdHandlers.put(astNode, theParent);
 176  
         }
 177  556
         return new MethodCallHandler(indentCheck, ast, theParent);
 178  
     }
 179  
 
 180  
     /** Clears cache of created handlers. */
 181  
     public void clearCreatedHandlers() {
 182  77
         createdHandlers.clear();
 183  77
     }
 184  
 }