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 import java.io.ByteArrayInputStream; 25 import java.io.ByteArrayOutputStream; 26 import java.io.DataOutputStream; 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.nio.ByteOrder; 30 import java.nio.file.Path; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.HashSet; 34 import java.util.List; 35 import java.util.Set; 36 import java.util.stream.Stream; 37 import jdk.tools.jlink.internal.Archive; 38 import jdk.tools.jlink.internal.ImageFileCreator; 39 import jdk.tools.jlink.internal.ImagePluginStack; 40 import jdk.tools.jlink.plugin.ExecutableImage; 41 import jdk.tools.jlink.builder.ImageBuilder; 42 import jdk.tools.jlink.plugin.Pool; 43 44 45 /* 46 * @test 47 * @summary ImageFileCreator class test 48 * @author Jean-Francois Denise 49 * @modules jdk.jlink/jdk.tools.jlink.internal 50 * java.base/jdk.internal.jimage 51 * @run main/othervm -verbose:gc -Xmx1g ImageFileCreatorTest 52 */ 53 public class ImageFileCreatorTest { 54 55 private static class TestArchive implements Archive { 56 57 private final String name; 58 private final List<Entry> entries = new ArrayList<>(); 59 60 private TestArchive(String name, List<String> entries) { 61 this.name = name; 62 for (String p : entries) { 63 this.entries.add(new TestEntry(p, p)); 64 } 65 } 66 67 @Override 68 public String moduleName() { 69 return name; 70 } 71 72 @Override 73 public Stream<Entry> entries() { 74 return entries.stream(); 75 } 76 77 @Override 78 public Path getPath() { 79 return null; 80 } 81 82 @Override 83 public void open() throws IOException { 84 } 85 86 @Override 87 public void close() throws IOException { 88 } 89 90 private class TestEntry extends Entry { 91 92 TestEntry(String path, String name) { 93 super(TestArchive.this, path, name, Entry.EntryType.CLASS_OR_RESOURCE); 94 } 95 96 @Override 97 public long size() { 98 return 0; 99 } 100 101 @Override 102 public InputStream stream() throws IOException { 103 return new ByteArrayInputStream(new byte[0]); 104 } 105 } 106 } 107 108 public static void main(String[] args) throws Exception { 109 110 { 111 List<String> entries = new ArrayList<>(); 112 entries.add("classes/class"); 113 test(entries); 114 } 115 116 { 117 // Add an entry that is a directory, that is wrong 118 List<String> entries = new ArrayList<>(); 119 entries.add("classes"); 120 entries.add("classes/class"); 121 test(entries); 122 } 123 124 { 125 // Add an entry that is wrongly prefixed by / 126 // /bad//classes/class is the resource added 127 // /bad/classes/class is the metadata node built. 128 List<String> entries = new ArrayList<>(); 129 entries.add("/classes/class"); 130 test(entries); 131 } 132 133 { 134 // Trailing '/' is wrong 135 List<String> entries = new ArrayList<>(); 136 entries.add("classes/class/"); 137 test(entries); 138 } 139 140 { 141 // Too much '/' characters 142 List<String> entries = new ArrayList<>(); 143 entries.add("classes//class/"); 144 test(entries); 145 } 146 147 { 148 // Too much '/' characters 149 List<String> entries = new ArrayList<>(); 150 entries.add("classes/////class/"); 151 test(entries); 152 } 153 154 { 155 // Single '/' character 156 List<String> entries = new ArrayList<>(); 157 entries.add("/"); 158 test(entries); 159 } 160 161 { 162 // 2 '/' characters 163 List<String> entries = new ArrayList<>(); 164 entries.add("//"); 165 test(entries); 166 } 167 168 { 169 // 3 '/' characters 170 List<String> entries = new ArrayList<>(); 171 entries.add("///"); 172 test(entries); 173 } 174 175 { 176 // no character 177 List<String> entries = new ArrayList<>(); 178 entries.add(""); 179 test(entries); 180 } 181 182 { 183 // all together 184 List<String> entries = new ArrayList<>(); 185 entries.add(""); 186 entries.add("///"); 187 entries.add("//"); 188 entries.add("/"); 189 entries.add("classes/////class/"); 190 entries.add("classes//class/"); 191 entries.add("classes/class/"); 192 entries.add("/classes/class"); 193 entries.add("classes"); 194 entries.add("classes/class"); 195 test(entries); 196 } 197 198 } 199 200 private static void test(List<String> entries) throws Exception { 201 TestArchive arch = new TestArchive("bad", entries); 202 Set<Archive> archives = new HashSet<>(); 203 archives.add(arch); 204 ImageBuilder noopBuilder = new ImageBuilder() { 205 206 @Override 207 public DataOutputStream getJImageOutputStream() { 208 return new DataOutputStream(new ByteArrayOutputStream()); 209 } 210 211 @Override 212 public ExecutableImage getExecutableImage() { 213 return null; 214 } 215 216 @Override 217 public void storeFiles(Pool content) { 218 } 219 }; 220 221 ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(), 222 null, Collections.emptyList()); 223 224 ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack); 225 } 226 }