1 /* 2 ******************************************************************************* 3 * Copyright (C) 2010-2013, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.tool.docs; 8 9 import java.io.BufferedWriter; 10 import java.io.FileOutputStream; 11 import java.io.IOException; 12 import java.io.OutputStreamWriter; 13 import java.io.PrintWriter; 14 import java.util.BitSet; 15 import java.util.Date; 16 import java.util.TreeSet; 17 18 19 /** 20 * @author yumaoka 21 * 22 */ 23 public class CollectAPI { 24 private static final int MAXSTATE = APIInfo.STA_INTERNAL; 25 26 private APIData _apidata; 27 28 CollectAPI(String file)29 CollectAPI(String file) { 30 _apidata = APIData.read(file, true); 31 } 32 writeHTML(String outfile, BitSet filter)33 void writeHTML(String outfile, BitSet filter) throws IOException { 34 35 // collecting versions 36 TreeSet<String> versions = new TreeSet<String>(); 37 for (APIInfo info : _apidata.set) { 38 versions.add(info.getStatusVersion()); 39 } 40 41 FileOutputStream fos = new FileOutputStream(outfile); 42 PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"))); 43 44 String title = "ICU4J API Collection: " + _apidata.name; 45 String note = "Contents generated by CollectAPI tool on " + new Date().toString(); 46 47 pw.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); 48 pw.println("<html>"); 49 pw.println("<head>"); 50 pw.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); 51 pw.println("<title>" + title + "</title>"); 52 pw.println("</head>"); 53 pw.println("<body>"); 54 55 pw.println("<h1>" + title + "</h1>"); 56 57 for (String ver : versions) { 58 boolean sawEntryForVersion = false; 59 60 for (int state = 0; state <= MAXSTATE; state++) { 61 if (!filter.get(state)) { 62 continue; 63 } 64 65 boolean firstInState = true; 66 String pack = ""; 67 String clas = "***"; // hack - we just need a class name never used 68 boolean inList = false; 69 70 for (APIInfo info : _apidata.set) { 71 if (!info.getStatusVersion().equals(ver)) { 72 continue; 73 } 74 if (state != info.getVal(APIInfo.STA)) { 75 continue; 76 } 77 78 if (!sawEntryForVersion) { 79 pw.println("<h2>Status Version: " + ver + "</h2>"); 80 sawEntryForVersion = true; 81 } 82 83 if (firstInState) { 84 pw.println("<h3>[" + getStatusTypeName(state) + "]</h3>"); 85 firstInState = false; 86 } 87 88 String packageName = info.getPackageName(); 89 if (!packageName.equals(pack)) { 90 if (inList) { 91 pw.println("</ul>"); 92 inList = false; 93 } 94 pw.println("<h4>Package: " + packageName + "</h4>"); 95 pack = packageName; 96 } 97 98 String className = info.getClassName(); 99 if (className.length() == 0) { 100 // next class 101 if (inList) { 102 pw.println("</ul>"); 103 inList = false; 104 } 105 pw.print("<p><span style='color:red'>Class: </span>"); 106 info.print(pw, false, true, false); 107 pw.println("</p>"); 108 clas = className; 109 continue; 110 } 111 if (!className.equals(clas)) { 112 if (inList) { 113 pw.println("</ul>"); 114 inList = false; 115 } 116 pw.println("<span style='color:green'>APIs: </span>" + className); 117 clas = className; 118 } 119 120 if (!inList) { 121 pw.println("<ul>"); 122 inList = true; 123 } 124 pw.print("<li>"); 125 info.print(pw, false, true, false); 126 pw.println("</li>"); 127 } 128 129 if (inList) { 130 pw.println("</ul>"); 131 } 132 } 133 134 if (sawEntryForVersion) { 135 pw.println(); 136 pw.println("<hr/>"); 137 } 138 } 139 140 pw.println("<p><i><font size=\"-1\">" + note + "</font></i></p>"); 141 142 pw.println("</body>"); 143 pw.println("</html>"); 144 pw.close(); 145 } 146 writeTSV(String outfile, BitSet filter)147 void writeTSV(String outfile, BitSet filter) throws IOException { 148 FileOutputStream fos = new FileOutputStream(outfile); 149 PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"))); 150 151 for (APIInfo info : _apidata.set) { 152 if (!filter.get(info.getVal(APIInfo.STA))) { 153 continue; 154 } 155 StringBuilder buf = new StringBuilder(); 156 157 // package 158 buf.append(info.getPackageName()); 159 buf.append("\t"); 160 161 // class 162 String className = info.getClassName(); 163 if (className.length() == 0) { 164 className = info.getName(); 165 } 166 buf.append(className); 167 buf.append("\t"); 168 169 // signature, etc 170 info.format(buf, false, false, false); 171 buf.append("\t"); 172 173 // status 174 buf.append(APIInfo.getTypeValName(APIInfo.STA, info.getVal(APIInfo.STA))); 175 buf.append("\t"); 176 177 // version 178 String statusVer = info.getStatusVersion(); 179 if (statusVer.length() == 0) { 180 statusVer = "[N/A]"; 181 } 182 buf.append(statusVer); 183 184 pw.println(buf.toString()); 185 } 186 pw.close(); 187 } 188 main(String[] args)189 public static void main(String[] args) { 190 String apifile = null; 191 String outfile = null; 192 BitSet filter = new BitSet(MAXSTATE + 1); 193 boolean isTSV = false; 194 195 // default filter 196 filter.set(APIInfo.STA_STABLE); 197 filter.set(APIInfo.STA_DRAFT); 198 filter.set(APIInfo.STA_DEPRECATED); 199 200 for (int i = 0; i < args.length; i++) { 201 if (args[i].equals("-f")) { 202 if (i + 1 == args.length) { 203 System.out.println("Missing filter argument"); 204 return; 205 } 206 i++; 207 String[] types = args[i].split(","); 208 filter.clear(); 209 for (String type : types) { 210 if (type.equalsIgnoreCase(getStatusTypeName(APIInfo.STA_STABLE))) { 211 filter.set(APIInfo.STA_STABLE); 212 } else if (type.equalsIgnoreCase(getStatusTypeName(APIInfo.STA_DRAFT))) { 213 filter.set(APIInfo.STA_DRAFT); 214 } else if (type.equalsIgnoreCase(getStatusTypeName(APIInfo.STA_DEPRECATED))) { 215 filter.set(APIInfo.STA_DEPRECATED); 216 } else if (type.equalsIgnoreCase(getStatusTypeName(APIInfo.STA_OBSOLETE))) { 217 filter.set(APIInfo.STA_OBSOLETE); 218 } else if (type.equalsIgnoreCase(getStatusTypeName(APIInfo.STA_INTERNAL))) { 219 filter.set(APIInfo.STA_INTERNAL); 220 } else { 221 System.out.println("Bad filter type " + type); 222 return; 223 } 224 } 225 } else if (args[i].equals("-o")) { 226 if (i + 1 == args.length) { 227 System.out.println("Missing filter argument"); 228 return; 229 } 230 i++; 231 outfile = args[i]; 232 } else if (args[i].equals("-t")) { 233 isTSV = true; 234 } else { 235 apifile = args[i]; 236 if (i + 1 != args.length) { 237 System.out.println("Too many arguments"); 238 return; 239 } 240 } 241 } 242 243 if (apifile == null) { 244 System.out.println("No API file specified"); 245 return; 246 } 247 248 CollectAPI collection = new CollectAPI(apifile); 249 250 try { 251 if (isTSV) { 252 if (outfile == null) { 253 outfile = "api.tsv"; 254 } 255 collection.writeTSV(outfile, filter); 256 } else { 257 if (outfile == null) { 258 outfile = "api.html"; 259 } 260 collection.writeHTML(outfile, filter); 261 } 262 } catch (IOException e) { 263 e.printStackTrace(); 264 } 265 } 266 getStatusTypeName(int status)267 private static String getStatusTypeName(int status) { 268 String name = null; 269 switch (status) { 270 case APIInfo.STA_STABLE: 271 name = "Stable"; 272 break; 273 274 case APIInfo.STA_DRAFT: 275 name = "Draft"; 276 break; 277 278 case APIInfo.STA_DEPRECATED: 279 name = "Deprecated"; 280 break; 281 282 case APIInfo.STA_OBSOLETE: 283 name = "Obsolete"; 284 break; 285 286 case APIInfo.STA_INTERNAL: 287 name = "Internal"; 288 break; 289 290 default: 291 throw new IllegalArgumentException("Bad API status type " + status); 292 } 293 294 return name; 295 } 296 } 297