summaryrefslogtreecommitdiffstats
path: root/JLanguageTool/src/java/de/danielnaber/languagetool/rules/RuleMatch.java
blob: 05746fb34493e16f7f9bf66ccd5aef90a04b5808 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/* LanguageTool, a natural language style checker 
 * Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de)
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package de.danielnaber.languagetool.rules;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import de.danielnaber.languagetool.tools.StringTools;

/**
 * A class that holds information about where a rule matches text.
 * 
 * @author Daniel Naber
 */
public class RuleMatch implements Comparable<RuleMatch> {

  private static final Pattern SUGGESTION_PATTERN = Pattern.compile("<suggestion>(.*?)</suggestion>");

  private int fromLine = -1;
  private int column = -1;
  private int offset = -1;
  private int endLine = -1;
  private int endColumn = -1;

  private Rule rule;
  private int fromPos;
  private int toPos;
  private String message;
  // for OOo context menu
  private String shortMessage;

  private List<String> suggestedReplacements = new ArrayList<String>();

//TODO: remove this one after all rules get their short comments in place 
  public RuleMatch(Rule rule, int fromPos, int toPos, String message) {
    this(rule, fromPos, toPos, message, null, false);
  }
  
  // TODO: remove this constructor?
  public RuleMatch(Rule rule, int fromPos, int toPos, String message, String shortMessage) {
    this(rule, fromPos, toPos, message, shortMessage, false);
  }

  /**
   * Creates a RuleMatch object, taking the rule that triggered
   * this match, position of the match and an explanation message.
   * This message is scanned for &lt;suggestion>...&lt;/suggestion> to get suggested
   * fixes for the problem detected by this rule. 
   * 
   * @param startWithUppercase whether the original text at the position
   *    of the match start with an uppercase character
   */
  public RuleMatch(Rule rule, int fromPos, int toPos, String message, String shortMessage, 
      boolean startWithUppercase) {
    this.rule = rule;
    this.fromPos = fromPos;
    this.toPos = toPos;
    this.message = message;
    this.shortMessage = shortMessage;
    // extract suggestion from <suggestion>...</suggestion> in message:
    final Matcher matcher = SUGGESTION_PATTERN.matcher(message);
    int pos = 0;
    while (matcher.find(pos)) {
      pos = matcher.end();
      String repl = matcher.group(1);
      if (startWithUppercase)
        repl = StringTools.uppercaseFirstChar(repl);
      suggestedReplacements.add(repl);
    }
  }

  public Rule getRule() {
    return rule;
  }

  /**
   * Set the line number in which the match occurs.
   */
  public void setLine(final int fromLine) {
    this.fromLine = fromLine;
  }

  /**
   * Get the line number in which the match occurs.
   */
  public int getLine() {
    return fromLine;
  }

  /**
   * Set the line number in which the match ends.
   */
  public void setEndLine(final int endLine) {
    this.endLine = endLine;
  }

  /**
   * Get the line number in which the match ends.
   */
  public int getEndLine() {
    return endLine;
  }

  /**
   * Set the column number in which the match occurs.
   */
  public void setColumn(final int column) {
    this.column = column;
  }

  /**
   * Get the column number in which the match occurs.
   */
  public int getColumn() {
    return column;
  }

  /**
   * Set the column number in which the match ends.
   */
  public void setEndColumn(final int endColumn) {
    this.endColumn = endColumn;
  }

  /**
   * Get the column number in which the match ends.
   */
  public int getEndColumn() {
    return endColumn;
  }

  /**
   * Set the character offset at which the match occurs.
   */
  public void setOffset(final int offset) {
    this.offset = offset;
  }

  /**
   * Get the character offset at which the match occurs.
   */
  public int getOffset() {
    return offset;
  }

  /**
   * Position of the start of the error (in characters).
   */
  public int getFromPos() {
    return fromPos;
  }

  /**
   * Position of the end of the error (in characters).
   */
  public int getToPos() {
    return toPos;
  }

  /**
   * A human-readable explanation describing the error.
   */
  public String getMessage() {
    return message;
  }  

  /**
   * A shorter human-readable explanation describing the error.
   */
  public String getShortMessage() {
    return shortMessage;
  }


  /**
   * @see #getSuggestedReplacements()
   */
  public void setSuggestedReplacement(final String replacement) {
    if (replacement == null)
      throw new NullPointerException("replacement might be empty but not null");
    final List<String> fixes = new ArrayList<String>();
    fixes.add(replacement);
    setSuggestedReplacements(fixes);
  }

  /**
   * @see #getSuggestedReplacements()
   */
  public void setSuggestedReplacements(final List<String> replacement) {
    if (replacement == null)
      throw new NullPointerException("replacement might be empty but not null");
    this.suggestedReplacements = replacement;
  }

  /**
   * The text fragments which might be an appropriate fix for the problem. One
   * of these fragments can be used to replace the old text between getFromPos()
   * to getToPos(). Text between &lt;suggestion> and &lt;/suggestion> is
   * taken as the suggested replacement. 
   * @return List of String objects or an empty List
   */
  public List<String> getSuggestedReplacements() {
    return suggestedReplacements;
  }

  @Override
  public String toString() {
    return rule.getId() + ":" + fromPos + "-" + toPos + ":" + message;
  }

  public int compareTo(final RuleMatch other) {
    if (other == null)
      throw new ClassCastException();
    if (getFromPos() < other.getFromPos())
      return -1;
    if (getFromPos() > other.getFromPos())
      return 1;
    return 0;
  }

}