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