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