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-2015, International Business Machines Corporation and * 6bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert* others. All Rights Reserved. * 7bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert******************************************************************************* 8bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert*/ 9bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 10bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/** 11bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Represent a file of APIInfo records. 12bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 13bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 14bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpackage com.ibm.icu.dev.tool.docs; 15bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 16bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.BufferedReader; 17bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.File; 18bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.FileInputStream; 19bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.IOException; 20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.InputStream; 21bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.InputStreamReader; 22bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.io.PrintWriter; 23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Collections; 24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Enumeration; 25bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Iterator; 26bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Set; 27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.TreeSet; 28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.zip.GZIPInputStream; 29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.zip.ZipEntry; 30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.zip.ZipFile; 31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpublic final class APIData { 33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int version; 34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String name; 35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String base; 36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert TreeSet<APIInfo> set; 37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static APIData read(BufferedReader br, boolean internal) { 39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert try { 40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert APIData data = new APIData(); 41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert data.version = Integer.parseInt(APIInfo.readToken(br)); // version 43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (data.version > APIInfo.VERSION) { 44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw new IllegalArgumentException( 45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "data version " + data.version 46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert + " is newer than current version (" + APIInfo.VERSION + ")"); 47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert data.name = APIInfo.readToken(br); 49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert data.base = APIInfo.readToken(br); // base 50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert br.readLine(); 51bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 52bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert data.set = new TreeSet(APIInfo.defaultComparator()); 53bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (APIInfo info = new APIInfo(); info.read(br); info = new APIInfo()) { 54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (internal || !info.isInternal()) { 55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert data.set.add(info); 56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // System.out.println("read " + data.set.size() + " record(s)"); 59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return data; 60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert catch (IOException e) { 62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert RuntimeException re = new RuntimeException("error reading api data"); 63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert re.initCause(e); 64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw re; 65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public static APIData read(File file, boolean internal) { 69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String fileName = file.getName(); 70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ZipFile zf = null; 71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert try { 72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert InputStream is; 73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (fileName.endsWith(".zip")) { 74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert zf = new ZipFile(file); 75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Enumeration entryEnum = zf.entries(); 76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (entryEnum.hasMoreElements()) { 77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ZipEntry entry = (ZipEntry)entryEnum.nextElement(); 78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert is = zf.getInputStream(entry); 79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // we only handle one!!! 80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw new IOException("zip file is empty"); 82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert is = new FileInputStream(file); 85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (fileName.endsWith(".gz")) { 86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert is = new GZIPInputStream(is); 87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert InputStreamReader isr = new InputStreamReader(is); 90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return read(new BufferedReader(isr), internal); 91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } catch (IOException e) { 92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert RuntimeException re = new RuntimeException("error getting info stream: " + fileName); 93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert re.initCause(e); 94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw re; 95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } finally { 96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (zf != null) { 97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert try { 98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert zf.close(); 99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } catch (IOException e) { 100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert RuntimeException re = new RuntimeException("failed to close the zip file: " + fileName); 101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert re.initCause(e); 102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw re; 103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static APIData read(String fileName, boolean internal) { 109bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return read(new File(fileName), internal); 110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 111bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 112bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final String[] stanames = { 113bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "draft", "stable", "deprecated", "obsolete", "internal" 114bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 115bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final String[] catnames = { 116bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "classes", "fields", "constructors", "methods" 117bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 118bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 119bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void printStats(PrintWriter pw) { 120bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // classes, methods, fields 121bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // draft, stable, other 122bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 123bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int[] stats = new int[catnames.length * stanames.length]; 124bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 125bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Iterator iter = set.iterator(); 126bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert while (iter.hasNext()) { 127bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert APIInfo info = (APIInfo)iter.next(); 128bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 129bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (info.isPublic() || info.isProtected()) { 130bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int sta = info.getVal(APIInfo.STA); 131bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int cat = info.getVal(APIInfo.CAT); 132bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert stats[cat * stanames.length + sta] += 1; 133bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 134bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 135bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 136bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int tt = 0; 137bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int cat = 0; cat < catnames.length; ++cat) { 138bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.println(catnames[cat]); 139bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int t = 0; 140bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int sta = 0; sta < stanames.length; ++sta) { 141bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int v = stats[cat * stanames.length + sta]; 142bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert t += v; 143bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.println(" " + stanames[sta] + ": " + v); 144bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 145bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert tt += t; 146bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.println("total: " + t); 147bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.println(); 148bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 149bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.println("total apis: " + tt); 150bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 151bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 152bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Set<APIInfo> getAPIInfoSet() { 153bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return Collections.unmodifiableSet(set); 154bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 155bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 156bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public static void main(String[] args) { 157bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert PrintWriter pw = new PrintWriter(System.out); 158bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 159bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean internal = false; 160bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String path = "src/com/ibm/icu/dev/tool/docs/"; 161bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 162bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String fn = "icu4j52.api3.gz"; 163bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (args.length == 0) { 164bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert args = new String[] { "-file", fn }; 165bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 166bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 167bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < args.length; ++i) { 168bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String arg = args[i]; 169bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (arg.equals("-path:")) { 170bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert path = args[++i]; 171bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (arg.equals("-internal:")) { 172bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert internal = args[++i].toLowerCase().charAt(0) == 't'; 173bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else if (arg.equals("-file")) { 174bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fn = args[++i]; 175bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 176bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert File f = new File(path, fn); 177bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert read(f,internal).printStats(pw); 178bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pw.flush(); 179bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 180bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 181bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 182bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert} 183