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