1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks.regexp;
21
22 import java.util.regex.Matcher;
23
24 import com.puppycrawl.tools.checkstyle.api.FileText;
25 import com.puppycrawl.tools.checkstyle.api.LineColumn;
26
27
28
29
30 class MultilineDetector {
31
32
33
34
35
36 public static final String MSG_REGEXP_EXCEEDED = "regexp.exceeded";
37
38
39
40
41
42 public static final String MSG_REGEXP_MINIMUM = "regexp.minimum";
43
44
45
46
47
48 public static final String MSG_EMPTY = "regexp.empty";
49
50
51
52
53 public static final String MSG_STACKOVERFLOW = "regexp.StackOverflowError";
54
55
56 private final DetectorOptions options;
57
58 private int currentMatches;
59
60 private Matcher matcher;
61
62 private FileText text;
63
64
65
66
67
68 MultilineDetector(DetectorOptions options) {
69 this.options = options;
70 }
71
72
73
74
75
76 public void processLines(FileText fileText) {
77 text = new FileText(fileText);
78 resetState();
79
80 final String format = options.getFormat();
81 if (format == null || format.isEmpty()) {
82 options.getReporter().log(1, MSG_EMPTY);
83 }
84 else {
85 matcher = options.getPattern().matcher(fileText.getFullText());
86 findMatch();
87 finish();
88 }
89 }
90
91
92 private void findMatch() {
93 try {
94 boolean foundMatch = matcher.find();
95
96 while (foundMatch) {
97 currentMatches++;
98 if (currentMatches > options.getMaximum()) {
99 final LineColumn start = text.lineColumn(matcher.start());
100 if (options.getMessage().isEmpty()) {
101 options.getReporter().log(start.getLine(),
102 MSG_REGEXP_EXCEEDED, matcher.pattern().toString());
103 }
104 else {
105 options.getReporter()
106 .log(start.getLine(), options.getMessage());
107 }
108 }
109 foundMatch = matcher.find();
110 }
111 }
112
113 catch (StackOverflowError ignored) {
114
115
116
117 options.getReporter().log(1, MSG_STACKOVERFLOW, matcher.pattern().toString());
118 }
119 }
120
121
122 private void finish() {
123 if (currentMatches < options.getMinimum()) {
124 if (options.getMessage().isEmpty()) {
125 options.getReporter().log(1, MSG_REGEXP_MINIMUM,
126 options.getMinimum(), options.getFormat());
127 }
128 else {
129 options.getReporter().log(1, options.getMessage());
130 }
131 }
132 }
133
134
135
136
137 private void resetState() {
138 currentMatches = 0;
139 }
140
141 }