1 19 20 package org.netbeans.editor.ext; 21 22 import java.util.HashMap ; 23 import java.util.ArrayList ; 24 import javax.swing.text.Position ; 25 import org.netbeans.editor.TokenItem; 26 27 34 35 class FormatTokenPositionSupport { 36 37 private final FormatWriter formatWriter; 38 39 40 private SaveSet firstSet; 41 42 43 private SaveSet lastSet; 44 45 46 private final HashMap tokens2positionLists = new HashMap (); 47 48 FormatTokenPositionSupport(FormatWriter formatWriter) { 49 this.formatWriter = formatWriter; 50 } 51 52 private ArrayList getPosList(TokenItem token) { 53 ArrayList ret = (ArrayList )tokens2positionLists.get(token); 54 if (ret == null) { 55 ret = new ArrayList (3); 56 tokens2positionLists.put(token, ret); 57 } 58 return ret; 59 } 60 61 66 synchronized ExtTokenPosition getTokenPosition(TokenItem token, int offset, 67 Position.Bias bias) { 68 if (token == null) { 70 if (offset != 0) { 71 throw new IllegalArgumentException ( 72 "Ending token position has non-zero offset=" + offset); } 74 75 } else if (offset >= token.getImage().length()) { 76 throw new IllegalArgumentException ("Offset=" + offset + " >= tokenLength=" + token.getImage().length()); } 79 80 ArrayList posList = getPosList(token); 81 int cnt = posList.size(); 82 ExtTokenPosition etp; 83 for (int i = 0; i < cnt; i++) { 84 etp = (ExtTokenPosition)posList.get(i); 85 if (etp.getOffset() == offset && etp.getBias() == bias) { 86 return etp; 87 } 88 } 89 90 etp = new ExtTokenPosition(token, offset, bias); 91 posList.add(etp); 92 return etp; 93 } 94 95 103 synchronized void splitStartTokenPositions(TokenItem token, int startLength) { 104 TokenItem prevToken = token.getPrevious(); 105 if (prevToken != null) { 106 prevToken = formatWriter.findNonEmptyToken(prevToken, true); 107 } 108 ArrayList posList = getPosList(token); 109 int len = posList.size(); 110 ArrayList prevPosList = getPosList(prevToken); 111 for (int i = 0; i < len; i++) { 112 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 113 if (etp.offset < startLength) { etp.token = prevToken; 115 posList.remove(i); 116 prevPosList.add(etp); 117 i--; 118 len--; 119 } 120 } 121 } 122 123 131 synchronized void splitEndTokenPositions(TokenItem token, int endLength) { 132 TokenItem nextToken = token.getNext(); 133 if (nextToken != null) { 134 nextToken = formatWriter.findNonEmptyToken(nextToken, false); 135 } 136 ArrayList nextPosList = getPosList(nextToken); 137 138 ArrayList posList = getPosList(token); 139 int len = posList.size(); 140 int offset = token.getImage().length() - endLength; 141 for (int i = 0; i < len; i++) { 142 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 143 if (etp.offset >= offset) { etp.token = nextToken; 145 etp.offset -= offset; 146 posList.remove(i); 147 nextPosList.add(etp); 148 i--; 149 len--; 150 } 151 } 152 } 153 154 155 synchronized void tokenTextInsert(TokenItem token, int offset, int length) { 156 ArrayList posList = getPosList(token); 157 int len = posList.size(); 158 for (int i = 0; i < len; i++) { 160 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 161 if ((etp.bias == Position.Bias.Backward) 162 ? (etp.offset > offset) : (etp.offset >= offset)) { 163 etp.offset += length; 164 } 165 } 166 167 if (token.getImage().length() == offset) { 169 TokenItem nextToken = token.getNext(); 170 if (nextToken != null) { 171 nextToken = formatWriter.findNonEmptyToken(nextToken, false); 172 } 173 posList = getPosList(nextToken); 174 len = posList.size(); 175 for (int i = 0; i < len; i++) { 176 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 177 if (etp.bias == Position.Bias.Backward && etp.offset == 0) { 178 etp.token = token; 179 etp.offset = offset; 180 } 181 } 182 } 183 184 185 } 186 187 188 synchronized void tokenTextRemove(TokenItem token, int offset, int length) { 189 ArrayList posList = getPosList(token); 190 int len = posList.size(); 191 int newLen = token.getImage().length() - length; 192 ArrayList nextList = getPosList(token.getNext()); 193 for (int i = 0; i < len; i++) { 194 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 195 if (etp.offset >= offset + length) { etp.offset -= length; 197 198 } else if (etp.offset >= offset) { 199 etp.offset = offset; 200 } 201 202 if (etp.offset >= newLen) { etp.token = token.getNext(); 205 etp.offset = 0; 206 posList.remove(i); 207 nextList.add(etp); 208 i--; 209 len--; 210 } 211 } 212 } 213 214 215 synchronized void tokenRemove(TokenItem token) { 216 TokenItem nextToken = token.getNext(); 217 if (nextToken != null) { 218 nextToken = formatWriter.findNonEmptyToken(nextToken, false); 219 } 220 ArrayList nextPosList = getPosList(nextToken); 221 222 ArrayList posList = getPosList(token); 223 int len = posList.size(); 224 for (int i = 0; i < len; i++) { 225 ExtTokenPosition etp = (ExtTokenPosition)posList.get(i); 226 etp.token = nextToken; 227 etp.offset = 0; 228 nextPosList.add(etp); 229 } 230 posList.clear(); 231 232 tokens2positionLists.remove(token); 234 } 235 236 237 synchronized void tokenInsert(TokenItem token) { 238 if (token.getImage().length() > 0) { ArrayList posList = getPosList(token); 240 241 TokenItem nextToken = token.getNext(); 242 if (nextToken != null) { 243 nextToken = formatWriter.findNonEmptyToken(nextToken, false); 244 } 245 ArrayList nextPosList = getPosList(nextToken); 246 247 int nextLen = nextPosList.size(); 248 for (int i = 0; i < nextLen; i++) { 249 ExtTokenPosition etp = (ExtTokenPosition)nextPosList.get(i); 250 if (etp.offset == 0 && etp.getBias() == Position.Bias.Backward) { 251 etp.token = token; nextPosList.remove(i); 253 i--; 254 nextLen--; 255 posList.add(etp); 256 } 257 } 258 } 259 } 260 261 262 synchronized void clearSaveSets() { 263 firstSet = null; 264 lastSet = null; 265 } 266 267 270 synchronized void addSaveSet(int baseOffset, int writtenLen, 271 int[] offsets, Position.Bias [] biases) { 272 for (int i = 0; i < offsets.length; i++) { 274 if (offsets[i] < 0 || offsets[i] > writtenLen) { 275 throw new IllegalArgumentException ( 276 "Invalid save-offset=" + offsets[i] + " at index=" + i + ". Written length is " + writtenLen); } 279 } 280 281 SaveSet newSet = new SaveSet(baseOffset, offsets, biases); 282 283 if (firstSet != null) { 284 lastSet.next = newSet; 285 lastSet = newSet; 286 287 } else { firstSet = lastSet = newSet; 289 } 290 } 291 292 293 synchronized void createPositions(FormatTokenPosition formatStartPosition) { 294 updateSaveOffsets(formatStartPosition); 295 296 SaveSet curSet = firstSet; 297 FormatWriter.FormatTokenItem token 298 = (FormatWriter.FormatTokenItem)formatStartPosition.getToken(); 299 boolean noText = (token == null); 300 301 while (curSet != null) { 302 int len = curSet.offsets.length; 303 for (int i = 0; i < len; i++) { 304 if (noText) { 305 curSet.positions[i] = getTokenPosition(null, 0, curSet.biases[i]); 306 307 } else { 309 int offset = curSet.offsets[i]; 311 while (token != null) { 312 if (offset < token.getSaveOffset()) { 313 token = (FormatWriter.FormatTokenItem)token.getPrevious(); 314 315 } else if ((offset > token.getSaveOffset() + token.getImage().length()) 316 || token.getImage().length() == 0 317 ) { 318 token = (FormatWriter.FormatTokenItem)token.getNext(); 319 320 } else { curSet.positions[i] = getTokenPosition(token, 322 offset - token.getSaveOffset(), curSet.biases[i]); 323 break; } 325 } 326 327 if (token == null) { curSet.positions[i] = getTokenPosition(null, 0, curSet.biases[i]); 329 token = (FormatWriter.FormatTokenItem)formatWriter.getLastToken(); 330 } 331 } 332 } 333 334 curSet = curSet.next; 335 } 336 } 337 338 synchronized void updateSaveSets(FormatTokenPosition formatStartPosition) { 339 updateSaveOffsets(formatStartPosition); 340 341 SaveSet curSet = firstSet; 342 int endOffset = 0; if (formatStartPosition.getToken() != null) { 344 endOffset = ((FormatWriter.FormatTokenItem)formatWriter.getLastToken()).getSaveOffset() 345 + formatWriter.getLastToken().getImage().length(); 346 } 347 348 while (curSet != null) { 349 int len = curSet.offsets.length; 350 for (int i = 0; i < len; i++) { 351 FormatWriter.FormatTokenItem token 352 = (FormatWriter.FormatTokenItem)curSet.positions[i].getToken(); 353 if (token == null) { 354 curSet.offsets[i] = endOffset; 355 356 } else { curSet.offsets[i] = token.getSaveOffset() 358 + curSet.positions[i].getOffset(); 359 } 360 } 361 } 362 } 363 364 367 private void updateSaveOffsets(FormatTokenPosition formatStartPosition) { 368 if (firstSet != null) { FormatWriter.FormatTokenItem ti 370 = (FormatWriter.FormatTokenItem)formatStartPosition.getToken(); 371 int offset = -formatStartPosition.getOffset(); 372 373 while (ti != null) { 374 ti.setSaveOffset(offset); 375 offset += ti.getImage().length(); 376 377 ti = (FormatWriter.FormatTokenItem)ti.getNext(); 378 } 379 } 380 } 381 382 385 class ExtTokenPosition implements FormatTokenPosition { 386 387 TokenItem token; 388 389 int offset; 390 391 392 Position.Bias bias; 393 394 ExtTokenPosition(TokenItem token, int offset) { 395 this(token, offset, Position.Bias.Forward); 396 } 397 398 ExtTokenPosition(TokenItem token, int offset, Position.Bias bias) { 399 this.token = token; 400 this.offset = offset; 401 this.bias = bias; 402 } 403 404 public TokenItem getToken() { 405 return token; 406 } 407 408 public int getOffset() { 409 return (token != null) ? offset : 0; 410 } 411 412 public Position.Bias getBias() { 413 return bias; 414 } 415 416 public boolean equals(Object o) { 417 return equals(o, true); } 419 420 public boolean equals(Object o, boolean ignoreBias) { 421 if (o instanceof FormatTokenPosition) { 422 FormatTokenPosition tp = (FormatTokenPosition)o; 423 424 return token == tp.getToken() && offset == tp.getOffset() 425 && (ignoreBias || bias == tp.getBias()); 426 } 427 428 return false; 429 } 430 431 public String toString() { 432 return "<" + getToken() + ", " + getOffset() + ", " + getBias() + ">"; } 434 435 } 436 437 440 static class SaveSet { 441 442 443 SaveSet next; 444 445 446 int baseOffset; 447 448 449 int[] offsets; 450 451 452 Position.Bias [] biases; 453 454 455 FormatTokenPosition[] positions; 456 457 SaveSet(int baseOffset, int[] offsets, Position.Bias [] biases) { 458 this.baseOffset = baseOffset; 459 this.offsets = offsets; 460 this.biases = biases; 461 } 462 463 } 464 465 } 466 | Popular Tags |