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 previsitor 27 * @author Andrei Eremeev 28 * @modules jdk.jlink/jdk.tools.jlink.internal 29 * jdk.jlink/jdk.tools.jlink 30 * @run main/othervm PrevisitorTest 31 */ 32 import java.nio.ByteOrder; 33 import java.util.ArrayList; 34 import java.util.Collection; 35 import java.util.Collections; 36 import java.util.HashMap; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Optional; 40 import java.util.stream.Collectors; 41 42 import jdk.tools.jlink.internal.ImagePluginConfiguration; 43 import jdk.tools.jlink.internal.Jlink; 44 import jdk.tools.jlink.internal.PluginRepository; 45 import jdk.tools.jlink.internal.ImagePluginStack; 46 import jdk.tools.jlink.internal.ResourcePoolManager; 47 import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl; 48 import jdk.tools.jlink.internal.ResourcePrevisitor; 49 import jdk.tools.jlink.internal.StringTable; 50 import jdk.tools.jlink.plugin.Plugin; 51 import jdk.tools.jlink.plugin.ResourcePool; 52 import jdk.tools.jlink.plugin.ResourcePoolBuilder; 53 import jdk.tools.jlink.plugin.ResourcePoolEntry; 54 55 public class PrevisitorTest { 56 57 public static void main(String[] args) throws Exception { 58 new PrevisitorTest().test(); 59 } 60 61 private static Plugin createPlugin(String name) { 62 return Jlink.newPlugin(name, Collections.emptyMap(), null); 63 } 64 65 public void test() throws Exception { 66 CustomPlugin plugin = new CustomPlugin(); 67 PluginRepository.registerPlugin(plugin); 68 List<Plugin> plugins = new ArrayList<>(); 69 plugins.add(createPlugin(CustomPlugin.NAME)); 70 ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins, 71 null, null)); 72 ResourcePoolManager inResources = new ResourcePoolManager(ByteOrder.nativeOrder(), new CustomStringTable()); 73 inResources.add(ResourcePoolEntry.create("/aaa/bbb/res1.class", new byte[90])); 74 inResources.add(ResourcePoolEntry.create("/aaa/bbb/res2.class", new byte[90])); 75 inResources.add(ResourcePoolEntry.create("/aaa/bbb/res3.class", new byte[90])); 76 inResources.add(ResourcePoolEntry.create("/aaa/ddd/res1.class", new byte[90])); 77 inResources.add(ResourcePoolEntry.create("/aaa/res1.class", new byte[90])); 78 ResourcePool outResources = stack.visitResources(inResources); 79 Collection<String> input = inResources.entries() 80 .map(Object::toString) 81 .collect(Collectors.toList()); 82 Collection<String> output = outResources.entries() 83 .map(Object::toString) 84 .collect(Collectors.toList()); 85 if (!input.equals(output)) { 86 throw new AssertionError("Input and output resources differ: input: " 87 + input + ", output: " + output); 88 } 89 } 90 91 private static class CustomStringTable implements StringTable { 92 93 private final List<String> strings = new ArrayList<>(); 94 95 @Override 96 public int addString(String str) { 97 strings.add(str); 98 return strings.size() - 1; 99 } 100 101 @Override 102 public String getString(int id) { 103 return strings.get(id); 104 } 105 106 public int size() { 107 return strings.size(); 108 } 109 } 110 111 private static class CustomPlugin implements Plugin, ResourcePrevisitor { 112 113 private static String NAME = "plugin"; 114 115 private boolean isPrevisitCalled = false; 116 117 @Override 118 public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) { 119 if (!isPrevisitCalled) { 120 throw new AssertionError("Previsit was not called"); 121 } 122 CustomStringTable table = (CustomStringTable)((ResourcePoolImpl)inResources).getStringTable(); 123 if (table.size() == 0) { 124 throw new AssertionError("Table is empty"); 125 } 126 Map<String, Integer> count = new HashMap<>(); 127 for (int i = 0; i < table.size(); ++i) { 128 String s = table.getString(i); 129 Optional<ResourcePoolEntry> e = inResources.findEntry(s); 130 if (e.isPresent()) { 131 throw new AssertionError(); 132 } 133 count.compute(s, (k, c) -> 1 + (c == null ? 0 : c)); 134 } 135 count.forEach((k, v) -> { 136 if (v != 1) { 137 throw new AssertionError("Expected one entry in the table, got: " + v + " for " + k); 138 } 139 }); 140 inResources.entries().forEach(r -> { 141 outResources.add(r); 142 }); 143 144 return outResources.build(); 145 } 146 147 @Override 148 public String getName() { 149 return NAME; 150 } 151 152 @Override 153 public void previsit(ResourcePool resources, StringTable strings) { 154 isPrevisitCalled = true; 155 resources.entries().forEach(r -> { 156 String s = r.path(); 157 int lastIndexOf = s.lastIndexOf('/'); 158 if (lastIndexOf >= 0) { 159 strings.addString(s.substring(0, lastIndexOf)); 160 } 161 }); 162 } 163 } 164 }