jdk/test/tools/jlink/plugins/CompressorPluginTest.java
changeset 39042 52db877f18db
parent 38320 e24c7029e8ba
child 39321 c60f34e8c057
equal deleted inserted replaced
39041:347b1b47ce21 39042:52db877f18db
   101                     new StringSharingDecompressorFactory()
   101                     new StringSharingDecompressorFactory()
   102                 });
   102                 });
   103 
   103 
   104         // compress == ZIP + String sharing + filter
   104         // compress == ZIP + String sharing + filter
   105         options.setProperty(DefaultCompressPlugin.FILTER,
   105         options.setProperty(DefaultCompressPlugin.FILTER,
   106                 "*Exception.class,^*IOException.class");
   106                 "**Exception.class");
   107         checkCompress(classes, new DefaultCompressPlugin(), options,
   107         checkCompress(classes, new DefaultCompressPlugin(), options,
   108                 new ResourceDecompressorFactory[]{
   108                 new ResourceDecompressorFactory[]{
   109                     new ZipDecompressorFactory(),
   109                     new ZipDecompressorFactory(),
   110                     new StringSharingDecompressorFactory()
   110                     new StringSharingDecompressorFactory()
   111                 }, Collections.singletonList(".*Exception.class"),
   111                 }, Collections.singletonList(".*Exception.class"));
   112                 Collections.singletonList(".*IOException.class"));
       
   113 
   112 
   114         // compress level 1 == ZIP
   113         // compress level 1 == ZIP
   115         Properties options1 = new Properties();
   114         Properties options1 = new Properties();
   116         options1.setProperty(DefaultCompressPlugin.NAME,
   115         options1.setProperty(DefaultCompressPlugin.NAME,
   117                 "1");
   116                 "1");
   121                     new ZipDecompressorFactory()
   120                     new ZipDecompressorFactory()
   122                 });
   121                 });
   123 
   122 
   124         // compress level 1 == ZIP
   123         // compress level 1 == ZIP
   125         options1.setProperty(DefaultCompressPlugin.FILTER,
   124         options1.setProperty(DefaultCompressPlugin.FILTER,
   126                 "*Exception.class,^*IOException.class");
   125                 "**Exception.class");
   127         checkCompress(classes, new DefaultCompressPlugin(),
   126         checkCompress(classes, new DefaultCompressPlugin(),
   128                 options1,
   127                 options1,
   129                 new ResourceDecompressorFactory[]{
   128                 new ResourceDecompressorFactory[]{
   130                     new ZipDecompressorFactory()
   129                     new ZipDecompressorFactory()
   131                 }, Collections.singletonList(".*Exception.class"),
   130                 }, Collections.singletonList(".*Exception.class"));
   132                 Collections.singletonList(".*IOException.class"));
       
   133 
   131 
   134         // compress level 2 == ZIP + String sharing
   132         // compress level 2 == ZIP + String sharing
   135         Properties options2 = new Properties();
   133         Properties options2 = new Properties();
   136         options2.setProperty(DefaultCompressPlugin.NAME,
   134         options2.setProperty(DefaultCompressPlugin.NAME,
   137                 "2");
   135                 "2");
   142                     new StringSharingDecompressorFactory()
   140                     new StringSharingDecompressorFactory()
   143                 });
   141                 });
   144 
   142 
   145         // compress level 2 == ZIP + String sharing + filter
   143         // compress level 2 == ZIP + String sharing + filter
   146         options2.setProperty(DefaultCompressPlugin.FILTER,
   144         options2.setProperty(DefaultCompressPlugin.FILTER,
   147                 "*Exception.class,^*IOException.class");
   145                 "**Exception.class");
   148         checkCompress(classes, new DefaultCompressPlugin(),
   146         checkCompress(classes, new DefaultCompressPlugin(),
   149                 options2,
   147                 options2,
   150                 new ResourceDecompressorFactory[]{
   148                 new ResourceDecompressorFactory[]{
   151                     new ZipDecompressorFactory(),
   149                     new ZipDecompressorFactory(),
   152                     new StringSharingDecompressorFactory()
   150                     new StringSharingDecompressorFactory()
   153                 }, Collections.singletonList(".*Exception.class"),
   151                 }, Collections.singletonList(".*Exception.class"));
   154                 Collections.singletonList(".*IOException.class"));
       
   155 
   152 
   156         // compress level 0 == String sharing
   153         // compress level 0 == String sharing
   157         Properties options0 = new Properties();
   154         Properties options0 = new Properties();
   158         options0.setProperty(DefaultCompressPlugin.NAME, "0");
   155         options0.setProperty(DefaultCompressPlugin.NAME, "0");
   159         checkCompress(classes, new DefaultCompressPlugin(),
   156         checkCompress(classes, new DefaultCompressPlugin(),
   162                     new StringSharingDecompressorFactory()
   159                     new StringSharingDecompressorFactory()
   163                 });
   160                 });
   164 
   161 
   165         // compress level 0 == String sharing + filter
   162         // compress level 0 == String sharing + filter
   166         options0.setProperty(DefaultCompressPlugin.FILTER,
   163         options0.setProperty(DefaultCompressPlugin.FILTER,
   167                 "*Exception.class,^*IOException.class");
   164                 "**Exception.class");
   168         checkCompress(classes, new DefaultCompressPlugin(),
   165         checkCompress(classes, new DefaultCompressPlugin(),
   169                 options0,
   166                 options0,
   170                 new ResourceDecompressorFactory[]{
   167                 new ResourceDecompressorFactory[]{
   171                     new StringSharingDecompressorFactory()
   168                     new StringSharingDecompressorFactory()
   172                 }, Collections.singletonList(".*Exception.class"),
   169                 }, Collections.singletonList(".*Exception.class"));
   173                 Collections.singletonList(".*IOException.class"));
       
   174     }
   170     }
   175 
   171 
   176     private ModulePool gatherResources(Path module) throws Exception {
   172     private ModulePool gatherResources(Path module) throws Exception {
   177         ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
   173         ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
   178 
   174 
   224     }
   220     }
   225 
   221 
   226     private void checkCompress(ModulePool resources, Plugin prov,
   222     private void checkCompress(ModulePool resources, Plugin prov,
   227             Properties config,
   223             Properties config,
   228             ResourceDecompressorFactory[] factories) throws Exception {
   224             ResourceDecompressorFactory[] factories) throws Exception {
   229         checkCompress(resources, prov, config, factories, Collections.emptyList(), Collections.emptyList());
   225         checkCompress(resources, prov, config, factories, Collections.emptyList());
   230     }
   226     }
   231 
   227 
   232     private void checkCompress(ModulePool resources, Plugin prov,
   228     private void checkCompress(ModulePool resources, Plugin prov,
   233             Properties config,
   229             Properties config,
   234             ResourceDecompressorFactory[] factories,
   230             ResourceDecompressorFactory[] factories,
   235             List<String> includes,
   231             List<String> includes) throws Exception {
   236             List<String> excludes) throws Exception {
       
   237         long[] original = new long[1];
   232         long[] original = new long[1];
   238         long[] compressed = new long[1];
   233         long[] compressed = new long[1];
   239         resources.entries().forEach(resource -> {
   234         resources.entries().forEach(resource -> {
   240             List<Pattern> includesPatterns = includes.stream()
   235             List<Pattern> includesPatterns = includes.stream()
   241                     .map(Pattern::compile)
       
   242                     .collect(Collectors.toList());
       
   243             List<Pattern> excludesPatterns = excludes.stream()
       
   244                     .map(Pattern::compile)
   236                     .map(Pattern::compile)
   245                     .collect(Collectors.toList());
   237                     .collect(Collectors.toList());
   246 
   238 
   247             Map<String, String> props = new HashMap<>();
   239             Map<String, String> props = new HashMap<>();
   248             if (config != null) {
   240             if (config != null) {
   265                 public String getString(int id) {
   257                 public String getString(int id) {
   266                     return strings.get(id);
   258                     return strings.get(id);
   267                 }
   259                 }
   268             });
   260             });
   269             inputResources.add(resource);
   261             inputResources.add(resource);
   270             ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns);
   262             ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns);
   271             original[0] += resource.getLength();
   263             original[0] += resource.getLength();
   272             compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
   264             compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
   273             applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns, excludesPatterns);
   265             applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns);
   274         });
   266         });
   275         String compressors = Stream.of(factories)
   267         String compressors = Stream.of(factories)
   276                 .map(Object::getClass)
   268                 .map(Object::getClass)
   277                 .map(Class::getSimpleName)
   269                 .map(Class::getSimpleName)
   278                 .collect(Collectors.joining(", "));
   270                 .collect(Collectors.joining(", "));
   284     }
   276     }
   285 
   277 
   286     private ModulePool applyCompressor(Plugin plugin,
   278     private ModulePool applyCompressor(Plugin plugin,
   287             ModulePoolImpl inputResources,
   279             ModulePoolImpl inputResources,
   288             ModuleEntry res,
   280             ModuleEntry res,
   289             List<Pattern> includesPatterns,
   281             List<Pattern> includesPatterns) {
   290             List<Pattern> excludesPatterns) {
       
   291         TransformerPlugin compressor = (TransformerPlugin) plugin;
   282         TransformerPlugin compressor = (TransformerPlugin) plugin;
   292         ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
   283         ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
   293         compressor.visit(inputResources, compressedModulePool);
   284         compressor.visit(inputResources, compressedModulePool);
   294         String path = res.getPath();
   285         String path = res.getPath();
   295         ModuleEntry compressed = compressedModulePool.findEntry(path).get();
   286         ModuleEntry compressed = compressedModulePool.findEntry(path).get();
   296         CompressedResourceHeader header
   287         CompressedResourceHeader header
   297                 = CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
   288                 = CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
   298         if (isIncluded(includesPatterns, excludesPatterns, path)) {
   289         if (isIncluded(includesPatterns, path)) {
   299             if (header == null) {
   290             if (header == null) {
   300                 throw new AssertionError("Path should be compressed: " + path);
   291                 throw new AssertionError("Path should be compressed: " + path);
   301             }
   292             }
   302             if (header.getDecompressorNameOffset() == 0) {
   293             if (header.getDecompressorNameOffset() == 0) {
   303                 throw new AssertionError("Invalid plugin offset "
   294                 throw new AssertionError("Invalid plugin offset "
   315 
   306 
   316     private void applyDecompressors(ResourceDecompressorFactory[] decompressors,
   307     private void applyDecompressors(ResourceDecompressorFactory[] decompressors,
   317             ModulePool inputResources,
   308             ModulePool inputResources,
   318             ModulePool compressedResources,
   309             ModulePool compressedResources,
   319             Map<Integer, String> strings,
   310             Map<Integer, String> strings,
   320             List<Pattern> includesPatterns,
   311             List<Pattern> includesPatterns) {
   321             List<Pattern> excludesPatterns) {
       
   322         compressedResources.entries().forEach(compressed -> {
   312         compressedResources.entries().forEach(compressed -> {
   323             CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
   313             CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
   324                     ByteOrder.nativeOrder(), compressed.getBytes());
   314                     ByteOrder.nativeOrder(), compressed.getBytes());
   325             String path = compressed.getPath();
   315             String path = compressed.getPath();
   326             ModuleEntry orig = inputResources.findEntry(path).get();
   316             ModuleEntry orig = inputResources.findEntry(path).get();
   327             if (!isIncluded(includesPatterns, excludesPatterns, path)) {
   317             if (!isIncluded(includesPatterns, path)) {
   328                 return;
   318                 return;
   329             }
   319             }
   330             byte[] decompressed = compressed.getBytes();
   320             byte[] decompressed = compressed.getBytes();
   331             for (ResourceDecompressorFactory factory : decompressors) {
   321             for (ResourceDecompressorFactory factory : decompressors) {
   332                 try {
   322                 try {
   350                 }
   340                 }
   351             }
   341             }
   352         });
   342         });
   353     }
   343     }
   354 
   344 
   355     private boolean isIncluded(List<Pattern> includesPatterns, List<Pattern> excludesPatterns, String path) {
   345     private boolean isIncluded(List<Pattern> includesPatterns, String path) {
   356         return !excludesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches())
   346         return includesPatterns.isEmpty() ||
   357                 && (includesPatterns.isEmpty()
   347                includesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches());
   358                 || includesPatterns.stream().anyMatch((pattern) -> pattern.matcher(path).matches()));
       
   359     }
   348     }
   360 }
   349 }