1 /* 2 * Copyright (c) 2012, 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 * Basic tests for ModuleFileParser 26 */ 27 28 import java.io.*; 29 import static java.lang.System.out; 30 import java.util.Arrays; 31 import java.util.Iterator; 32 import java.util.Map.Entry; 33 import org.openjdk.jigsaw.FileConstants.ModuleFile.SectionType; 34 import static org.openjdk.jigsaw.FileConstants.ModuleFile.SectionType.*; 35 import org.openjdk.jigsaw.ModuleFile; 36 import org.openjdk.jigsaw.ModuleFile.SectionHeader; 37 import org.openjdk.jigsaw.ModuleFile.SubSectionFileHeader; 38 import org.openjdk.jigsaw.ModuleFileParser; 39 import org.openjdk.jigsaw.ModuleFileParser.Event; 40 import static org.openjdk.jigsaw.ModuleFileParser.Event.END_FILE; 41 import static org.openjdk.jigsaw.ModuleFileParser.Event.END_SECTION; 42 import org.openjdk.jigsaw.ModuleFileParserException; 43 44 public class ModuleFileParserTest { 45 public static void main(String[] args) throws Exception { 46 if (args.length != 1) { 47 usage(); 48 return; 49 } 50 File jmod = new File(args[0]); 51 52 list(jmod); 53 getClasses(jmod); 54 getOneClass(jmod); 55 getlibs(jmod); 56 verify(jmod); 57 } 58 59 /* 60 * List the sections of the given module file. 61 */ 62 static void list(File jmod) { 63 out.format("Listing sections of %s%n", jmod); 64 65 try (FileInputStream fis = new FileInputStream(jmod)) { 66 ModuleFileParser parser = ModuleFile.newParser(fis); 67 while (parser.skipToNextStartSection()) { 68 SectionHeader header = parser.getSectionHeader(); 69 SectionType type = header.getType(); 70 switch (type) { 71 case MODULE_INFO: 72 out.format("%s section, %s%n", type, header); break; 73 case SIGNATURE: 74 out.format("%s section, %s%n", type, header); break; 75 case CLASSES: 76 out.format("%s section, %s%n", type, header); break; 77 case RESOURCES: 78 out.format("%s section, %s%n", type, header); break; 79 case NATIVE_LIBS: 80 out.format("%s section, %s%n", type, header); break; 81 case NATIVE_CMDS: 82 out.format("%s section, %s%n", type, header); break; 83 case CONFIG: 84 out.format("%s section, %s%n", type, header); break; 85 default: 86 throw new IOException("Unknown section type"); 87 } 88 } 89 } catch (IOException | ModuleFileParserException e) { 90 out.format("%s%n", e); 91 } 92 } 93 94 /* 95 * Extract classes from the given module file. 96 */ 97 static void getClasses(File jmod) { 98 out.format("Reading classes from %s%n", jmod); 99 100 try (FileInputStream fis = new FileInputStream(jmod)) { 101 ModuleFileParser parser = ModuleFile.newParser(fis); 102 while (parser.skipToNextStartSection()) { 103 SectionHeader header = parser.getSectionHeader(); 104 if (header.getType() == CLASSES) { 105 out.format("Has %s section%n", header.getType()); 106 Iterator<Entry<String,InputStream>> classes = parser.getClasses(); 107 while (classes.hasNext()) { 108 Entry<String,InputStream> entry = classes.next(); 109 try (OutputStream os = createFile(jmod.getName() + 110 File.separator + "classes" + File.separator + 111 entry.getKey())) { 112 copyStream(entry.getValue(), os); 113 } 114 } 115 break; 116 } 117 } 118 } catch (IOException | ModuleFileParserException e) { 119 out.format("%s%n", e); 120 } 121 } 122 123 /* 124 * Extracts the first class from the CLASSES section of the given module file. 125 */ 126 static void getOneClass(File jmod) { 127 out.format("Reading one classes from %s%n", jmod); 128 129 try (FileInputStream fis = new FileInputStream(jmod)) { 130 ModuleFileParser parser = ModuleFile.newParser(fis); 131 while (parser.skipToNextStartSection()) { 132 SectionHeader header = parser.getSectionHeader(); 133 if (header.getType() == CLASSES) { 134 out.format("Has %s section%n", header.getType()); 135 Iterator<Entry<String,InputStream>> classes = parser.getClasses(); 136 if (classes.hasNext()) { 137 Entry<String,InputStream> entry = classes.next(); 138 try (OutputStream os = createFile(jmod.getName() + 139 File.separator + "classes" + File.separator + 140 entry.getKey())) { 141 copyStream(entry.getValue(), os); 142 } 143 } 144 break; 145 } 146 } 147 } catch (IOException | ModuleFileParserException e) { 148 out.format("%s%n", e); 149 } 150 } 151 152 /* 153 * Extract the native libs from the given module file. 154 */ 155 static void getlibs(File jmod) { 156 out.format("Reading libs from %s%n", jmod); 157 158 try (FileInputStream fis = new FileInputStream(jmod)) { 159 ModuleFileParser parser = ModuleFile.newParser(fis); 160 while (parser.skipToNextStartSection()) { 161 SectionHeader header = parser.getSectionHeader(); 162 if (header.getType() == NATIVE_LIBS) { 163 out.format("Has %s section%n", header.getType()); 164 while (parser.skipToNextStartSubSection()) { 165 SubSectionFileHeader subHeader = parser.getSubSectionFileHeader(); 166 String path = subHeader.getPath(); 167 try (OutputStream os = createFile(jmod.getName() + 168 File.separator + "lib" + File.separator + path)) { 169 copyStream(parser.getContentStream(), os); 170 } 171 } 172 break; 173 } 174 } 175 } catch (IOException | ModuleFileParserException e) { 176 out.format("%s%n", e); 177 } 178 } 179 180 /* 181 * Verify the integraty of the given module file. 182 */ 183 static void verify(File jmod) { 184 out.format("Verifying %s%n", jmod); 185 186 try (FileInputStream fis = new FileInputStream(jmod)) { 187 ModuleFileParser parser = ModuleFile.newParser(fis); 188 while (parser.hasNext()) { 189 Event event = parser.next(); 190 if (event == END_SECTION) { 191 SectionHeader header = parser.getSectionHeader(); 192 // compare hash in header to actual hash of content 193 if (!Arrays.equals(header.getHash(), parser.getHash())) 194 throw new RuntimeException("Verifying hash failed for " 195 + header.getType()); 196 } else if (event == END_FILE) { 197 // compare hash in header to actual hash of file content 198 if (!Arrays.equals(parser.fileHeader().getHash(), parser.getHash())) 199 throw new RuntimeException("Verifying hash failed for File"); 200 } 201 } 202 } catch (IOException | ModuleFileParserException e) { 203 out.format("%s%n", e); 204 } 205 } 206 207 /* 208 * Helper method to create sub directories (if necessary) 209 */ 210 private static OutputStream createFile(String pathName) throws IOException { 211 File path = new File(pathName); 212 File parent = new File(path.getParent()); 213 if (!parent.exists()) 214 parent.mkdirs(); 215 FileOutputStream fos = new FileOutputStream(path); 216 return new BufferedOutputStream(fos); 217 } 218 219 private static void copyStream(InputStream in, OutputStream out) 220 throws IOException 221 { 222 byte[] buf = new byte[8192]; 223 int read = 0; 224 while ((read = in.read(buf)) > 0) 225 out.write(buf, 0, read); 226 } 227 228 private static void usage() { 229 out.format("Usage: java ModuleFileTest <module-file>%n"); 230 } 231 }