12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
3bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/**
4bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert*******************************************************************************
5bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert* Copyright (C) 2004-2010, International Business Machines Corporation and         *
6bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert* others. All Rights Reserved.                                                *
7bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert*******************************************************************************
8bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert*/
9bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
10bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/**
11bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Generate a list of ICU's public APIs, sorted by qualified name and signature
12bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * public APIs are all non-internal, non-package apis in com.ibm.icu.[lang|math|text|util].
13bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * For each API, list
14bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - public, package, protected, or private (PB PK PT PR)
15bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - static or non-static (STK NST)
16bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - final or non-final (FN NF)
17bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - synchronized or non-synchronized (SYN NSY)
18bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - stable, draft, deprecated, obsolete (ST DR DP OB)
19bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - abstract or non-abstract (AB NA)
20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * - constructor, member, field (C M F)
21bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *
22bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Requires JDK 1.4.2 or later
23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *
24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Sample invocation:
25bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * c:/j2sdk1.4.2/bin/javadoc
26bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -classpath c:/jd2sk1.4.2/lib/tools.jar
27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -doclet com.ibm.icu.dev.tool.docs.CheckAPI
28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -docletpath c:/doug/cvsproj/icu4j/src
29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -sourcepath c:/eclipse2.1/workspace2/icu4j/src
30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -compare c:/doug/cvsproj/icu4j/src/com/ibm/icu/dev/tool/docs/api2_6_1.txt
31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   -output foo
32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *   com.ibm.icu.text
33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert *
34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * todo: separate generation of data files (which requires taglet) from
35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * comparison and report generation (which does not require it)
36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * todo: provide command-line control of filters of which subclasses/packages to process
37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * todo: record full inheritance heirarchy, not just immediate inheritance
38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * todo: allow for aliasing comparisons (force (pkg.)*class to be treated as though it
39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * were in a different pkg/class heirarchy (facilitates comparison of icu4j and java)
40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */
41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpackage com.ibm.icu.dev.tool.docs;
43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.BufferedReader;
45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.BufferedWriter;
46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.File;
47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.FileInputStream;
48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.FileNotFoundException;
49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.FileOutputStream;
50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.IOException;
51bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.InputStream;
52bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.InputStreamReader;
53bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.OutputStream;
54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.OutputStreamWriter;
55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.ArrayList;
56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Collection;
57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Comparator;
58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Iterator;
59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.TreeSet;
60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ClassDoc;
62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ConstructorDoc;
63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.Doc;
64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ExecutableMemberDoc;
65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.FieldDoc;
66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.MethodDoc;
67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.ProgramElementDoc;
68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.RootDoc;
69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.sun.javadoc.Tag;
70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpublic class CheckAPI {
72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    RootDoc root;
73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    String compare; // file
74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    String compareName;
75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    TreeSet compareSet;
76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    TreeSet results;
77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    boolean html;
78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    String srcName = "Current"; // default source name
79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    String output;
80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int DATA_FILE_VERSION = 1;
82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final char SEP = ';';
83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int STA = 0, STA_DRAFT = 0, STA_STABLE = 1, STA_DEPRECATED = 2, STA_OBSOLETE = 3;
85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int VIS = 1, VIS_PACKAGE = 0, VIS_PUBLIC= 1, VIS_PROTECTED = 2, VIS_PRIVATE = 3;
86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int STK = 2, STK_STATIC = 1;
87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int FIN = 3, FIN_FINAL = 1;
88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int SYN = 4, SYN_SYNCHRONIZED = 1;
89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int ABS = 5, ABS_ABSTRACT = 1;
90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int CAT = 6, CAT_CLASS = 0, CAT_FIELD = 1, CAT_CONSTRUCTOR = 2, CAT_METHOD = 3;
91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int PAK = 7;
92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int CLS = 8;
93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int NAM = 9;
94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int SIG = 10;
95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int EXC = 11;
96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int NUM_TYPES = 11;
97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    static abstract class APIInfo {
99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public abstract int getVal(int typ);
100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public abstract String get(int typ, boolean brief);
101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public abstract void write(BufferedWriter w, boolean brief, boolean html, boolean detail);
102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    final static class Info extends APIInfo {
105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private int    info;
106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private String pack; // package
107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private String cls; // enclosing class
108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private String name; // name
109bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private String sig;  // signature, class: inheritance, method: signature, field: type, const: signature
110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private String exc;  // throws
111bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
112bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public int getVal(int typ) {
113bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            validateType(typ);
114bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return (info >> (typ*2)) & 0x3;
115bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
116bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
117bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public String get(int typ, boolean brief) {
118bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            validateType(typ);
119bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            String[] vals = brief ? shortNames[typ] : names[typ];
120bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (vals == null) {
121bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                switch (typ) {
122bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case PAK: return pack;
123bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case CLS: return cls;
124bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case NAM: return name;
125bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case SIG: return sig;
126bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case EXC: return exc;
127bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
128bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
129bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int val = (info >> (typ*2)) & 0x3;
130bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return vals[val];
131bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
132bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
133bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private void setType(int typ, int val) {
134bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            validateType(typ);
135bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            info &= ~(0x3 << (typ*2));
136bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            info |= (val&0x3) << (typ * 2);
137bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
138bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
139bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private void setType(int typ, String val) {
140bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            validateType(typ);
141bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            String[] vals = shortNames[typ];
142bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (vals == null) {
143bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                switch (typ) {
144bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case PAK: pack = val; break;
145bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case CLS: cls = val; break;
146bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case NAM: name = val; break;
147bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case SIG: sig = val; break;
148bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                case EXC: exc = val; break;
149bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
150bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                return;
151bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
152bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
153bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            for (int i = 0; i < vals.length; ++i) {
154bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (val.equalsIgnoreCase(vals[i])) {
155bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    info &= ~(0x3 << (typ*2));
156bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    info |= i << (typ*2);
157bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    return;
158bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
159bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
160bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
161bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            throw new IllegalArgumentException("unrecognized value '" + val + "' for type '" + typeNames[typ] + "'");
162bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
163bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
164bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public void write(BufferedWriter w, boolean brief, boolean html, boolean detail) {
165bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
166bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (brief) {
167bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    for (int i = 0; i < NUM_TYPES; ++i) {
168bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        String s = get(i, true);
169bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (s != null) {
170bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(s);
171bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
172bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(SEP);
173bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
174bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                } else {
175bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    // remove all occurrences of icu packages from the param string
176bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    // fortunately, all the packages have 4 chars (lang, math, text, util).
177bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    String xsig = sig;
178bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (!detail) {
179bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        final String ICUPACK = "com.ibm.icu.";
180bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        StringBuffer buf = new StringBuffer();
181bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        for (int i = 0; i < sig.length();) {
182bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            int n = sig.indexOf(ICUPACK, i);
183bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (n == -1) {
184bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                buf.append(sig.substring(i));
185bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                break;
186bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
187bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            buf.append(sig.substring(i, n));
188bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            i = n + ICUPACK.length() + 5; // trailing 'xxxx.'
189bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
190bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        xsig = buf.toString();
191bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
192bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
193bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    // construct signature
194bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    for (int i = STA; i < CAT; ++i) { // include status
195bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        String s = get(i, false);
196bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (s != null && s.length() > 0) {
197bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (i == STA) {
198bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write('(');
199bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write(s);
200bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write(')');
201bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            } else {
202bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write(s);
203bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
204bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(' ');
205bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
206bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
207bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
208bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    int val = getVal(CAT);
209bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    switch (val) {
210bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    case CAT_CLASS:
211bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (sig.indexOf("extends") == -1) {
212bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("interface ");
213bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        } else {
214bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("class ");
215bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
216bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (cls.length() > 0) {
217bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(cls);
218bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write('.');
219bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
220bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(name);
221bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (detail) {
222bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(' ');
223bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(sig);
224bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
225bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        break;
226bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
227bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    case CAT_FIELD:
228bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(xsig);
229bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(' ');
230bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(name);
231bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        break;
232bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
233bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    case CAT_METHOD:
234bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    case CAT_CONSTRUCTOR:
235bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        int n = xsig.indexOf('(');
236bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (n > 0) {
237bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(xsig.substring(0, n));
238bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(' ');
239bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        } else {
240bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            n = 0;
241bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
242bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(name);
243bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write(xsig.substring(n));
244bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        break;
245bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
246bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
247bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                w.newLine();
248bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
249bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (IOException e) {
250bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                RuntimeException re = new RuntimeException("IO Error");
251bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                re.initCause(e);
252bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw re;
253bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
254bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
255bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
256bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public boolean read(BufferedReader r) {
257bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int i = 0;
258bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
259bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                for (; i < NUM_TYPES; ++i) {
260bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    setType(i, readToken(r));
261bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
262bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                r.readLine(); // swallow line end sequence
263bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
264bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (IOException e) {
265bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (i == 0) { // assume if first read returns error, we have reached end of input
266bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    return false;
267bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
268bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                RuntimeException re = new RuntimeException("IO Error");
269bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                re.initCause(e);
270bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw re;
271bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
272bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
273bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return true;
274bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
275bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
276bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public boolean read(ProgramElementDoc doc) {
277bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
278bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // Doc. name
279bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // Doc. isField, isMethod, isConstructor, isClass, isInterface
280bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ProgramElementDoc. containingClass, containingPackage
281bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ProgramElementDoc. isPublic, isProtected, isPrivate, isPackagePrivate
282bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ProgramElementDoc. isStatic, isFinal
283bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // MemberDoc.isSynthetic
284bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ExecutableMemberDoc isSynchronized, signature
285bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // Type.toString() // e.g. "String[][]"
286bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ClassDoc.isAbstract, superClass, interfaces, fields, methods, constructors, innerClasses
287bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // FieldDoc type
288bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // ConstructorDoc qualifiedName
289bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // MethodDoc isAbstract, returnType
290bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
291bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
292bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // status
293bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            setType(STA, tagStatus(doc));
294bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
295bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // visibility
296bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (doc.isPublic()) {
297bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(VIS, VIS_PUBLIC);
298bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc.isProtected()) {
299bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(VIS, VIS_PROTECTED);
300bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc.isPrivate()) {
301bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(VIS, VIS_PRIVATE);
302bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
303bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // default is package
304bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
305bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
306bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // static
307bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (doc.isStatic()) {
308bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(STK, STK_STATIC);
309bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
310bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // default is non-static
311bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
312bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
313bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // final
314bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (doc.isFinal()) {
315bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(FIN, FIN_FINAL);
316bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
317bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // default is non-final
318bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
319bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
320bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            // type
321bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (doc.isField()) {
322bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(CAT, CAT_FIELD);
323bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc.isMethod()) {
324bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(CAT, CAT_METHOD);
325bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc.isConstructor()) {
326bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(CAT, CAT_CONSTRUCTOR);
327bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc.isClass() || doc.isInterface()) {
328bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(CAT, CAT_CLASS);
329bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
330bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
331bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            setType(PAK, doc.containingPackage().name());
332bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            setType(CLS, (doc.isClass() || doc.isInterface() || (doc.containingClass() == null)) ? "" : doc.containingClass().name());
333bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            setType(NAM, doc.name());
334bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
335bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (doc instanceof FieldDoc) {
336bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                FieldDoc fdoc = (FieldDoc)doc;
337bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(SIG, fdoc.type().toString());
338bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (doc instanceof ClassDoc) {
339bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                ClassDoc cdoc = (ClassDoc)doc;
340bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
341bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (cdoc.isClass() && cdoc.isAbstract()) { // interfaces are abstract by default, don't mark them as abstract
342bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    setType(ABS, ABS_ABSTRACT);
343bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
344bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
345bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                StringBuffer buf = new StringBuffer();
346bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (cdoc.isClass()) {
347bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    buf.append("extends ");
348bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    buf.append(cdoc.superclass().qualifiedName());
349bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
350bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                ClassDoc[] imp = cdoc.interfaces();
351bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (imp != null && imp.length > 0) {
352bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (buf.length() > 0) {
353bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        buf.append(" ");
354bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
355bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    buf.append("implements");
356bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    for (int i = 0; i < imp.length; ++i) {
357bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (i != 0) {
358bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            buf.append(",");
359bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
360bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        buf.append(" ");
361bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        buf.append(imp[i].qualifiedName());
362bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
363bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
364bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                setType(SIG, buf.toString());
365bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
366bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                ExecutableMemberDoc emdoc = (ExecutableMemberDoc)doc;
367bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (emdoc.isSynchronized()) {
368bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    setType(SYN, SYN_SYNCHRONIZED);
369bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
370bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
371bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (doc instanceof MethodDoc) {
372bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    MethodDoc mdoc = (MethodDoc)doc;
373bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (mdoc.isAbstract()) {
374bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        setType(ABS, ABS_ABSTRACT);
375bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
376bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    setType(SIG, mdoc.returnType().toString() + emdoc.signature());
377bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                } else {
378bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    // constructor
379bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    setType(SIG, emdoc.signature());
380bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
381bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
382bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
383bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return true;
384bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
385bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
386bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public static Comparator defaultComparator() {
387bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            final Comparator c = new Comparator() {
388bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    public int compare(Object lhs, Object rhs) {
389bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info lhi = (Info)lhs;
390bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info rhi = (Info)rhs;
391bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        int result = lhi.pack.compareTo(rhi.pack);
392bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (result == 0) {
393bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            result = (lhi.getVal(CAT) == CAT_CLASS ? lhi.name : lhi.cls)
394bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                .compareTo(rhi.getVal(CAT) == CAT_CLASS ? rhi.name : rhi.cls);
395bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (result == 0) {
396bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                result = lhi.getVal(CAT)- rhi.getVal(CAT);
397bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                if (result == 0) {
398bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    result = lhi.name.compareTo(rhi.name);
399bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    if (result == 0) {
400bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                        result = lhi.sig.compareTo(rhi.sig);
401bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    }
402bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                }
403bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
404bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
405bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        return result;
406bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
407bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                };
408bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return c;
409bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
410bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
411bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public static Comparator changedComparator() {
412bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            final Comparator c = new Comparator() {
413bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    public int compare(Object lhs, Object rhs) {
414bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info lhi = (Info)lhs;
415bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info rhi = (Info)rhs;
416bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        int result = lhi.pack.compareTo(rhi.pack);
417bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (result == 0) {
418bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            result = (lhi.getVal(CAT) == CAT_CLASS ? lhi.name : lhi.cls)
419bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                .compareTo(rhi.getVal(CAT) == CAT_CLASS ? rhi.name : rhi.cls);
420bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (result == 0) {
421bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                result = lhi.getVal(CAT)- rhi.getVal(CAT);
422bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                if (result == 0) {
423bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    result = lhi.name.compareTo(rhi.name);
424bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    if (result == 0 && lhi.getVal(CAT) != CAT_CLASS) {
425bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                        result = lhi.sig.compareTo(rhi.sig);
426bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    }
427bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                }
428bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
429bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
430bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        return result;
431bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
432bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                };
433bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return c;
434bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
435bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
436bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public static Comparator classFirstComparator() {
437bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            final Comparator c = new Comparator() {
438bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    public int compare(Object lhs, Object rhs) {
439bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info lhi = (Info)lhs;
440bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        Info rhi = (Info)rhs;
441bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        int result = lhi.pack.compareTo(rhi.pack);
442bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (result == 0) {
443bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            boolean lcls = lhi.getVal(CAT) == CAT_CLASS;
444bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            boolean rcls = rhi.getVal(CAT) == CAT_CLASS;
445bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            result = lcls == rcls ? 0 : (lcls ? -1 : 1);
446bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (result == 0) {
447bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                result = (lcls ? lhi.name : lhi.cls).compareTo(rcls ? rhi.name : rhi.cls);
448bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                if (result == 0) {
449bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    result = lhi.getVal(CAT)- rhi.getVal(CAT);
450bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    if (result == 0) {
451bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                        result = lhi.name.compareTo(rhi.name);
452bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                        if (result == 0 && !lcls) {
453bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                            result = lhi.sig.compareTo(rhi.sig);
454bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                        }
455bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    }
456bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                }
457bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
458bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
459bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        return result;
460bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
461bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                };
462bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return c;
463bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
464bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
465bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private static final String[] typeNames = {
466bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            "status", "visibility", "static", "final", "synchronized",
467bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            "abstract", "category", "package", "class", "name", "signature"
468bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        };
469bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
470bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private static final String[][] names = {
471bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "draft     ", "stable    ", "deprecated", "obsolete  " },
472bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "package", "public", "protected", "private" },
473bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "", "static" },
474bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "", "final" },
475bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "", "synchronized" },
476bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "", "abstract" },
477bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "class", "field", "constructor", "method"  },
478bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
479bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
480bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
481bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
482bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null
483bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        };
484bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
485bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private static final String[][] shortNames = {
486bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "DR", "ST", "DP", "OB" },
487bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "PK", "PB", "PT", "PR" },
488bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "NS", "ST" },
489bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "NF", "FN" },
490bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "NS", "SY" },
491bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "NA", "AB" },
492bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            { "L", "F", "C", "M" },
493bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
494bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
495bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
496bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null,
497bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            null
498bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        };
499bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
500bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private static void validateType(int typ) {
501bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (typ < 0 || typ > NUM_TYPES) {
502bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw new IllegalArgumentException("bad type index: " + typ);
503bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
504bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
505bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
506bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public String toString() {
507bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return get(NAM, true);
508bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
509bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
510bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
511bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    static final class DeltaInfo extends APIInfo {
512bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private Info a;
513bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        private Info b;
514bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
515bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        DeltaInfo(Info a, Info b) {
516bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            this.a = a;
517bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            this.b = b;
518bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
519bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
520bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public int getVal(int typ) {
521bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return a.getVal(typ);
522bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
523bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
524bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public String get(int typ, boolean brief) {
525bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return a.get(typ, brief);
526bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
527bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
528bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public void write(BufferedWriter w, boolean brief, boolean html, boolean detail) {
529bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            a.write(w, brief, html, detail);
530bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
531bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (html) {
532bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    w.write("<br>");
533bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
534bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                w.newLine();
535bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
536bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (Exception e) {
537bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
538bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            b.write(w, brief, html, detail);
539bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
540bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
541bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        public String toString() {
542bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return a.get(NAM, true);
543bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
544bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
545bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
546bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    public static int optionLength(String option) {
547bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (option.equals("-html")) {
548bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return 1;
549bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        } else if (option.equals("-name")) {
550bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return 2;
551bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        } else if (option.equals("-output")) {
552bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return 2;
553bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        } else if (option.equals("-compare")) {
554bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            return 2;
555bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
556bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return 0;
557bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
558bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
559bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    public static boolean start(RootDoc root) {
560bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return new CheckAPI(root).run();
561bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
562bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
563bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    CheckAPI(RootDoc root) {
564bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        this.root = root;
565bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
566bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        //      this.compare = "c:/doug/cvsproj/icu4j/src/com/ibm/icu/dev/tool/docs/api2_8.txt";
567bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
568bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        String[][] options = root.options();
569bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int i = 0; i < options.length; ++i) {
570bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            String opt = options[i][0];
571bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (opt.equals("-html")) {
572bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.html = true;
573bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (opt.equals("-name")) {
574bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.srcName = options[i][1];
575bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (opt.equals("-output")) {
576bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.output = options[i][1];
577bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (opt.equals("-compare")) {
578bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.compare = options[i][1];
579bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
580bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
581bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
582bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (compare != null) {
583bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
584bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // URL url = new URL(compare);
585bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                File f = new File(compare);
586bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                InputStream is = new FileInputStream(f);
587bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                InputStreamReader isr = new InputStreamReader(is);
588bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                BufferedReader br = new BufferedReader(isr);
589bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
590bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // read header line
591bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                /*int version = */Integer.parseInt(readToken(br));
592bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // check version if we change it later, probably can just rebuild though
593bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.compareName = readToken(br);
594bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                br.readLine();
595bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
596bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // read data
597bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                this.compareSet = new TreeSet(Info.defaultComparator());
598bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                for (Info info = new Info(); info.read(br); info = new Info()) {
599bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    compareSet.add(info);
600bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
601bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
602bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (Exception e) {
603bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                RuntimeException re = new RuntimeException("error reading " + compare);
604bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                re.initCause(e);
605bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw re;
606bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
607bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
608bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
609bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        results = new TreeSet(Info.defaultComparator());
610bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
611bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
612bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private boolean run() {
613bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        doDocs(root.classes());
614bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
615bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        OutputStream os = System.out;
616bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (output != null) {
617bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
618bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                os = new FileOutputStream(output);
619bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
620bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (FileNotFoundException e) {
621bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                RuntimeException re = new RuntimeException(e.getMessage());
622bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                re.initCause(e);
623bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw re;
624bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
625bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
626bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
627bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        BufferedWriter bw = null;
628bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        try {
629bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
630bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            bw = new BufferedWriter(osw);
631bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
632bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (compareSet == null) {
633bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // writing data file
634bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                bw.write(String.valueOf(DATA_FILE_VERSION) + SEP); // header version
635bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                bw.write(srcName + SEP); // source name
636bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                bw.newLine();
637bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                writeResults(results, bw, true, false, false);
638bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
639bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                // writing comparison info
640bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                TreeSet removed = (TreeSet)compareSet.clone();
641bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                removed.removeAll(results);
642bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
643bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                TreeSet added = (TreeSet)results.clone();
644bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                added.removeAll(compareSet);
645bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
646bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                Iterator ai = added.iterator();
647bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                Iterator ri = removed.iterator();
648bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                ArrayList changed = new ArrayList();
649bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                Comparator c = Info.changedComparator();
650bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                Info a = null, r = null;
651bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                while (ai.hasNext() && ri.hasNext()) {
652bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (a == null) a = (Info)ai.next();
653bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (r == null) r = (Info)ri.next();
654bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    int result = c.compare(a, r);
655bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (result < 0) {
656bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        a = null;
657bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else if (result > 0) {
658bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        r = null;
659bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
660bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        changed.add(new DeltaInfo(a, r));
661bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        a = null; ai.remove();
662bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        r = null; ri.remove();
663bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
664bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
665bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
666bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                added = stripAndResort(added);
667bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                removed = stripAndResort(removed);
668bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
669bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (html) {
670bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    String title = "ICU4J API Comparison: " + srcName + " with " + compareName;
671bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
672bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
673bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
674bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<html>");
675bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
676bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<head>");
677bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
678bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
679bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
680bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<title>");
681bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write(title);
682bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</title>");
683bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
684bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<body>");
685bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
686bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
687bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<h1>");
688bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write(title);
689bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</h1>");
690bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
691bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
692bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<hr/>");
693bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
694bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<h2>");
695bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("Removed from " + compareName);
696bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</h2>");
697bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
698bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
699bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (removed.size() > 0) {
700bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(removed, bw, false, true, false);
701bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
702bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("<p>(no API removed)</p>");
703bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
704bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
705bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
706bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<hr/>");
707bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
708bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<h2>");
709bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("Changed in " + srcName);
710bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</h2>");
711bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
712bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
713bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (changed.size() > 0) {
714bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(changed, bw, false, true, true);
715bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
716bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("<p>(no API changed)</p>");
717bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
718bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
719bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
720bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<hr/>");
721bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
722bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<h2>");
723bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("Added in " + srcName);
724bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</h2>");
725bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
726bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
727bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (added.size() > 0) {
728bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(added, bw, false, true, false);
729bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
730bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("<p>(no API added)</p>");
731bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
732bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<hr/>");
733bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
734bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("<p><i>Contents generated by CheckAPI tool.<br/>Copyright (C) 2004, International Business Machines Corporation, All Rights Reserved.</i></p>");
735bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
736bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</body>");
737bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
738bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("</html>");
739bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
740bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                } else {
741bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("Comparing " + srcName + " with " + compareName);
742bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
743bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
744bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
745bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
746bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("=== Removed from " + compareName + " ===");
747bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
748bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (removed.size() > 0) {
749bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(removed, bw, false, false, false);
750bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
751bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("(no API removed)");
752bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
753bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
754bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
755bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
756bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("=== Changed in " + srcName + " ===");
757bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
758bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (changed.size() > 0) {
759bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(changed, bw, false, false, true);
760bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
761bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("(no API changed)");
762bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
763bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
764bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
765bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
766bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.write("=== Added in " + srcName + " ===");
767bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
768bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (added.size() > 0) {
769bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        writeResults(added, bw, false, false, false);
770bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
771bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        bw.write("(no API added)");
772bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
773bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    bw.newLine();
774bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
775bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
776bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
777bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            bw.close();
778bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        } catch (IOException e) {
779bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try { bw.close(); } catch (IOException e2) {}
780bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            RuntimeException re = new RuntimeException("write error: " + e.getMessage());
781bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            re.initCause(e);
782bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            throw re;
783bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
784bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
785bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return false;
786bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
787bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
788bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private void doDocs(ProgramElementDoc[] docs) {
789bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (docs != null && docs.length > 0) {
790bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            for (int i = 0; i < docs.length; ++i) {
791bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                doDoc(docs[i]);
792bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
793bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
794bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
795bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
796bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private void doDoc(ProgramElementDoc doc) {
797bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (ignore(doc)) return;
798bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
799bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (doc.isClass() || doc.isInterface()) {
800bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            ClassDoc cdoc = (ClassDoc)doc;
801bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            doDocs(cdoc.fields());
802bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            doDocs(cdoc.constructors());
803bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            doDocs(cdoc.methods());
804bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            doDocs(cdoc.innerClasses());
805bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
806bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
807bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Info info = new Info();
808bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (info.read(doc)) {
809bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            results.add(info);
810bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
811bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
812bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
813bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private boolean ignore(ProgramElementDoc doc) {
814bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (doc == null) return true;
815bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (doc.isPrivate() || doc.isPackagePrivate()) return true;
816bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (doc instanceof ConstructorDoc && ((ConstructorDoc)doc).isSynthetic()) return true;
817bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (doc.qualifiedName().indexOf(".misc") != -1) return true;
818bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Tag[] tags = doc.tags();
819bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int i = 0; i < tags.length; ++i) {
820bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (tagKindIndex(tags[i].kind()) == INTERNAL) return true;
821bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
822bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
823bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return false;
824bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
825bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
826bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static void writeResults(Collection c, BufferedWriter w, boolean brief, boolean html, boolean detail) {
827bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Iterator iter = c.iterator();
828bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        String pack = null;
829bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        String clas = null;
830bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        while (iter.hasNext()) {
831bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            APIInfo info = (APIInfo)iter.next();
832bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (brief) {
833bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                info.write(w, brief, false, detail);
834bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else {
835bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                try {
836bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    String p = info.get(PAK, true);
837bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (!p.equals(pack)) {
838bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.newLine();
839bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (html) {
840bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (clas != null) {
841bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write("</ul>");
842bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.newLine();
843bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
844bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (pack != null) {
845bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write("</ul>");
846bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.newLine();
847bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
848bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
849bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("<h3>Package ");
850bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(p);
851bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("</h3>");
852bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.newLine();
853bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("<ul>");
854bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.newLine();
855bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        } else {
856bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write("Package ");
857bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(p);
858bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            w.write(':');
859bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
860bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.newLine();
861bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.newLine();
862bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
863bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        pack = p;
864bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        clas = null;
865bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
866bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
867bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (info.getVal(CAT) != CAT_CLASS) {
868bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        String name = info.get(CLS, true);
869bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        if (!name.equals(clas)) {
870bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            if (html) {
871bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                if (clas != null) {
872bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                    w.write("</ul>");
873bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                }
874bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write("<li>");
875bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write(name);
876bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.newLine();
877bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write("<ul>");
878bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            } else {
879bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.write(name);
880bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                                w.newLine();
881bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            }
882bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                            clas = name;
883bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        }
884bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write("    ");
885bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
886bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    if (html) {
887bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write("<li>");
888bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        info.write(w, brief, html, detail);
889bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        w.write("</li>");
890bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    } else {
891bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                        info.write(w, brief, html, detail);
892bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    }
893bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
894bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                catch (IOException e) {
895bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    System.err.println("IOException " + e.getMessage() + " writing " + info);
896bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
897bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
898bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
899bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (html) {
900bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            try {
901bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (clas != null) {
902bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    w.write("</ul>");
903bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    w.newLine();
904bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
905bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (pack != null) {
906bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    w.write("</ul>");
907bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    w.newLine();
908bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
909bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
910bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            catch (IOException e) {
911bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
912bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
913bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
914bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
915bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static String readToken(BufferedReader r) throws IOException {
916bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        char[] buf = new char[256];
917bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        int i = 0;
918bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (; i < buf.length; ++i) {
919bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int c = r.read();
920bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (c == -1) {
921bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw new IOException("unexpected EOF");
922bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            } else if (c == SEP) {
923bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
924bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
925bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            buf[i] = (char)c;
926bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
927bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        if (i == buf.length) {
928bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            throw new IOException("unterminated token" + new String(buf));
929bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
930bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
931bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return new String(buf, 0, i);
932bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
933bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
934bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static TreeSet stripAndResort(TreeSet t) {
935bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        stripClassInfo(t);
936bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        TreeSet r = new TreeSet(Info.classFirstComparator());
937bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        r.addAll(t);
938bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return r;
939bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
940bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
941bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static void stripClassInfo(Collection c) {
942bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        // c is sorted with class info first
943bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Iterator iter = c.iterator();
944bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        String cname = null;
945bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        while (iter.hasNext()) {
946bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            Info info = (Info)iter.next();
947bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            String cls = info.get(CLS, true);
948bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (cname != null) {
949bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (cname.equals(cls)) {
950bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    iter.remove();
951bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    continue;
952bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
953bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                cname = null;
954bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
955bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (info.getVal(CAT) == CAT_CLASS) {
956bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                cname = info.get(NAM, true);
957bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
958bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
959bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
960bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
961bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static int tagStatus(final Doc doc) {
962bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        class Result {
963bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int res = -1;
964bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            void set(int val) { if (res != -1) throw new RuntimeException("bad doc: " + doc); res = val; }
965bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int get() {
966bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                if (res == -1) {
967bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    System.err.println("warning: no tag for " + doc);
968bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                    return 0;
969bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                }
970bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                return res;
971bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
972bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
973bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
974bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Tag[] tags = doc.tags();
975bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        Result result = new Result();
976bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int i = 0; i < tags.length; ++i) {
977bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            Tag tag = tags[i];
978bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
979bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            String kind = tag.kind();
980bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            int ix = tagKindIndex(kind);
981bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
982bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            switch (ix) {
983bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case INTERNAL:
984bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                result.set(-2);
985bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
986bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
987bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case DRAFT:
988bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                result.set(STA_DRAFT);
989bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
990bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
991bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case STABLE:
992bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                result.set(STA_STABLE);
993bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
994bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
995bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case DEPRECATED:
996bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                result.set(STA_DEPRECATED);
997bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
998bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
999bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case OBSOLETE:
1000bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                result.set(STA_OBSOLETE);
1001bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
1002bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1003bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case SINCE:
1004bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case EXCEPTION:
1005bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case VERSION:
1006bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case UNKNOWN:
1007bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case AUTHOR:
1008bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case SEE:
1009bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case PARAM:
1010bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case RETURN:
1011bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case THROWS:
1012bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            case SERIAL:
1013bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                break;
1014bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1015bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            default:
1016bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                throw new RuntimeException("unknown index " + ix + " for tag: " + kind);
1017bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
1018bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
1019bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1020bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return result.get();
1021bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
1022bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1023bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int UNKNOWN = -1;
1024bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int INTERNAL = 0;
1025bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int DRAFT = 1;
1026bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int STABLE = 2;
1027bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int SINCE = 3;
1028bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int DEPRECATED = 4;
1029bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int AUTHOR = 5;
1030bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int SEE = 6;
1031bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int VERSION = 7;
1032bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int PARAM = 8;
1033bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int RETURN = 9;
1034bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int THROWS = 10;
1035bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int OBSOLETE = 11;
1036bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int EXCEPTION = 12;
1037bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static final int SERIAL = 13;
1038bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1039bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    private static int tagKindIndex(String kind) {
1040bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        final String[] tagKinds = {
1041bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            "@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see", "@version",
1042bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            "@param", "@return", "@throws", "@obsolete", "@exception", "@serial"
1043bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        };
1044bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert
1045bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        for (int i = 0; i < tagKinds.length; ++i) {
1046bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            if (kind.equals(tagKinds[i])) {
1047bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert                return i;
1048bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert            }
1049bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        }
1050bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert        return UNKNOWN;
1051bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert    }
1052bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert}
1053