34 import java.lang.module.ResolvedModule; 35 import java.nio.file.Files; 36 import java.nio.file.Path; 37 import java.nio.file.Paths; 38 import java.util.Arrays; 39 import java.util.Comparator; 40 import java.util.Date; 41 import java.util.Enumeration; 42 import java.util.HashMap; 43 import java.util.HashSet; 44 import java.util.Map; 45 import java.util.Set; 46 import java.util.stream.Collectors; 47 import java.util.zip.ZipEntry; 48 import java.util.zip.ZipFile; 49 import static java.lang.module.ModuleDescriptor.*; 50 import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Selector.*; 51 import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*; 52 53 public class ModuleSummary { 54 private static final String USAGE = "Usage: ModuleSummary -mp <dir> -o <outfile> [-root mn]*"; 55 56 public static void main(String[] args) throws Exception { 57 int i=0; 58 Path modpath = null; 59 Path outfile = null; 60 Set<String> roots = new HashSet<>(); 61 while (i < args.length && args[i].startsWith("-")) { 62 String arg = args[i++]; 63 switch (arg) { 64 case "-mp": 65 modpath = Paths.get(args[i++]); 66 break; 67 case "-o": 68 outfile = Paths.get(args[i++]); 69 break; 70 case "-root": 71 roots.add(args[i++]); 72 default: 73 System.err.println(USAGE); 74 System.exit(-1); 75 } 76 } 77 if (outfile == null || modpath == null) { 78 System.err.println(USAGE); 79 System.exit(1); 80 } 81 Path dir = outfile.getParent() != null ? outfile.getParent() : Paths.get("."); 82 Files.createDirectories(dir); 83 84 Map<String, ModuleSummary> modules = new HashMap<>(); 85 Set<ModuleReference> mrefs = ModuleFinder.ofSystem().findAll(); 86 for (ModuleReference mref : mrefs) { 87 String mn = mref.descriptor().name(); 88 Path jmod = modpath.resolve(mn + ".jmod"); 89 modules.put(mn, new ModuleSummary(mref, jmod)); 90 } 475 sb.append(toTableRow(String.format("Total jmod bytes (%d %s)", deps.size(), files), reqJmodFileSize)); 476 477 if (aggregator && !aggregatorNote) { 478 aggregatorNote = true; 479 sb.append(blankRow()); 480 sb.append(toTableRow("<i>* aggregator is a module with module-info.class only</i>", BR)); 481 } 482 if (!totalBytesNote) { 483 totalBytesNote = true; 484 sb.append(blankRow()); 485 sb.append(toTableRow("<i><sup>1</sup>sum of all files including debug files</i>", BR)); 486 sb.append(toTableRow("<i><sup>2</sup>sum of direct and indirect dependencies</i>", BR)); 487 } 488 sb.append("</table>").append("</td>"); 489 return sb.toString(); 490 } 491 492 private String moduleName(String mn) { 493 if (aggregator) { 494 StringBuilder sb = new StringBuilder(); 495 sb.append(String.format("<tr><td colspan=\"2\"><span class=\"%s\">", AGGREGATOR)) 496 .append(mn) 497 .append("</span>").append(" "); 498 if (!aggregatorNote) { 499 sb.append("(aggregator<sup>*</sup>)"); 500 } else { 501 sb.append("(aggregator)"); 502 } 503 sb.append("</td></tr>"); 504 return sb.toString(); 505 } else { 506 return toTableRow(mn, MODULE_DEF); 507 } 508 } 509 510 public String requiresColumn() { 511 StringBuilder sb = new StringBuilder(); 512 sb.append(String.format("<td>")); 513 boolean footnote = requiresPublicNote; 514 ms.descriptor().requires().stream() 515 .sorted(Comparator.comparing(Requires::name)) 636 } 637 builder.data(bytes); 638 return builder.build(); 639 } 640 641 class TableDataBuilder { 642 private final StringBuilder sb; 643 TableDataBuilder() { 644 this.sb = new StringBuilder("<tr>"); 645 } 646 TableDataBuilder data(String s) { 647 data(BR, s); 648 return this; 649 } 650 TableDataBuilder data(long num) { 651 data(NUMBER, String.format("%,d", num)); 652 return this; 653 } 654 TableDataBuilder colspan(Selector selector, int columns, String data) { 655 sb.append("<td colspan=\"").append(columns).append("\">"); 656 sb.append("<span class=\"").append(selector).append("\">"); 657 sb.append(data).append("</span></td>"); 658 return this; 659 } 660 661 TableDataBuilder data(Selector selector, String data) { 662 sb.append("<td class=\"").append(selector).append("\">"); 663 sb.append(data).append("</td>"); 664 return this; 665 } 666 String build() { 667 sb.append("</tr>"); 668 return sb.toString(); 669 } 670 } 671 } 672 673 private static final String[] STYLES = new String[]{ 674 "<link rel=\"stylesheet\" type=\"text/css\" href=\"/.fonts/dejavu.css\"/>", 675 "<style type=\"text/css\">", 676 " HTML, BODY, DIV, SPAN, APPLET, OBJECT, IFRAME, H1, H2, H3, H4, H5, H6, P,", | 34 import java.lang.module.ResolvedModule; 35 import java.nio.file.Files; 36 import java.nio.file.Path; 37 import java.nio.file.Paths; 38 import java.util.Arrays; 39 import java.util.Comparator; 40 import java.util.Date; 41 import java.util.Enumeration; 42 import java.util.HashMap; 43 import java.util.HashSet; 44 import java.util.Map; 45 import java.util.Set; 46 import java.util.stream.Collectors; 47 import java.util.zip.ZipEntry; 48 import java.util.zip.ZipFile; 49 import static java.lang.module.ModuleDescriptor.*; 50 import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Selector.*; 51 import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*; 52 53 public class ModuleSummary { 54 private static final String USAGE = "Usage: ModuleSummary --module-path <dir> -o <outfile> [--root mn]*"; 55 56 public static void main(String[] args) throws Exception { 57 int i=0; 58 Path modpath = null; 59 Path outfile = null; 60 Set<String> roots = new HashSet<>(); 61 while (i < args.length && args[i].startsWith("-")) { 62 String arg = args[i++]; 63 switch (arg) { 64 case "--module-path": 65 modpath = Paths.get(args[i++]); 66 break; 67 case "-o": 68 outfile = Paths.get(args[i++]); 69 break; 70 case "--root": 71 roots.add(args[i++]); 72 default: 73 System.err.println(USAGE); 74 System.exit(-1); 75 } 76 } 77 if (outfile == null || modpath == null) { 78 System.err.println(USAGE); 79 System.exit(1); 80 } 81 Path dir = outfile.getParent() != null ? outfile.getParent() : Paths.get("."); 82 Files.createDirectories(dir); 83 84 Map<String, ModuleSummary> modules = new HashMap<>(); 85 Set<ModuleReference> mrefs = ModuleFinder.ofSystem().findAll(); 86 for (ModuleReference mref : mrefs) { 87 String mn = mref.descriptor().name(); 88 Path jmod = modpath.resolve(mn + ".jmod"); 89 modules.put(mn, new ModuleSummary(mref, jmod)); 90 } 475 sb.append(toTableRow(String.format("Total jmod bytes (%d %s)", deps.size(), files), reqJmodFileSize)); 476 477 if (aggregator && !aggregatorNote) { 478 aggregatorNote = true; 479 sb.append(blankRow()); 480 sb.append(toTableRow("<i>* aggregator is a module with module-info.class only</i>", BR)); 481 } 482 if (!totalBytesNote) { 483 totalBytesNote = true; 484 sb.append(blankRow()); 485 sb.append(toTableRow("<i><sup>1</sup>sum of all files including debug files</i>", BR)); 486 sb.append(toTableRow("<i><sup>2</sup>sum of direct and indirect dependencies</i>", BR)); 487 } 488 sb.append("</table>").append("</td>"); 489 return sb.toString(); 490 } 491 492 private String moduleName(String mn) { 493 if (aggregator) { 494 StringBuilder sb = new StringBuilder(); 495 sb.append(String.format("<tr><td colspan=\"2\"><span class=\"%s\">", AGGREGATOR)) 496 .append(mn) 497 .append("</span>").append(" "); 498 if (!aggregatorNote) { 499 sb.append("(aggregator<sup>*</sup>)"); 500 } else { 501 sb.append("(aggregator)"); 502 } 503 sb.append("</td></tr>"); 504 return sb.toString(); 505 } else { 506 return toTableRow(mn, MODULE_DEF); 507 } 508 } 509 510 public String requiresColumn() { 511 StringBuilder sb = new StringBuilder(); 512 sb.append(String.format("<td>")); 513 boolean footnote = requiresPublicNote; 514 ms.descriptor().requires().stream() 515 .sorted(Comparator.comparing(Requires::name)) 636 } 637 builder.data(bytes); 638 return builder.build(); 639 } 640 641 class TableDataBuilder { 642 private final StringBuilder sb; 643 TableDataBuilder() { 644 this.sb = new StringBuilder("<tr>"); 645 } 646 TableDataBuilder data(String s) { 647 data(BR, s); 648 return this; 649 } 650 TableDataBuilder data(long num) { 651 data(NUMBER, String.format("%,d", num)); 652 return this; 653 } 654 TableDataBuilder colspan(Selector selector, int columns, String data) { 655 sb.append("<td colspan=\"").append(columns).append("\">"); 656 sb.append("<span class=\"").append(selector).append("\">"); 657 sb.append(data).append("</span></td>"); 658 return this; 659 } 660 661 TableDataBuilder data(Selector selector, String data) { 662 sb.append("<td class=\"").append(selector).append("\">"); 663 sb.append(data).append("</td>"); 664 return this; 665 } 666 String build() { 667 sb.append("</tr>"); 668 return sb.toString(); 669 } 670 } 671 } 672 673 private static final String[] STYLES = new String[]{ 674 "<link rel=\"stylesheet\" type=\"text/css\" href=\"/.fonts/dejavu.css\"/>", 675 "<style type=\"text/css\">", 676 " HTML, BODY, DIV, SPAN, APPLET, OBJECT, IFRAME, H1, H2, H3, H4, H5, H6, P,", |