1 30 31 package de.susebox.jtopas; 32 33 import java.lang.ref.WeakReference ; 37 import java.util.Iterator ; 38 import java.util.LinkedList ; 39 import java.util.Map ; 40 import java.util.TreeMap ; 41 42 import de.susebox.java.lang.ExtIllegalArgumentException; 43 44 45 49 63 public abstract class AbstractTokenizerProperties implements TokenizerProperties 64 { 65 66 70 88 protected abstract TokenizerProperty doAddProperty(TokenizerProperty property); 89 90 111 protected abstract TokenizerProperty doRemoveProperty(TokenizerProperty property); 112 113 129 protected abstract TokenizerProperty doGetProperty(int type, String startImage); 130 131 150 protected abstract String doSetWhitespaces(String whitespaces); 151 152 172 protected abstract String doSetSeparators(String separators); 173 174 175 179 185 public void setParseFlags(int flags) { 186 flags = normalizeFlags(flags, flags); 188 189 synchronized(this) { 191 int oldFlags = _flags; 192 193 _flags = flags; 194 if (oldFlags != _flags) { 195 notifyListeners(new TokenizerPropertyEvent( 196 TokenizerPropertyEvent.PROPERTY_MODIFIED, 197 new TokenizerProperty(TokenizerProperty.PARSE_FLAG_MASK, 198 new String [] { Integer.toBinaryString(_flags) } ), 199 new TokenizerProperty(TokenizerProperty.PARSE_FLAG_MASK, 200 new String [] { Integer.toBinaryString(oldFlags) } ))); 201 } 202 } 203 } 204 205 211 public int getParseFlags() { 212 return _flags; 213 } 214 215 224 public boolean isFlagSet(int flag) { 225 return (_flags & flag) == flag; 226 } 227 228 240 public boolean isFlagSet(TokenizerProperty prop, int flag) throws NullPointerException { 241 return prop.isFlagSet(flag, isFlagSet(flag)); 242 } 243 244 245 249 260 public void setWhitespaces(String whitespaces) { 261 String newValue = (whitespaces != null) ? whitespaces : ""; 263 String oldValue; 264 265 if ((_flags & Flags.F_NO_CASE) != 0) { 266 newValue = newValue.toUpperCase(); 267 } 268 269 synchronized(this) { 271 oldValue = doSetWhitespaces(newValue); 272 273 handleEvent(Token.WHITESPACE, newValue, oldValue); 275 } 276 } 277 278 285 public void addWhitespaces(String whitespaces) throws IllegalArgumentException { 286 try { 287 if (whitespaces.length() > 0) { 288 setWhitespaces(mergeSet(getWhitespaces(), whitespaces, false)); 289 } 290 } catch (NullPointerException ex) { 291 throw new IllegalArgumentException (); 292 } 293 } 294 295 302 public void removeWhitespaces(String whitespaces) throws IllegalArgumentException { 303 try { 304 if (whitespaces.length() > 0) { 305 setWhitespaces(mergeSet(getWhitespaces(), whitespaces, true)); 306 } 307 } catch (NullPointerException ex) { 308 throw new IllegalArgumentException (); 309 } 310 } 311 312 323 public void setSeparators(String separators) { 324 String newValue = (separators != null) ? separators : ""; 326 String oldValue; 327 328 if ((_flags & Flags.F_NO_CASE) != 0) { 329 newValue = newValue.toUpperCase(); 330 } 331 332 synchronized(this) { 334 oldValue = doSetSeparators(newValue); 335 336 handleEvent(Token.SEPARATOR, newValue, oldValue); 338 } 339 } 340 341 348 public void addSeparators(String separators) throws IllegalArgumentException { 349 try { 350 if (separators.length() > 0) { 351 setSeparators(mergeSet(getSeparators(), separators, false)); 352 } 353 } catch (NullPointerException ex) { 354 throw new IllegalArgumentException (); 355 } 356 } 357 358 365 public void removeSeparators(String separators) throws IllegalArgumentException { 366 try { 367 if (separators.length() > 0) { 368 setSeparators(mergeSet(getSeparators(), separators, true)); 369 } 370 } catch (NullPointerException ex) { 371 throw new IllegalArgumentException (); 372 } 373 } 374 375 376 380 392 public void addString(String start, String end, String escape) 393 throws IllegalArgumentException 394 { 395 addString(start, end, escape, null); 396 } 397 398 409 public void addString(String start, String end, String escape, Object companion) 410 throws IllegalArgumentException 411 { 412 addString(start, end, escape, companion, getParseFlags()); 413 } 414 415 426 public void addString(String start, String end, String escape, Object companion, int flags) 427 throws IllegalArgumentException 428 { 429 addString(start, end, escape, companion, flags, flags); 430 } 431 432 444 public void addString(String start, String end, String escape, Object companion, int flags, int flagMask) 445 throws IllegalArgumentException 446 { 447 addProperty( 448 new TokenizerProperty(Token.STRING, new String [] { start, end, escape }, 449 companion, flags, flagMask) 450 ); 451 } 452 453 460 public void removeString(String start) throws IllegalArgumentException { 461 TokenizerProperty prop = getString(start); 462 463 if (prop != null) { 464 removeProperty(prop); 465 } 466 } 467 468 469 477 public Object getStringCompanion(String start) throws IllegalArgumentException { 478 TokenizerProperty prop = getString(start); 479 480 if (prop != null) { 481 return prop.getCompanion(); 482 } else { 483 return null; 484 } 485 } 486 487 488 496 public boolean stringExists(String start) { 497 try { 498 return getString(start) != null; 499 } catch (IllegalArgumentException ex) { 500 return false; 501 } 502 } 503 504 512 public TokenizerProperty getString(String start) throws IllegalArgumentException { 513 checkArgument(start, "String"); 515 516 synchronized(this) { 518 return doGetProperty(Token.STRING, start); 519 } 520 } 521 522 523 527 534 public void addLineComment(String lineComment) throws IllegalArgumentException { 535 addLineComment(lineComment, null); 536 } 537 538 546 public void addLineComment(String lineComment, Object companion) throws IllegalArgumentException { 547 addLineComment(lineComment, companion, getParseFlags()); 548 } 549 550 551 561 public void addLineComment(String lineComment, Object companion, int flags) throws IllegalArgumentException { 562 addLineComment(lineComment, companion, flags, flags); 563 } 564 565 575 public void addLineComment(String lineComment, Object companion, int flags, int flagMask) 576 throws IllegalArgumentException 577 { 578 addProperty( 579 new TokenizerProperty(Token.LINE_COMMENT, new String [] { lineComment }, 580 companion, flags, flagMask) 581 ); 582 } 583 584 591 public void removeLineComment(String lineComment) throws IllegalArgumentException { 592 TokenizerProperty prop = getLineComment(lineComment); 593 594 if (prop != null) { 595 removeProperty(prop); 596 } 597 } 598 599 600 608 public Object getLineCommentCompanion(String lineComment) throws IllegalArgumentException { 609 TokenizerProperty prop = getLineComment(lineComment); 610 611 if (prop != null) { 612 return prop.getCompanion(); 613 } else { 614 return null; 615 } 616 } 617 618 626 public boolean lineCommentExists(String lineComment) { 627 try { 628 return getLineComment(lineComment) != null; 629 } catch (IllegalArgumentException ex) { 630 return false; 631 } 632 } 633 634 642 public TokenizerProperty getLineComment(String lineComment) throws IllegalArgumentException { 643 checkArgument(lineComment, "Line comment"); 645 646 synchronized(this) { 648 return doGetProperty(Token.LINE_COMMENT, lineComment); 649 } 650 } 651 652 653 657 666 public void addBlockComment(String start, String end) throws IllegalArgumentException { 667 addBlockComment(start, end, null); 668 } 669 670 680 public void addBlockComment(String start, String end, Object companion) throws IllegalArgumentException { 681 addBlockComment(start, end, companion, getParseFlags()); 682 } 683 684 695 public void addBlockComment(String start, String end, Object companion, int flags) throws IllegalArgumentException { 696 addBlockComment(start, end, companion, flags, flags); 697 } 698 699 710 public void addBlockComment(String start, String end, Object companion, int flags, int flagMask) 711 throws IllegalArgumentException 712 { 713 addProperty( 714 new TokenizerProperty(Token.BLOCK_COMMENT, new String [] { start, end }, 715 companion, flags, flagMask) 716 ); 717 } 718 719 727 public void removeBlockComment(String start) throws IllegalArgumentException { 728 TokenizerProperty prop = getBlockComment(start); 729 730 if (prop != null) { 731 removeProperty(prop); 732 } 733 } 734 735 744 public Object getBlockCommentCompanion(String start) throws IllegalArgumentException { 745 TokenizerProperty prop = getBlockComment(start); 746 747 if (prop != null) { 748 return prop.getCompanion(); 749 } else { 750 return null; 751 } 752 } 753 754 762 public boolean blockCommentExists(String start) { 763 try { 764 return getBlockComment(start) != null; 765 } catch (IllegalArgumentException ex) { 766 return false; 767 } 768 } 769 770 778 public TokenizerProperty getBlockComment(String start) throws IllegalArgumentException { 779 checkArgument(start, "Block comment"); 781 782 synchronized(this) { 784 return doGetProperty(Token.BLOCK_COMMENT, start); 785 } 786 } 787 788 789 793 802 public void addSpecialSequence(String specSeq) throws IllegalArgumentException { 803 addSpecialSequence(specSeq, null); 804 } 805 806 807 817 public void addSpecialSequence(String specSeq, Object companion) throws IllegalArgumentException { 818 addSpecialSequence(specSeq, companion, getParseFlags()); 819 } 820 821 822 833 public void addSpecialSequence(String specSeq, Object companion, int flags) throws IllegalArgumentException { 834 addSpecialSequence(specSeq, companion, flags, flags); 835 } 836 837 847 public void addSpecialSequence(String specSeq, Object companion, int flags, int flagMask) 848 throws IllegalArgumentException 849 { 850 addProperty( 851 new TokenizerProperty(Token.SPECIAL_SEQUENCE, new String [] { specSeq }, 852 companion, flags, flagMask) 853 ); 854 } 855 856 863 public void removeSpecialSequence(String specSeq) throws IllegalArgumentException { 864 TokenizerProperty prop = getSpecialSequence(specSeq); 865 866 if (prop != null) { 867 removeProperty(prop); 868 } 869 } 870 871 872 880 public Object getSpecialSequenceCompanion(String specSeq) throws IllegalArgumentException { 881 TokenizerProperty prop = getSpecialSequence(specSeq); 882 883 if (prop != null) { 884 return prop.getCompanion(); 885 } else { 886 return null; 887 } 888 } 889 890 891 899 public boolean specialSequenceExists(String specSeq) { 900 try { 901 return getSpecialSequence(specSeq) != null; 902 } catch (IllegalArgumentException ex) { 903 return false; 904 } 905 } 906 907 915 public TokenizerProperty getSpecialSequence(String specSeq) throws IllegalArgumentException { 916 checkArgument(specSeq, "Special sequence"); 918 919 synchronized(this) { 921 return doGetProperty(Token.SPECIAL_SEQUENCE, specSeq); 922 } 923 } 924 925 926 930 937 public void addKeyword(String keyword) throws IllegalArgumentException { 938 addKeyword(keyword, null); 939 } 940 941 942 950 public void addKeyword(String keyword, Object companion) throws IllegalArgumentException { 951 addKeyword(keyword, companion, getParseFlags()); 952 } 953 954 955 963 public void addKeyword(String keyword, Object companion, int flags) throws IllegalArgumentException { 964 addKeyword(keyword, companion, flags, flags); 965 } 966 967 977 public void addKeyword(String keyword, Object companion, int flags, int flagMask) 978 throws IllegalArgumentException 979 { 980 addProperty( 981 new TokenizerProperty(Token.KEYWORD, new String [] { keyword }, companion, flags, flagMask) 982 ); 983 } 984 985 992 public void removeKeyword(String keyword) throws IllegalArgumentException { 993 TokenizerProperty prop = getKeyword(keyword); 994 995 if (prop != null) { 996 removeProperty(prop); 997 } 998 } 999 1000 1001 1009 public Object getKeywordCompanion(String keyword) throws IllegalArgumentException { 1010 TokenizerProperty prop = getKeyword(keyword); 1011 1012 if (prop != null) { 1013 return prop.getCompanion(); 1014 } else { 1015 return null; 1016 } 1017 } 1018 1019 1027 public boolean keywordExists(String keyword) { 1028 try { 1029 return getKeyword(keyword) != null; 1030 } catch (IllegalArgumentException ex) { 1031 return false; 1032 } 1033 } 1034 1035 1043 public TokenizerProperty getKeyword(String keyword) throws IllegalArgumentException { 1044 checkArgument(keyword, "Keyword"); 1046 1047 synchronized(this) { 1049 return doGetProperty(Token.KEYWORD, keyword); 1050 } 1051 } 1052 1053 1054 1058 1068 public void addPattern(String pattern) throws IllegalArgumentException { 1069 addPattern(pattern, null); 1070 } 1071 1072 1084 public void addPattern(String pattern, Object companion) throws IllegalArgumentException { 1085 addPattern(pattern, companion, getParseFlags()); 1086 } 1087 1088 1101 public void addPattern(String pattern, Object companion, int flags) throws IllegalArgumentException { 1102 addPattern(pattern, companion, flags, flags); 1103 } 1104 1105 1116 public void addPattern(String pattern, Object companion, int flags, int flagMask) 1117 throws IllegalArgumentException 1118 { 1119 addProperty( 1120 new TokenizerProperty(Token.PATTERN, new String [] { pattern }, companion, flags, flagMask) 1121 ); 1122 } 1123 1124 1131 public void removePattern(String pattern) throws IllegalArgumentException { 1132 TokenizerProperty prop = getPattern(pattern); 1133 1134 if (prop != null) { 1135 removeProperty(prop); 1136 } 1137 } 1138 1139 1148 public Object getPatternCompanion(String pattern) throws IllegalArgumentException { 1149 TokenizerProperty prop = getPattern(pattern); 1150 1151 if (prop != null) { 1152 return prop.getCompanion(); 1153 } else { 1154 return null; 1155 } 1156 } 1157 1158 1166 public boolean patternExists(String pattern) { 1167 try { 1168 return getPattern(pattern) != null; 1169 } catch (IllegalArgumentException ex) { 1170 return false; 1171 } 1172 } 1173 1174 1175 1186 public TokenizerProperty getPattern(String pattern) throws IllegalArgumentException { 1187 checkArgument(pattern, "Pattern"); 1189 1190 synchronized(this) { 1192 return doGetProperty(Token.PATTERN, pattern); 1193 } 1194 } 1195 1196 1197 1201 1209 public void addProperty(TokenizerProperty property) throws IllegalArgumentException { 1210 checkPropertyArgument(property); 1212 1213 String [] images = property.getImages(); 1215 1216 switch (property.getType()) { 1217 case Token.STRING: 1218 case Token.BLOCK_COMMENT: 1219 checkArgument((images.length < 2) ? null : images[1], "End sequence"); 1220 break; 1221 } 1222 1223 synchronized(this) { 1225 TokenizerProperty oldProp = doAddProperty(property); 1226 1227 if (oldProp == null) { 1228 notifyListeners(new TokenizerPropertyEvent(TokenizerPropertyEvent.PROPERTY_ADDED, property)); 1229 } else if ( ! oldProp.equals(property)) { 1230 notifyListeners(new TokenizerPropertyEvent(TokenizerPropertyEvent.PROPERTY_MODIFIED, property, oldProp)); 1231 } 1232 } 1233 } 1234 1235 1243 public void removeProperty(TokenizerProperty property) throws IllegalArgumentException { 1244 checkPropertyArgument(property); 1246 1247 synchronized(this) { 1249 TokenizerProperty removed = doRemoveProperty(property); 1250 1251 if (removed != null) { 1252 notifyListeners(new TokenizerPropertyEvent(TokenizerPropertyEvent.PROPERTY_REMOVED, removed)); 1253 } 1254 } 1255 } 1256 1257 1258 1266 public boolean propertyExists(TokenizerProperty property) { 1267 try { 1268 checkPropertyArgument(property); 1269 synchronized(this) { 1270 return doGetProperty(property.getType(), property.getImages()[0]) != null; 1271 } 1272 } catch (IllegalArgumentException ex) { 1273 return false; 1274 } 1275 } 1276 1277 1278 1282 1289 public void addTokenizerPropertyListener(TokenizerPropertyListener listener) { 1290 if (listener != null) { 1291 synchronized(_listeners) { 1292 WeakReference ref = new WeakReference (listener); 1293 _listeners.add(ref); 1294 } 1295 } 1296 } 1297 1298 1299 1307 public void removeTokenizerPropertyListener(TokenizerPropertyListener listener) { 1308 if (listener != null) { 1309 synchronized(_listeners) { 1310 Iterator iter = _listeners.iterator(); 1311 1312 while (iter.hasNext()) { 1313 WeakReference ref = (WeakReference )iter.next(); 1314 Object elem = ref.get(); 1315 1316 if (elem == null) { 1317 iter.remove(); 1319 } else if (listener.equals(elem)) { 1320 iter.remove(); 1322 break; 1323 } 1324 } 1325 } 1326 } 1327 } 1328 1329 1330 1334 1343 private void mapCharacterSet(Map map, String set, boolean removeIt) throws IllegalArgumentException { 1344 for (int index = 0; index < set.length(); ++index) { 1345 char cc = set.charAt(index); 1346 1347 switch (cc) { 1348 case '-': 1349 try { 1350 char start = set.charAt(index - 1); 1351 char end = set.charAt(index + 1); 1352 if (end == '\\') { 1353 end = set.charAt(index + 2); 1354 index += 2; 1355 } else { 1356 index++; 1357 } 1358 for (char rangeCC = start; rangeCC <= end; ++rangeCC) { 1359 if (removeIt) { 1360 map.remove(new Character (rangeCC)); 1361 } else { 1362 map.put(new Character (rangeCC), null); 1363 } 1364 } 1365 } catch (Exception ex) { 1366 throw new IllegalArgumentException (set); 1367 } 1368 break; 1369 1370 case '\\': 1371 index++; 1372 cc = set.charAt(index); 1373 1374 default: 1375 if (index + 1 >= set.length() || set.charAt(index + 1) != '-') { 1376 if (removeIt) { 1377 map.remove(new Character (cc)); 1378 } else { 1379 map.put(new Character (cc), null); 1380 } 1381 } 1382 } 1383 } 1384 } 1385 1386 1393 private boolean escapeChar(char cc) { 1394 switch (cc) { 1395 case '\\': 1396 case '-': 1397 return true; 1398 default: 1399 return false; 1400 } 1401 } 1402 1403 1411 private void addRange(StringBuffer buffer, char rangeStart, char rangeEnd) { 1412 if (escapeChar(rangeStart)) { 1413 buffer.append('\\'); 1414 } 1415 buffer.append((char)rangeStart); 1416 if (rangeStart < rangeEnd - 1) { 1417 buffer.append('-'); 1418 } 1419 if (rangeStart != rangeEnd) { 1420 if (escapeChar(rangeEnd)) { 1421 buffer.append('\\'); 1422 } 1423 buffer.append((char)rangeEnd); 1424 } 1425 } 1426 1427 1428 1439 private String mergeSet(String set1, String set2, boolean removeSet2) throws IllegalArgumentException { 1440 TreeMap map = new TreeMap (); 1442 1443 mapCharacterSet(map, set1, false); 1444 mapCharacterSet(map, set2, removeSet2); 1445 1446 StringBuffer buffer = new StringBuffer (set1.length() + set2.length()); 1448 1449 if (map.size() > 0) { 1450 Iterator iter = map.keySet().iterator(); 1451 char rangeStart = ((Character )map.firstKey()).charValue(); 1452 char rangeEnd = rangeStart; 1453 1454 while (iter.hasNext()) { 1455 char cc = ((Character )iter.next()).charValue(); 1456 1457 if (cc > rangeEnd + 1) { 1458 addRange(buffer, rangeStart, rangeEnd); 1459 rangeStart = rangeEnd = cc; 1460 } else { 1461 rangeEnd = cc; 1462 } 1463 } 1464 addRange(buffer, rangeStart, rangeEnd); 1465 } 1466 1467 return buffer.toString(); 1469 } 1470 1471 1481 private int normalizeFlags(int flags, int flagMask) { 1482 if ((flagMask & (Flags.F_CASE | Flags.F_NO_CASE)) == (Flags.F_CASE | Flags.F_NO_CASE)) { 1483 if ((flags & (Flags.F_CASE | Flags.F_NO_CASE)) == 0) { 1484 flags |= Flags.F_CASE; 1486 } else if ((flags & Flags.F_CASE) != 0) { 1487 flags &= ~Flags.F_NO_CASE; 1489 } 1490 } 1491 return flags; 1492 } 1493 1494 1503 protected void checkArgument(String arg, String name) throws IllegalArgumentException { 1504 if (arg == null) { 1505 throw new ExtIllegalArgumentException("{0} is null.", new Object [] { name } ); 1506 } else if (arg.length() <= 0) { 1507 throw new ExtIllegalArgumentException("{0} is empty.", new Object [] { name } ); 1508 } 1509 } 1510 1511 1519 protected void checkPropertyArgument(TokenizerProperty property) throws IllegalArgumentException { 1520 if (property == null) { 1522 throw new ExtIllegalArgumentException("Property is null.", null ); 1523 } else if (property.getImages() == null) { 1524 throw new ExtIllegalArgumentException("No image(s) given in property.", null ); 1525 } else if (property.getImages()[0] == null) { 1526 throw new ExtIllegalArgumentException("No (leading) image given in property.", null ); 1527 } 1528 } 1529 1530 1538 protected void handleEvent( 1539 int type, 1540 String newValue, 1541 String oldValue 1542 ) 1543 { 1544 if (newValue != null && newValue.length() > 0) { 1545 if (oldValue == null) { 1546 notifyListeners( 1547 new TokenizerPropertyEvent( 1548 TokenizerPropertyEvent.PROPERTY_ADDED, 1549 new TokenizerProperty(type, new String [] { newValue } ))); 1550 } else if ( ! oldValue.equals(newValue)) { 1551 notifyListeners( 1552 new TokenizerPropertyEvent( 1553 TokenizerPropertyEvent.PROPERTY_MODIFIED, 1554 new TokenizerProperty(type, new String [] { newValue } ), 1555 new TokenizerProperty(type, new String [] { oldValue } ))); 1556 } 1557 } else if (oldValue != null && oldValue.length() > 0) { 1558 notifyListeners( 1559 new TokenizerPropertyEvent( 1560 TokenizerPropertyEvent.PROPERTY_REMOVED, 1561 new TokenizerProperty(type, new String [] { oldValue } ))); 1562 } 1563 } 1564 1565 1571 protected void notifyListeners(TokenizerPropertyEvent event) { 1572 Iterator iter = _listeners.iterator(); 1573 1574 while (iter.hasNext()) { 1575 WeakReference ref = (WeakReference )iter.next(); 1576 TokenizerPropertyListener listener = (TokenizerPropertyListener)ref.get(); 1577 1578 if (listener == null) { 1579 iter.remove(); 1581 } else { 1582 listener.propertyChanged(event); 1584 } 1585 } 1586 } 1587 1588 1589 1593 1596 protected int _flags = 0; 1597 1598 1601 private LinkedList _listeners = new LinkedList (); 1602} 1603 | Popular Tags |