1 package org.unicode.cldr.util; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.io.PrintWriter; 9 import java.util.ArrayList; 10 import java.util.Arrays; 11 import java.util.Collection; 12 import java.util.Collections; 13 import java.util.HashSet; 14 import java.util.Iterator; 15 import java.util.LinkedHashSet; 16 import java.util.List; 17 import java.util.Map; 18 import java.util.Set; 19 import java.util.TreeMap; 20 import java.util.TreeSet; 21 22 import org.unicode.cldr.draft.FileUtilities; 23 import org.xml.sax.Attributes; 24 import org.xml.sax.ContentHandler; 25 import org.xml.sax.ErrorHandler; 26 import org.xml.sax.InputSource; 27 import org.xml.sax.Locator; 28 import org.xml.sax.SAXException; 29 import org.xml.sax.SAXParseException; 30 import org.xml.sax.XMLReader; 31 import org.xml.sax.ext.DeclHandler; 32 33 import com.ibm.icu.impl.Relation; 34 import com.ibm.icu.text.UTF16; 35 36 /** 37 * @deprecated 38 */ 39 @Deprecated 40 public class FindDTDOrder implements DeclHandler, ContentHandler, ErrorHandler { 41 static final boolean SHOW_PROGRESS = CldrUtility.getProperty("verbose", false); 42 static final boolean SHOW_ALL = CldrUtility.getProperty("show_all", false); 43 private static final boolean DEBUG = false; 44 45 private static FindDTDOrder INSTANCE; 46 47 private boolean recordingAttributeElements; 48 main(String[] args)49 public static void main(String[] args) throws IOException { 50 System.out.println("Outdated, no longer used"); 51 FindDTDOrder me = getInstance(); 52 me.showData(); 53 } 54 getInstance()55 public static FindDTDOrder getInstance() { 56 synchronized (FindDTDOrder.class) { 57 if (INSTANCE == null) { 58 try { 59 FindDTDOrder me = new FindDTDOrder(); 60 XMLReader xmlReader = CLDRFile.createXMLReader(true); 61 xmlReader.setContentHandler(me); 62 xmlReader.setErrorHandler(me); 63 xmlReader.setProperty( 64 "http://xml.org/sax/properties/declaration-handler", me); 65 66 FileInputStream fis; 67 InputSource is; 68 me.recordingAttributeElements = true; 69 String filename = CLDRPaths.MAIN_DIRECTORY + "/root.xml"; 70 File file = new File(filename); 71 if (DEBUG) { 72 System.out.println("Opening " + file.getCanonicalFile()); 73 } 74 File dtd = new File(PathUtilities.getNormalizedPathString(file) + "/../" + "../../common/dtd/ldml.dtd"); 75 if (DEBUG) { 76 System.out.println("Opening " + dtd.getCanonicalFile()); 77 } 78 79 fis = new FileInputStream(filename); 80 if (DEBUG) { 81 BufferedReader b = new BufferedReader(new InputStreamReader(fis)); 82 for (int i = 0; i < 30; ++i) { 83 String line = b.readLine(); 84 System.out.println(line); 85 } 86 throw new IllegalArgumentException("just testing"); 87 } 88 is = new InputSource(fis); 89 is.setSystemId(PathUtilities.getNormalizedPathString(file) + "/../"); 90 xmlReader.parse(is); 91 fis.close(); 92 93 me.recordingAttributeElements = false; 94 filename = CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY 95 + "/supplementalData.xml"; 96 File file2 = new File(filename); 97 if (DEBUG) { 98 System.out.println("Opening " + file2.getCanonicalFile()); 99 } 100 101 fis = new FileInputStream(filename); 102 is = new InputSource(fis); 103 is.setSystemId(PathUtilities.getNormalizedPathString(file) + "/../"); 104 xmlReader.parse(is); 105 fis.close(); 106 // Then Attributes 107 List<String> rawDtdAttributeOrder = Collections.unmodifiableList(new ArrayList<>(me.attributeSet)); 108 List<String> cldrFileAttributeOrder = CLDRFile.getAttributeOrder(); 109 110 LinkedHashSet<String> modifiedDtdOrder = new LinkedHashSet<>(cldrFileAttributeOrder); 111 // add items, keeping the ordering stable 112 modifiedDtdOrder.retainAll(rawDtdAttributeOrder); // remove any superfluous stuff 113 modifiedDtdOrder.addAll(rawDtdAttributeOrder); 114 115 // certain stuff always goes at the end 116 modifiedDtdOrder.removeAll(me.getCommonAttributes()); 117 modifiedDtdOrder.addAll(me.getCommonAttributes()); 118 119 // now make a list for comparison 120 List<String> dtdAttributeOrder = new ArrayList<>(modifiedDtdOrder); 121 122 // fix to and from 123 dtdAttributeOrder.remove("from"); 124 dtdAttributeOrder.add(dtdAttributeOrder.indexOf("to"), "from"); 125 126 me.attributeList = Collections.unmodifiableList(dtdAttributeOrder); 127 me.checkData(); 128 me.orderingList = Collections.unmodifiableList(me.orderingList); 129 130 // me.writeAttributeElements(); 131 INSTANCE = me; 132 } catch (Exception e) { 133 throw (IllegalArgumentException) new IllegalArgumentException().initCause(e); 134 } 135 } 136 } 137 return INSTANCE; 138 } 139 writeAttributeElements()140 public void writeAttributeElements() { 141 System.out.println(CldrUtility.LINE_SEPARATOR + "======== Start Attributes to Elements (unblocked) " 142 + CldrUtility.LINE_SEPARATOR); 143 for (String attribute : attributeToElements.keySet()) { 144 Set<String> filtered = new TreeSet<>(); 145 for (String element : attributeToElements.getAll(attribute)) { 146 if (!isBlocked(element)) { 147 filtered.add(element); 148 } 149 } 150 System.out.println(attribute + "\t" + CldrUtility.join(filtered, " ")); 151 } 152 System.out.println(CldrUtility.LINE_SEPARATOR + "======== End Attributes to Elements" 153 + CldrUtility.LINE_SEPARATOR); 154 System.out.println(CldrUtility.LINE_SEPARATOR + "======== Start Elements to Children (skipping alias, special)" 155 + CldrUtility.LINE_SEPARATOR); 156 showElementTree("ldml", "", new HashSet<String>()); 157 System.out.println(CldrUtility.LINE_SEPARATOR + "======== End Elements to Children" 158 + CldrUtility.LINE_SEPARATOR); 159 } 160 showElementTree(String element, String indent, HashSet<String> seenSoFar)161 private void showElementTree(String element, String indent, HashSet<String> seenSoFar) { 162 // skip blocking elements 163 if (isBlocked(element)) { 164 return; 165 } 166 Set<String> children = elementToChildren.getAll(element); 167 if (seenSoFar.contains(element)) { 168 System.out.println(indent + element 169 + (children == null || children.size() == 0 ? "" : "\t*dup*\t" + children)); 170 return; 171 } 172 System.out.println(indent + element); 173 seenSoFar.add(element); 174 if (children != null) { 175 indent += "\t"; 176 for (String child : children) { 177 showElementTree(child, indent, seenSoFar); 178 } 179 } 180 } 181 isBlocked(String element)182 private boolean isBlocked(String element) { 183 return isAncestorOf("supplementalData", element) 184 || isAncestorOf("collation", element) 185 || isAncestorOf("cldrTest", element) 186 || isAncestorOf("transform", element); 187 } 188 189 Relation<String, String> ancestorToDescendant = null; 190 isAncestorOf(String possibleAncestor, String possibleDescendent)191 private boolean isAncestorOf(String possibleAncestor, String possibleDescendent) { 192 if (ancestorToDescendant == null) { 193 ancestorToDescendant = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class); 194 buildPairwiseRelations(new ArrayList<String>(), "ldml"); 195 } 196 Set<String> possibleDescendents = ancestorToDescendant.getAll(possibleAncestor); 197 if (possibleDescendents == null) return false; 198 return possibleDescendents.contains(possibleDescendent); 199 } 200 buildPairwiseRelations(List<String> parents, String current)201 private void buildPairwiseRelations(List<String> parents, String current) { 202 Set<String> children = elementToChildren.getAll(current); 203 if (children == null || children.size() == 0) return; 204 205 // we make a new list, since otherwise the iteration fails in recursion (because of the modification) 206 // if this were performance-sensitive we'd do it differently 207 ArrayList<String> newParents = new ArrayList<>(parents); 208 newParents.add(current); 209 210 for (String child : children) { 211 for (String ancestor : newParents) { 212 ancestorToDescendant.put(ancestor, child); 213 buildPairwiseRelations(newParents, child); 214 } 215 } 216 } 217 218 PrintWriter log = null; 219 220 Set elementOrderings = new LinkedHashSet(); // set of orderings 221 222 Set<String> allDefinedElements = new LinkedHashSet<>(); 223 224 boolean showReason = false; 225 226 Object DONE = new Object(); // marker 227 228 Relation<String, String> elementToChildren = Relation.of(new TreeMap<String, Set<String>>(), 229 TreeSet.class); 230 FindDTDOrder()231 FindDTDOrder() { 232 log = new PrintWriter(System.out); 233 } 234 235 private List<String> orderingList = new ArrayList<>(); 236 checkData()237 public void checkData() { 238 // verify that the ordering is the consistent for all child elements 239 // do this by building an ordering from the lists. 240 // The first item has no greater item in any set. So find an item that is 241 // only first 242 MergeLists<String> mergeLists = new MergeLists<>(new TreeSet<>(new UTF16.StringComparator(true, 243 false, 0))) 244 .add(Arrays.asList("ldml")) 245 .addAll(elementOrderings); // 246 List<String> result = mergeLists.merge(); 247 Collection badOrder = MergeLists.hasConsistentOrderWithEachOf(result, elementOrderings); 248 if (badOrder != null) { 249 throw new IllegalArgumentException("Failed to find good order: " + badOrder); 250 } 251 252 showReason = false; 253 orderingList.add("ldml"); 254 if (SHOW_PROGRESS) { 255 log.println("SHOW_PROGRESS "); 256 for (Iterator it = elementOrderings.iterator(); it.hasNext();) { 257 Object value = it.next(); 258 log.println(value); 259 } 260 } 261 while (true) { 262 Object first = getFirst(); 263 if (first == DONE) 264 break; 265 if (first != null) { 266 // log.println("Adding:\t" + first); 267 if (orderingList.contains(first)) { 268 throw new IllegalArgumentException("Already present: " + first); 269 } 270 orderingList.add(first.toString()); 271 } else { 272 showReason = true; 273 getFirst(); 274 if (SHOW_PROGRESS) 275 log.println(); 276 if (SHOW_PROGRESS) 277 log.println("Failed ordering. So far:"); 278 for (Iterator<String> it = orderingList.iterator(); it.hasNext();) 279 if (SHOW_PROGRESS) 280 log.print("\t" + it.next()); 281 if (SHOW_PROGRESS) 282 log.println(); 283 if (SHOW_PROGRESS) 284 log.println("Items:"); 285 // for (Iterator it = element_childComparator.keySet().iterator(); 286 // it.hasNext();) showRow(it.next(), true); 287 if (SHOW_PROGRESS) 288 log.println(); 289 break; 290 } 291 } 292 293 if (DEBUG) { 294 System.out.println("New code in CLDRFile:\n" + result); 295 System.out.println("Old code in CLDRFile:\n" + orderingList); 296 } 297 // System.out.println("New code2: " + CldrUtility.breakLines(CldrUtility.join(result, " "), sep, 298 // FIRST_LETTER_CHANGE.matcher(""), 80)); 299 300 Set<String> missing = new TreeSet<>(allDefinedElements); 301 missing.removeAll(orderingList); 302 orderingList.addAll(missing); 303 304 attributeEquivalents = new XEquivalenceClass(null); 305 for (Iterator it = attribEquiv.keySet().iterator(); it.hasNext();) { 306 Object ename = it.next(); 307 Set s = attribEquiv.get(ename); 308 Iterator it2 = s.iterator(); 309 Object first = it2.next(); 310 while (it2.hasNext()) { 311 attributeEquivalents.add(first, it2.next(), ename); 312 } 313 } 314 315 } 316 317 String sep = CldrUtility.LINE_SEPARATOR + "\t\t\t"; 318 showData()319 private void showData() throws IOException { 320 321 // finish up 322 String oldAttributeOrder = breakLines(CLDRFile.getAttributeOrder()); 323 log.println("Successful Ordering..."); 324 log.println(); 325 log.println("Old Attribute Ordering: "); 326 log.println(oldAttributeOrder); 327 328 String newAttributeOrder = breakLines(attributeList); 329 330 if (newAttributeOrder.equals(oldAttributeOrder)) { 331 log.println("*** New Attribute Ordering: <same>"); 332 log.println("*** No changes required..."); 333 } else { 334 log.println("*** New Attribute Ordering: "); 335 log.println(newAttributeOrder); 336 log.println("*** Replace in CLDRFile elementOrdering & supplementalMetadata ***"); 337 } 338 339 log.println("Attribute Eq: "); 340 for (Iterator it = attributeEquivalents.getSamples().iterator(); it.hasNext();) { 341 log.println("\t" 342 + getJavaList(new TreeSet(attributeEquivalents.getEquivalences(it.next())))); 343 } 344 if (SHOW_PROGRESS) { 345 for (Iterator it = attributeEquivalents.getEquivalenceSets().iterator(); it.hasNext();) { 346 Object last = null; 347 Set s = (Set) it.next(); 348 for (Iterator it2 = s.iterator(); it2.hasNext();) { 349 Object temp = it2.next(); 350 if (last != null) 351 log.println(last + " ~ " + temp + "\t" + attributeEquivalents.getReasons(last, temp)); 352 last = temp; 353 } 354 log.println(); 355 } 356 } 357 358 String oldOrder = getJavaList(CLDRFile.getElementOrder()); 359 log.println("Old Element Ordering:\n" 360 + oldOrder); 361 362 String newOrder = '"' + breakLines(orderingList) + '"'; 363 if (newOrder.equals(oldOrder)) { 364 log.println("*** New Element Ordering: <same>"); 365 log.println("*** No changes required..."); 366 } else { 367 log.println("*** New Element Ordering:\n" + newOrder); 368 log.println("*** Replace in CLDRFile elementOrdering & supplementalMetadata ***"); 369 } 370 371 if (SHOW_ALL) { 372 log.println("Old Size: " + CLDRFile.getElementOrder().size()); 373 Set temp = new HashSet(CLDRFile.getElementOrder()); 374 temp.removeAll(orderingList); 375 log.println("Old - New: " + temp); 376 log.println("New Size: " + orderingList.size()); 377 temp = new HashSet(orderingList); 378 temp.removeAll(CLDRFile.getElementOrder()); 379 log.println("New - Old: " + temp); 380 381 Differ differ = new Differ(200, 1); 382 Iterator oldIt = CLDRFile.getElementOrder().iterator(); 383 Iterator newIt = orderingList.iterator(); 384 while (oldIt.hasNext() || newIt.hasNext()) { 385 if (oldIt.hasNext()) 386 differ.addA(oldIt.next()); 387 if (newIt.hasNext()) 388 differ.addB(newIt.next()); 389 differ.checkMatch(!oldIt.hasNext() && !newIt.hasNext()); 390 391 if (differ.getACount() != 0 || differ.getBCount() != 0) { 392 log.println("Same: " + differ.getA(-1)); 393 for (int i = 0; i < differ.getACount(); ++i) { 394 log.println("\tOld: " + differ.getA(i)); 395 } 396 for (int i = 0; i < differ.getBCount(); ++i) { 397 log.println("\t\tNew: " + differ.getB(i)); 398 } 399 log.println("Same: " + differ.getA(differ.getACount())); 400 } 401 } 402 log.println("Done with differences"); 403 } 404 405 log.flush(); 406 407 writeNewSupplemental(CLDRPaths.SUPPLEMENTAL_DIRECTORY, "supplementalMetadata.xml", 408 "<attributeOrder>", "</attributeOrder>", 409 "<elementOrder>", "</elementOrder>", "\t\t\t", CldrUtility.LINE_SEPARATOR + "\t\t"); 410 writeNewSupplemental(CLDRPaths.BASE_DIRECTORY + "/tools/java/org/unicode/cldr/util/", 411 "CLDRFile.java", 412 "// START MECHANICALLY attributeOrdering GENERATED BY FindDTDOrder", 413 "// END MECHANICALLY attributeOrdering GENERATED BY FindDTDOrder", 414 "// START MECHANICALLY elementOrdering GENERATED BY FindDTDOrder", 415 "// END MECHANICALLY elementOrdering GENERATED BY FindDTDOrder", 416 "\t\t\t\t\t\"", 417 '"' + CldrUtility.LINE_SEPARATOR + "\t\t\t\t\t"); 418 } 419 writeNewSupplemental(String dir, String filename, String startAttributeTag, String endAttributeTag, String startElementTag, String endElementTag, String startSep, String endSep)420 private void writeNewSupplemental(String dir, String filename, String startAttributeTag, String endAttributeTag, 421 String startElementTag, String endElementTag, String startSep, String endSep) throws IOException { 422 BufferedReader oldFile = FileUtilities.openUTF8Reader(dir, filename); 423 Log.setLogNoBOM(CLDRPaths.GEN_DIRECTORY + "/DTDOrder/" + filename); 424 425 // CldrUtility.copyUpTo(oldFile, PatternCache.get("\\s*" + 426 // startAttributeTag + 427 // "\\s*"), Log.getLog(), true); 428 // Log.println(startSep + breakLines(attributeSet) + endSep + endAttributeTag); 429 // CldrUtility.copyUpTo(oldFile, PatternCache.get("\\s*" + 430 // endAttributeTag + 431 // "\\s*"), null, true); 432 433 CldrUtility.copyUpTo(oldFile, PatternCache.get("\\s*" + 434 startElementTag + 435 "\\s*"), Log.getLog(), true); 436 Log.println(startSep + breakLines(orderingList) + endSep + endElementTag); 437 CldrUtility.copyUpTo(oldFile, PatternCache.get("\\s*" + 438 endElementTag + 439 "\\s*"), null, true); 440 441 CldrUtility.copyUpTo(oldFile, null, Log.getLog(), false); // copy to end 442 443 Log.close(); 444 oldFile.close(); 445 } 446 breakLines(Collection orderingList)447 private String breakLines(Collection orderingList) { 448 final String joined = CldrUtility.join(orderingList, " "); 449 return joined; // return Utility.breakLines(joined, sep, FIRST_LETTER_CHANGE.matcher(""), 80); 450 } 451 getJavaList(Collection orderingList)452 private String getJavaList(Collection orderingList) { 453 boolean first2 = true; 454 StringBuffer result = new StringBuffer(); 455 result.append('"'); 456 for (Iterator it = orderingList.iterator(); it.hasNext();) { 457 if (first2) 458 first2 = false; 459 else 460 result.append(" "); 461 result.append(it.next().toString()); 462 } 463 result.append('"'); 464 return result.toString(); 465 } 466 467 /** 468 * @param parent 469 * @param skipEmpty 470 * TODO 471 */ 472 // private void showRow(Object parent, boolean skipEmpty) { 473 // List items = (List) element_childComparator.get(parent); 474 // if (skipEmpty && items.size() == 0) return; 475 // if (SHOW_PROGRESS) log.print(parent); 476 // for (Iterator it2 = items.iterator(); it2.hasNext();) if (SHOW_PROGRESS) 477 // log.print("\t" + it2.next()); 478 // if (SHOW_PROGRESS) log.println(); 479 // } 480 /** 481 * @param orderingList 482 */ getFirst()483 private Object getFirst() { 484 Set firstItems = new TreeSet(); 485 Set nonFirstItems = new TreeSet(); 486 for (Iterator it = elementOrderings.iterator(); it.hasNext();) { 487 List list = (List) it.next(); 488 if (list.size() != 0) { 489 firstItems.add(list.get(0)); 490 for (int i = 1; i < list.size(); ++i) { 491 nonFirstItems.add(list.get(i)); 492 } 493 } 494 } 495 if (firstItems.size() == 0 && nonFirstItems.size() == 0) 496 return DONE; 497 firstItems.removeAll(nonFirstItems); 498 if (firstItems.size() == 0) 499 return null; // failure 500 Object result = firstItems.iterator().next(); 501 removeEverywhere(result); 502 return result; 503 } 504 505 /** 506 * @param possibleFirst 507 */ removeEverywhere(Object possibleFirst)508 private void removeEverywhere(Object possibleFirst) { 509 // and remove from all the lists 510 for (Iterator it2 = elementOrderings.iterator(); it2.hasNext();) { 511 List list2 = (List) it2.next(); 512 if (SHOW_PROGRESS && list2.contains(possibleFirst)) { 513 log.println("Removing " + possibleFirst + " from " + list2); 514 } 515 while (list2.remove(possibleFirst)) 516 ; // repeat until returns false 517 } 518 } 519 520 // private boolean isNeverNotFirst(Object possibleFirst) { 521 // if (showReason) if (SHOW_PROGRESS) log.println("Trying: " + possibleFirst); 522 // for (Iterator it2 = element_childComparator.keySet().iterator(); 523 // it2.hasNext();) { 524 // Object key = it2.next(); 525 // List list2 = (List) element_childComparator.get(key); 526 // int pos = list2.indexOf(possibleFirst); 527 // if (pos > 0) { 528 // if (showReason) { 529 // if (SHOW_PROGRESS) log.print("Failed at:\t"); 530 // showRow(key, false); 531 // } 532 // return false; 533 // } 534 // } 535 // return true; 536 // } 537 538 static final Set<String> ELEMENT_SKIP_LIST = new HashSet<>(Arrays.asList(new String[] { 539 "collation", "base", "settings", "suppress_contractions", "optimize", 540 "rules", "reset", "context", "p", "pc", "s", "sc", "t", "tc", 541 "i", "ic", "extend", "x" })); 542 543 static final Set<String> SUBELEMENT_SKIP_LIST = new HashSet<>(Arrays 544 .asList(new String[] { "PCDATA", "EMPTY", "ANY" })); 545 546 // refine later; right now, doesn't handle multiple elements well. 547 @Override elementDecl(String name, String model)548 public void elementDecl(String name, String model) throws SAXException { 549 // if (ELEMENT_SKIP_LIST.contains(name)) return; 550 if (name.indexOf("contractions") >= 0 551 || model 552 .indexOf("[alias, base, settings, suppress, contractions, optimize, rules, special]") >= 0) { 553 } 554 allDefinedElements.add(name); 555 if (SHOW_PROGRESS) { 556 log.println("Element\t" + name + "\t" + model); 557 } 558 String[] list = model.split("[^-_A-Z0-9a-z]+"); 559 List<String> mc = new ArrayList<>(); 560 /* 561 * if (name.equals("currency")) { mc.add("alias"); mc.add("symbol"); 562 * mc.add("pattern"); } 563 */ 564 for (int i = 0; i < list.length; ++i) { 565 if (list[i].length() == 0) 566 continue; 567 if (list[i].equals("ANY") && !name.equals("special")) { 568 System.err.println("WARNING- SHOULD NOT HAVE 'ANY': " + name + "\t" 569 + model); 570 } 571 if (SUBELEMENT_SKIP_LIST.contains(list[i])) 572 continue; 573 // if (SHOW_PROGRESS) log.print("\t" + list[i]); 574 if (mc.contains(list[i])) { 575 if (name.equals("currency") && list[i].equals("displayName") || list[i].equals("symbol") 576 || list[i].equals("pattern")) { 577 // do nothing, exception 578 } else if (name.equals("rules") && (list[i].equals("reset") || list[i].equals("import"))) { 579 // do nothing, exception 580 } else { 581 throw new IllegalArgumentException("Duplicate element in definition of " + name 582 + ":\t" + list[i] + ":\t" + Arrays.asList(list) + ":\t" + mc); 583 } 584 } else { 585 mc.add(list[i]); 586 } 587 } 588 if (recordingAttributeElements) { 589 Set<String> children = new TreeSet<>(mc); 590 children.remove("alias"); 591 children.remove("special"); 592 children.remove("cp"); 593 elementToChildren.putAll(name, children); 594 } 595 allDefinedElements.addAll(mc); 596 597 if (mc.size() < 1) { 598 if (SHOW_PROGRESS) { 599 log.println("\tSKIPPING\t" + name + "\t" + mc); 600 } 601 } else { 602 if (SHOW_PROGRESS) { 603 log.println("\t" + name + "\t" + mc); 604 } 605 elementOrderings.add(mc); 606 } 607 608 // if (SHOW_PROGRESS) log.println(); 609 } 610 611 Set<String> skipCommon = new LinkedHashSet<>(Arrays.asList(new String[] { "validSubLocales", 612 "standard", "references", 613 "alt", "draft", 614 })); 615 616 Set<String> attributeSet = new TreeSet<>(); 617 { 618 attributeSet.add("_q"); 619 attributeSet.addAll(skipCommon); 620 } 621 List<String> attributeList; 622 623 Map<String, Set<String>> attribEquiv = new TreeMap<>(); 624 625 Relation<String, String> attributeToElements = Relation.of(new TreeMap<String, Set<String>>(), 626 TreeSet.class); 627 private XEquivalenceClass attributeEquivalents; 628 629 @Override attributeDecl(String eName, String aName, String type, String mode, String value)630 public void attributeDecl(String eName, String aName, String type, 631 String mode, String value) throws SAXException { 632 if (SHOW_ALL) 633 log.println("attributeDecl"); 634 // if (SHOW_ALL) log.println("Attribute\t" + eName + "\t" + 635 // aName + "\t" + type + "\t" + mode + "\t" + value); 636 if (SHOW_PROGRESS) System.out.println("Attribute\t" + eName + "\t" + aName + "\t" + type 637 + "\t" + mode + "\t" + value); 638 if (!skipCommon.contains(aName)) { 639 attributeSet.add(aName); 640 Set<String> l = attribEquiv.get(eName); 641 if (l == null) 642 attribEquiv.put(eName, l = new TreeSet<>()); 643 l.add(aName); 644 } 645 if (recordingAttributeElements) { 646 attributeToElements.put(aName, eName); 647 } 648 } 649 650 @Override internalEntityDecl(String name, String value)651 public void internalEntityDecl(String name, String value) throws SAXException { 652 if (SHOW_ALL) 653 log.println("internalEntityDecl"); 654 // if (SHOW_ALL) log.println("Internal Entity\t" + name + 655 // "\t" + value); 656 } 657 658 @Override externalEntityDecl(String name, String publicId, String systemId)659 public void externalEntityDecl(String name, String publicId, String systemId) 660 throws SAXException { 661 if (SHOW_ALL) 662 log.println("externalEntityDecl"); 663 // if (SHOW_ALL) log.println("Internal Entity\t" + name + 664 // "\t" + publicId + "\t" + systemId); 665 } 666 667 /* 668 * (non-Javadoc) 669 * 670 * @see org.xml.sax.ContentHandler#endDocument() 671 */ 672 @Override endDocument()673 public void endDocument() throws SAXException { 674 if (SHOW_ALL) 675 log.println("endDocument"); 676 } 677 678 /* 679 * (non-Javadoc) 680 * 681 * @see org.xml.sax.ContentHandler#startDocument() 682 */ 683 @Override startDocument()684 public void startDocument() throws SAXException { 685 if (SHOW_ALL) 686 log.println("startDocument"); 687 } 688 689 /* 690 * (non-Javadoc) 691 * 692 * @see org.xml.sax.ContentHandler#characters(char[], int, int) 693 */ 694 @Override characters(char[] ch, int start, int length)695 public void characters(char[] ch, int start, int length) throws SAXException { 696 if (SHOW_ALL) 697 log.println("characters"); 698 } 699 700 /* 701 * (non-Javadoc) 702 * 703 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int) 704 */ 705 @Override ignorableWhitespace(char[] ch, int start, int length)706 public void ignorableWhitespace(char[] ch, int start, int length) 707 throws SAXException { 708 if (SHOW_ALL) 709 log.println("ignorableWhitespace"); 710 } 711 712 /* 713 * (non-Javadoc) 714 * 715 * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String) 716 */ 717 @Override endPrefixMapping(String prefix)718 public void endPrefixMapping(String prefix) throws SAXException { 719 if (SHOW_ALL) 720 log.println("endPrefixMapping"); 721 } 722 723 /* 724 * (non-Javadoc) 725 * 726 * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String) 727 */ 728 @Override skippedEntity(String name)729 public void skippedEntity(String name) throws SAXException { 730 if (SHOW_ALL) 731 log.println("skippedEntity"); 732 } 733 734 /* 735 * (non-Javadoc) 736 * 737 * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator) 738 */ 739 @Override setDocumentLocator(Locator locator)740 public void setDocumentLocator(Locator locator) { 741 if (SHOW_ALL) 742 log.println("setDocumentLocator"); 743 } 744 745 /* 746 * (non-Javadoc) 747 * 748 * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, 749 * java.lang.String) 750 */ 751 @Override processingInstruction(String target, String data)752 public void processingInstruction(String target, String data) 753 throws SAXException { 754 if (SHOW_ALL) 755 log.println("processingInstruction"); 756 } 757 758 /* 759 * (non-Javadoc) 760 * 761 * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, 762 * java.lang.String) 763 */ 764 @Override startPrefixMapping(String prefix, String uri)765 public void startPrefixMapping(String prefix, String uri) throws SAXException { 766 if (SHOW_ALL) 767 log.println("startPrefixMapping"); 768 } 769 770 /* 771 * (non-Javadoc) 772 * 773 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, 774 * java.lang.String, java.lang.String) 775 */ 776 @Override endElement(String namespaceURI, String localName, String qName)777 public void endElement(String namespaceURI, String localName, String qName) 778 throws SAXException { 779 if (SHOW_ALL) 780 log.println("endElement"); 781 } 782 783 /* 784 * (non-Javadoc) 785 * 786 * @see org.xml.sax.ContentHandler#startElement(java.lang.String, 787 * java.lang.String, java.lang.String, org.xml.sax.Attributes) 788 */ 789 @Override startElement(String namespaceURI, String localName, String qName, Attributes atts)790 public void startElement(String namespaceURI, String localName, String qName, 791 Attributes atts) throws SAXException { 792 if (SHOW_ALL) 793 log.println("startElement"); 794 } 795 796 /* 797 * (non-Javadoc) 798 * 799 * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) 800 */ 801 @Override error(SAXParseException exception)802 public void error(SAXParseException exception) throws SAXException { 803 if (SHOW_ALL) 804 log.println("error"); 805 throw exception; 806 } 807 808 /* 809 * (non-Javadoc) 810 * 811 * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) 812 */ 813 @Override fatalError(SAXParseException exception)814 public void fatalError(SAXParseException exception) throws SAXException { 815 if (SHOW_ALL) 816 log.println("fatalError"); 817 throw exception; 818 } 819 820 /* 821 * (non-Javadoc) 822 * 823 * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) 824 */ 825 @Override warning(SAXParseException exception)826 public void warning(SAXParseException exception) throws SAXException { 827 if (SHOW_ALL) 828 log.println("warning"); 829 throw exception; 830 } 831 getAttributeOrder()832 public List<String> getAttributeOrder() { 833 return attributeList; 834 } 835 getElementOrder()836 public List<String> getElementOrder() { 837 return orderingList; 838 } 839 getCommonAttributes()840 public Set<String> getCommonAttributes() { 841 return skipCommon; 842 } 843 844 } 845