1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @summary Test a pool containing external files.
  27  * @author Andrei Eremeev
  28  * @modules jdk.jlink/jdk.tools.jlink.internal
  29  *          jdk.jlink/jdk.tools.jlink.plugin
  30  * @run build ImageFilePoolTest
  31  * @run main ImageFilePoolTest
  32  */
  33 
  34 import java.io.ByteArrayInputStream;
  35 import java.util.Optional;
  36 import java.util.function.Function;
  37 import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
  38 import jdk.tools.jlink.internal.ResourcePoolManager;
  39 import jdk.tools.jlink.plugin.ResourcePoolEntry;
  40 import jdk.tools.jlink.plugin.ResourcePool;
  41 
  42 public class ImageFilePoolTest {
  43     public static void main(String[] args) throws Exception {
  44         new ImageFilePoolTest().test();
  45     }
  46 
  47     public void test() throws Exception {
  48         checkNegative();
  49         checkVisitor();
  50     }
  51 
  52     private static final String SUFFIX = "END";
  53 
  54     private void checkVisitor() throws Exception {
  55         ResourcePoolManager input = new ResourcePoolManager();
  56         for (int i = 0; i < 1000; ++i) {
  57             String module = "module" + (i / 100);
  58             input.add(newInMemoryImageFile("/" + module + "/java/class" + i,
  59                     ResourcePoolEntry.Type.CONFIG, "class" + i));
  60         }
  61         if (input.entryCount() != 1000) {
  62             throw new AssertionError();
  63         }
  64         ResourcePoolManager output = new ResourcePoolManager();
  65         ResourceVisitor visitor = new ResourceVisitor();
  66         input.resourcePool().transformAndCopy(visitor, output.resourcePoolBuilder());
  67         if (visitor.getAmountBefore() == 0) {
  68             throw new AssertionError("Resources not found");
  69         }
  70         if (visitor.getAmountBefore() != input.entryCount()) {
  71             throw new AssertionError("Number of visited resources. Expected: " +
  72                     visitor.getAmountBefore() + ", got: " + input.entryCount());
  73         }
  74         if (visitor.getAmountAfter() != output.entryCount()) {
  75             throw new AssertionError("Number of added resources. Expected: " +
  76                     visitor.getAmountAfter() + ", got: " + output.entryCount());
  77         }
  78         output.entries().forEach(outFile -> {
  79             String path = outFile.path().replaceAll(SUFFIX + "$", "");
  80             Optional<ResourcePoolEntry> inFile = input.findEntry(path);
  81             if (!inFile.isPresent()) {
  82                 throw new AssertionError("Unknown resource: " + path);
  83             }
  84         });
  85     }
  86 
  87     private static class ResourceVisitor implements Function<ResourcePoolEntry, ResourcePoolEntry> {
  88 
  89         private int amountBefore;
  90         private int amountAfter;
  91 
  92         @Override
  93         public ResourcePoolEntry apply(ResourcePoolEntry file) {
  94             int index = ++amountBefore % 3;
  95             switch (index) {
  96                 case 0:
  97                     ++amountAfter;
  98                     return newInMemoryImageFile(file.path() + SUFFIX,
  99                             file.type(), file.path());
 100                 case 1:
 101                     ++amountAfter;
 102                     return newInMemoryImageFile(file.path(),
 103                             file.type(), file.path());
 104             }
 105             return null;
 106         }
 107 
 108         public int getAmountAfter() {
 109             return amountAfter;
 110         }
 111 
 112         public int getAmountBefore() {
 113             return amountBefore;
 114         }
 115     }
 116 
 117     private void checkNegative() throws Exception {
 118         ResourcePoolManager input = new ResourcePoolManager();
 119         try {
 120             input.add(null);
 121             throw new AssertionError("NullPointerException is not thrown");
 122         } catch (NullPointerException e) {
 123             // expected
 124         }
 125         try {
 126             input.contains(null);
 127             throw new AssertionError("NullPointerException is not thrown");
 128         } catch (NullPointerException e) {
 129             // expected
 130         }
 131         if (input.findEntry("unknown").isPresent()) {
 132             throw new AssertionError("ImageFileResourcePool does not return null for unknown file");
 133         }
 134         if (input.contains(newInMemoryImageFile("/unknown/foo", ResourcePoolEntry.Type.CONFIG, "unknown"))) {
 135             throw new AssertionError("'contain' returns true for /unknown/foo file");
 136         }
 137         input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
 138         try {
 139             input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
 140             throw new AssertionError("Exception expected");
 141         } catch (Exception e) {
 142             // expected
 143         }
 144     }
 145 
 146     private static ResourcePoolEntry newInMemoryImageFile(String path,
 147             ResourcePoolEntry.Type type, String content) {
 148         return ResourcePoolEntryFactory.create(path, type, content.getBytes());
 149     }
 150 }