KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > incava > doctorj > CommentSpellCheck


1 package org.incava.doctorj;
2
3 import java.io.*;
4 import java.util.*;
5 import org.incava.io.FileExt;
6 import org.incava.text.*;
7
8
9 public class CommentSpellCheck
10 {
11     public static CommentSpellCheck instance = null;
12
13     public static CommentSpellCheck getInstance()
14     {
15         if (instance == null) {
16             instance = new CommentSpellCheck();
17         }
18         return instance;
19     }
20
21     private boolean _canCheck;
22
23     private SpellChecker _checker;
24
25     /**
26      * The current description we're working on.
27      */

28     private String JavaDoc _desc;
29
30     /**
31      * The length of the current description.
32      */

33     private int _len;
34
35     /**
36      * The current position within the description.
37      */

38     private int _pos;
39     
40     protected CommentSpellCheck()
41     {
42         _checker = new NoCaseSpellChecker();
43         _canCheck = false;
44     }
45
46     public boolean addDictionary(String JavaDoc dictionary)
47     {
48         _canCheck = _checker.addDictionary(dictionary) || _canCheck;
49         return _canCheck;
50     }
51
52     public void addWord(String JavaDoc word)
53     {
54         _checker.addWord(word);
55         _canCheck = true;
56     }
57
58     public void check(String JavaDoc description)
59     {
60         if (_canCheck) {
61             // tr.Ace.log("checking '" + description + "'");
62

63             _desc = description;
64             _len = _desc.length();
65             _pos = 0;
66     
67             while (_pos < _len) {
68                 skipToWord();
69                 if (_pos < _len) {
70                     if (Character.isLetter(_desc.charAt(_pos))) {
71                         checkCurrentWord();
72                     }
73                     else {
74                         // not at an alpha character. Might be some screwy formatting or
75
// a nonstandard tag.
76
skipThroughWord();
77                     }
78                 }
79             }
80         }
81     }
82
83     protected void skipSection(String JavaDoc section)
84     {
85         // tr.Ace.log("section: " + section);
86
if (consume("<" + section + ">")) {
87             // tr.Ace.log("got section: " + section);
88
consumeTo("</" + section + ">");
89         }
90     }
91     
92     protected void skipLink()
93     {
94         if (consume("{@link")) {
95             consumeTo("}");
96         }
97     }
98
99     protected void skipBlanks()
100     {
101         while (_pos + 2 < _len && _desc.charAt(_pos) != '<' && !_desc.substring(_pos, _pos + 2).equals("{@") && !Character.isLetterOrDigit(_desc.charAt(_pos))) {
102             ++_pos;
103         }
104     }
105     
106     protected void skipToWord()
107     {
108         skipSection("code");
109         skipSection("pre");
110         skipLink();
111         consume("&nbsp;");
112     }
113
114     protected void checkWord(String JavaDoc word, int position)
115     {
116         // tr.Ace.log("checking word '" + word + "' at position " + position);
117

118         Map nearMatches = new TreeMap();
119         boolean valid = _checker.isCorrect(word, nearMatches);
120         if (!valid) {
121             wordMisspelled(word, position, nearMatches);
122         }
123     }
124
125     protected void wordMisspelled(String JavaDoc word, int position, Map nearMatches)
126     {
127         int nPrinted = 0;
128         final int printGoal = 15;
129         for (int i = 0; nPrinted < printGoal && i < 4; ++i) { // 4 == max edit distance
130
Integer JavaDoc eDist = new Integer JavaDoc(i);
131             List matches = (List)nearMatches.get(eDist);
132             if (matches != null) {
133                 Iterator it = matches.iterator();
134                 while (it.hasNext()) {
135                     // This is not debugging output -- this is actually wanted.
136
// But I often run "glark '^\s*System.out' to find all my
137
// print statements, so we'll hide this very sneakily:
138
/* escond */ System.out.println(" near match '" + it.next() + "': " + i);
139                     ++nPrinted;
140                 }
141             }
142         }
143     }
144
145     protected boolean consume(String JavaDoc what)
146     {
147         skipBlanks();
148         if (_pos + what.length() < _len && _desc.substring(_pos).startsWith(what)) {
149             _pos += what.length();
150             return true;
151         }
152         else {
153             return false;
154         }
155     }
156
157     protected void consumeTo(String JavaDoc what)
158     {
159         int _len = _desc.length();
160         while (_pos < _len && _pos + what.length() < _len && !_desc.substring(_pos).startsWith(what)) {
161             ++_pos;
162         }
163     }
164
165     protected void checkCurrentWord()
166     {
167         StringBuffer JavaDoc word = new StringBuffer JavaDoc();
168         word.append(_desc.charAt(_pos));
169         
170         int startingPosition = _pos;
171         boolean canCheck = true;
172
173         ++_pos;
174
175         // spell check words that do not have:
176
// - mixed case (varName)
177
// - embedded punctuation ("wouldn't", "pkg.foo")
178
// - numbers (M16, BR549)
179
while (_pos < _len) {
180             char ch = _desc.charAt(_pos);
181             if (Character.isWhitespace(ch)) {
182                 break;
183             }
184             else if (Character.isLowerCase(ch)) {
185                 word.append(ch);
186                 ++_pos;
187             }
188             else if (Character.isUpperCase(ch)) {
189                 skipThroughWord();
190                 return;
191             }
192             else if (Character.isDigit(ch)) {
193                 skipThroughWord();
194                 return;
195             }
196             else {
197                 // must be punctuation, which we can check it if there's nothing
198
// but punctuation up to the next space or end of description.
199
if (_pos + 1 == _len) {
200                     // that's OK to check
201
break;
202                 }
203                 else {
204                     ++_pos;
205                     while (_pos < _len && !Character.isWhitespace(_desc.charAt(_pos)) && !Character.isLetterOrDigit(_desc.charAt(_pos))) {
206                         // skipping through punctuation
207
++_pos;
208                     }
209                     if (_pos == _len || Character.isWhitespace(_desc.charAt(_pos))) {
210                         // punctuation ended the word, so we can check this
211
break;
212                     }
213                     else {
214                         // punctuation did NOT end the word, so we can NOT check this
215
skipThroughWord();
216                         return;
217                     }
218                 }
219             }
220         }
221
222         // tr.Ace.log("word: '" + word + "'");
223

224         // has to be more than one character:
225
if (canCheck && _pos - startingPosition > 1) {
226             checkWord(word.toString(), startingPosition);
227         }
228     }
229
230     protected void skipThroughWord()
231     {
232         ++_pos;
233         while (_pos < _len && !Character.isWhitespace(_desc.charAt(_pos))) {
234             ++_pos;
235         }
236     }
237
238 }
239
Popular Tags