1 package com.puppycrawl.tools.checkstyle.checks.javadoc; 20 21 import java.util.LinkedList ; 22 import java.util.List ; 23 24 34 class TagParser 35 { 36 37 private final List mTags = new LinkedList (); 38 39 44 public TagParser(String [] aText, int aLineNo) 45 { 46 parseTags(aText, aLineNo); 47 } 48 49 55 public HtmlTag nextTag() 56 { 57 return (HtmlTag) mTags.remove(0); 58 } 59 60 64 public boolean hasNextTag() 65 { 66 return (mTags.size() > 0); 67 } 68 69 74 private void add(HtmlTag aTag) 75 { 76 mTags.add(aTag); 77 } 78 79 85 private void parseTags(String [] aText, int aLineNo) 86 { 87 final int nLines = aText.length; 88 Point position = new Point(0, 0); 89 90 position = findChar(aText, '<', position); 91 while (position.getLineNo() < nLines) { 92 if (isCommentTag(aText, position)) { 94 position = skipHtmlComment(aText, position); 95 } 96 else if (!isTag(aText, position)) { 97 position = getNextCharPos(aText, position); 98 } 99 else { 100 final Point endTag = findChar(aText, '>', position); 102 final boolean incompleteTag = (endTag.getLineNo() >= nLines); 103 final String tagId = 105 (incompleteTag ? "" : getTagId(aText, position)); 106 final boolean closedTag = 108 ((endTag.getLineNo() < nLines) && (endTag.getColumnNo() > 0) 109 && (aText[endTag.getLineNo()] 110 .charAt(endTag.getColumnNo() - 1) == '/')); 111 add(new HtmlTag(tagId, 113 position.getLineNo() + aLineNo, 114 position.getColumnNo(), 115 closedTag, 116 incompleteTag, 117 aText[position.getLineNo()])); 118 position = endTag; 119 } 120 position = findChar(aText, '<', position); 121 } 122 } 123 124 130 private boolean isTag(String [] aText, Point aPos) 131 { 132 final int column = aPos.getColumnNo() + 1; 133 final String text = aText[aPos.getLineNo()]; 134 135 return (((column < text.length()) 136 && (((text.charAt(column) >= 'A') 137 && (text.charAt(column) <= 'Z')) 138 || ((text.charAt(column) >= 'a') 139 && (text.charAt(column) <= 'z')) 140 || (text.charAt(column) == '/'))) 141 || (column >= text.length())); 142 } 143 144 150 private String getTagId(String [] aText, Point aTagStart) 151 { 152 int column = aTagStart.getColumnNo() + 1; 153 String text = aText[aTagStart.getLineNo()]; 154 if (column >= text.length()) { 155 return ""; 156 } 157 158 if (text.charAt(column) == '/') { 159 column++; 160 } 161 162 text = text.substring(column).trim(); 163 column = 0; 164 165 while ((column < text.length()) 166 && (((text.charAt(column) >= 'A') 167 && (text.charAt(column) <= 'Z')) 168 || ((text.charAt(column) >= 'a') 169 && (text.charAt(column) <= 'z')) 170 || ((text.charAt(column) >= '0') 171 && (text.charAt(column) <= '9')))) 172 { 173 column++; 174 } 175 176 return text.substring(0, column); 177 } 178 179 186 private boolean isCommentTag(String [] aText, Point aPos) 187 { 188 return aText[aPos.getLineNo()].startsWith("<!--", aPos.getColumnNo()); 189 } 190 191 197 private Point skipHtmlComment(String [] aText, Point aFrom) 198 { 199 Point to = aFrom; 200 to = findChar(aText, '>', to); 201 while ((to.getLineNo() < aText.length) 202 && !aText[to.getLineNo()] 203 .substring(0, to.getColumnNo()).endsWith("-->")) 204 { 205 to = findChar(aText, '>', getNextCharPos(aText, to)); 206 } 207 return to; 208 } 209 210 217 private Point findChar(String [] aText, char aChar, Point aFrom) 218 { 219 Point curr = new Point(aFrom.getLineNo(), aFrom.getColumnNo()); 220 while ((curr.getLineNo() < aText.length) 221 && (aText[curr.getLineNo()].charAt(curr.getColumnNo()) != aChar)) 222 { 223 curr = getNextCharPos(aText, curr); 224 } 225 226 return curr; 227 } 228 229 236 private Point getNextCharPos(String [] aText, Point aFrom) 237 { 238 int line = aFrom.getLineNo(); 239 int column = aFrom.getColumnNo() + 1; 240 while ((line < aText.length) && (column >= aText[line].length())) { 241 line++; 243 column = 0; 244 if (line < aText.length) { 245 final String currentLine = aText[line]; 247 while ((column < currentLine.length()) 248 && (Character.isWhitespace(currentLine.charAt(column)) 249 || (currentLine.charAt(column) == '*'))) 250 { 251 column++; 252 if ((column < currentLine.length()) 253 && (currentLine.charAt(column - 1) == '*') 254 && (currentLine.charAt(column) == '/')) 255 { 256 column = currentLine.length(); 258 } 259 } 260 } 261 } 262 263 return new Point(line, column); 264 } 265 } 266 267 271 final class Point 272 { 273 274 private final int mLine; 275 276 private final int mColumn; 277 278 283 public Point(int aLineNo, int aColumnNo) 284 { 285 mLine = aLineNo; 286 mColumn = aColumnNo; 287 } 288 289 293 public int getLineNo() 294 { 295 return mLine; 296 } 297 298 302 public int getColumnNo() 303 { 304 return mColumn; 305 } 306 } 307 | Popular Tags |