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 last sorter property 27 * @author Jean-Francois Denise 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 LastSorterTest 32 */ 33 34import java.util.ArrayList; 35import java.util.Collections; 36import java.util.HashMap; 37import java.util.List; 38import java.util.Map; 39 40import jdk.tools.jlink.internal.ImagePluginConfiguration; 41import jdk.tools.jlink.internal.ImagePluginStack; 42import jdk.tools.jlink.internal.Jlink; 43import jdk.tools.jlink.internal.Jlink.PluginsConfiguration; 44import jdk.tools.jlink.internal.PluginRepository; 45import jdk.tools.jlink.internal.ResourcePoolManager; 46import jdk.tools.jlink.plugin.Plugin; 47import jdk.tools.jlink.plugin.ResourcePool; 48import jdk.tools.jlink.plugin.ResourcePoolBuilder; 49import jdk.tools.jlink.plugin.ResourcePoolEntry; 50 51public class LastSorterTest { 52 53 public LastSorterTest() { 54 for (int i = 1; i <= 6; i++) { 55 PluginRepository.registerPlugin(new SorterPlugin("sorterplugin" + i)); 56 } 57 } 58 59 public static void main(String[] args) throws Exception { 60 new LastSorterTest().test(); 61 } 62 63 public void test() throws Exception { 64 checkUnknownPlugin(); 65 66 checkOrderAfterLastSorter(); 67 68 checkPositiveCase(); 69 70 checkTwoLastSorters(); 71 } 72 73 private void checkTwoLastSorters() throws Exception { 74 List<Plugin> plugins = new ArrayList<>(); 75 plugins.add(createPlugin("sorterplugin5", "/a")); 76 plugins.add(createPlugin("sorterplugin6", "/a")); 77 PluginsConfiguration config = new Jlink.PluginsConfiguration(plugins, 78 null, "sorterplugin5"); 79 80 ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); 81 82 // check order 83 ResourcePoolManager res = fillOutResourceResourcePool(); 84 85 try { 86 stack.visitResources(res); 87 throw new AssertionError("Exception expected: Order of resources is already frozen." + 88 "Plugin sorterplugin6 is badly located"); 89 } catch (Exception e) { 90 // expected 91 } 92 } 93 94 private ResourcePoolManager fillOutResourceResourcePool() throws Exception { 95 ResourcePoolManager res = new ResourcePoolManager(); 96 res.add(ResourcePoolEntry.create("/eee/bbb/res1.class", new byte[90])); 97 res.add(ResourcePoolEntry.create("/aaaa/bbb/res2.class", new byte[90])); 98 res.add(ResourcePoolEntry.create("/bbb/aa/res1.class", new byte[90])); 99 res.add(ResourcePoolEntry.create("/aaaa/bbb/res3.class", new byte[90])); 100 res.add(ResourcePoolEntry.create("/bbb/aa/res2.class", new byte[90])); 101 res.add(ResourcePoolEntry.create("/fff/bbb/res1.class", new byte[90])); 102 res.add(ResourcePoolEntry.create("/aaaa/bbb/res1.class", new byte[90])); 103 res.add(ResourcePoolEntry.create("/bbb/aa/res3.class", new byte[90])); 104 res.add(ResourcePoolEntry.create("/ccc/bbb/res1.class", new byte[90])); 105 res.add(ResourcePoolEntry.create("/ddd/bbb/res1.class", new byte[90])); 106 return res; 107 } 108 109 private static Plugin createPlugin(String name, String arg) { 110 Map<String, String> conf = new HashMap<>(); 111 conf.put(name, arg); 112 return Jlink.newPlugin(name, conf, null); 113 } 114 115 private void checkPositiveCase() throws Exception { 116 List<Plugin> plugins = new ArrayList<>(); 117 plugins.add(createPlugin("sorterplugin1", "/c")); 118 plugins.add(createPlugin("sorterplugin2", "/b")); 119 plugins.add(createPlugin("sorterplugin3", "/a")); 120 121 PluginsConfiguration config = new Jlink.PluginsConfiguration(plugins, 122 null, "sorterplugin3"); 123 124 ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); 125 126 // check order 127 ResourcePoolManager res = fillOutResourceResourcePool(); 128 129 stack.visitResources(res); 130 } 131 132 private void checkUnknownPlugin() { 133 List<Plugin> plugins = new ArrayList<>(); 134 plugins.add(createPlugin("sorterplugin1", "/1")); 135 plugins.add(createPlugin("sorterplugin2", "/1")); 136 plugins.add(createPlugin("sorterplugin3", "/1")); 137 plugins.add(createPlugin("sorterplugin4", "/1")); 138 139 PluginsConfiguration config = new Jlink.PluginsConfiguration(plugins, 140 null, "sorterplugin5"); 141 try { 142 ImagePluginConfiguration.parseConfiguration(config); 143 throw new AssertionError("Unknown plugin should have failed."); 144 } catch (Exception ex) { 145 // XXX OK expected 146 } 147 } 148 149 private void checkOrderAfterLastSorter() throws Exception { 150 List<Plugin> plugins = new ArrayList<>(); 151 plugins.add(createPlugin("sorterplugin1", "/c")); 152 plugins.add(createPlugin("sorterplugin2", "/b")); 153 plugins.add(createPlugin("sorterplugin3", "/a")); 154 plugins.add(createPlugin("sorterplugin4", "/d")); 155 156 PluginsConfiguration config = new Jlink.PluginsConfiguration(plugins, 157 null, "sorterplugin3"); 158 159 ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); 160 161 // check order 162 ResourcePoolManager res = fillOutResourceResourcePool(); 163 try { 164 stack.visitResources(res); 165 throw new AssertionError("Order was changed after the last sorter, but no exception occurred"); 166 } catch (Exception ex) { 167 // XXX OK expected 168 } 169 } 170 171 public static class SorterPlugin implements Plugin { 172 173 private final String name; 174 private String starts; 175 176 private SorterPlugin(String name) { 177 this.name = name; 178 } 179 180 @Override 181 public ResourcePool transform(ResourcePool resources, ResourcePoolBuilder output) { 182 List<ResourcePoolEntry> paths = new ArrayList<>(); 183 resources.entries().forEach(res -> { 184 if (res.path().startsWith(starts)) { 185 paths.add(0, res); 186 } else { 187 paths.add(res); 188 } 189 }); 190 191 for (ResourcePoolEntry r : paths) { 192 output.add(r); 193 } 194 195 return output.build(); 196 } 197 198 @Override 199 public String getName() { 200 return name; 201 } 202 203 @Override 204 public void configure(Map<String, String> config) { 205 String arguments = config.get(name); 206 this.starts = arguments; 207 } 208 } 209} 210