001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019package com.puppycrawl.tools.checkstyle.checks.indentation; 020 021import java.util.BitSet; 022 023/** 024 * Encapsulates representation of notion of expected indentation levels. 025 * Provide a way to have multiple accaptable levels. 026 * 027 * @author o_sukhodolsky 028 */ 029public class IndentLevel 030{ 031 /** set of acceptable indentation levels. */ 032 private final BitSet levels = new BitSet(); 033 034 /** 035 * Creates new instance with one accaptable indentation level. 036 * @param indent accaptable indentation level. 037 */ 038 public IndentLevel(int indent) 039 { 040 levels.set(indent); 041 } 042 043 /** 044 * Creates new instance for nested structure. 045 * @param base parent's level 046 * @param offsets offsets from parent's level. 047 */ 048 public IndentLevel(IndentLevel base, int... offsets) 049 { 050 final BitSet src = base.levels; 051 for (int i = src.nextSetBit(0); i >= 0; i = src.nextSetBit(i + 1)) { 052 for (int offset : offsets) { 053 levels.set(i + offset); 054 } 055 } 056 } 057 058 /** 059 * Checks wether we have more than one level. 060 * @return wether we have more than one level. 061 */ 062 public final boolean isMultiLevel() 063 { 064 return levels.cardinality() > 1; 065 } 066 067 /** 068 * Checks if given indentation is acceptable. 069 * @param indent indentation to check. 070 * @return true if given indentation is acceptable, 071 * false otherwise. 072 */ 073 public boolean accept(int indent) 074 { 075 return levels.get(indent); 076 } 077 078 /** 079 * @param indent indentation to check. 080 * @return true if <code>indent</code> less then minimal of 081 * acceptable indentation levels, false otherwise. 082 */ 083 public boolean gt(int indent) 084 { 085 return levels.nextSetBit(0) > indent; 086 } 087 088 /** 089 * Adds one more acceptable indentation level. 090 * @param indent new acceptable indentation. 091 */ 092 public void addAcceptedIndent(int indent) 093 { 094 levels.set(indent); 095 } 096 097 /** 098 * Adds one more acceptable indentation level. 099 * @param indent new acceptable indentation. 100 */ 101 public void addAcceptedIndent(IndentLevel indent) 102 { 103 levels.or(indent.levels); 104 } 105 106 /** 107 * Returns first indentation level. 108 * @return indentation level. 109 */ 110 public int getFirstIndentLevel() 111 { 112 return levels.nextSetBit(0); 113 } 114 115 /** 116 * Returns last indentation level. 117 * @return indentation level. 118 */ 119 public int getLastIndentLevel() 120 { 121 return levels.length() - 1; 122 } 123 124 @Override 125 public String toString() 126 { 127 if (levels.cardinality() == 1) { 128 return String.valueOf(levels.nextSetBit(0)); 129 } 130 final StringBuilder sb = new StringBuilder(); 131 for (int i = levels.nextSetBit(0); i >= 0; 132 i = levels.nextSetBit(i + 1)) 133 { 134 if (sb.length() > 0) { 135 sb.append(", "); 136 } 137 sb.append(i); 138 } 139 return sb.toString(); 140 } 141}