--- /dev/null Fri Jun 15 22:43:42 2012 +++ new/test/org/openjdk/jigsaw/ModuleFileParserTest.java Fri Jun 15 22:43:41 2012 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Basic tests for ModuleFileParser + */ + +import java.io.*; +import static java.lang.System.out; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map.Entry; +import org.openjdk.jigsaw.FileConstants.ModuleFile.SectionType; +import static org.openjdk.jigsaw.FileConstants.ModuleFile.SectionType.*; +import org.openjdk.jigsaw.ModuleFile; +import org.openjdk.jigsaw.ModuleFile.SectionHeader; +import org.openjdk.jigsaw.ModuleFile.SubSectionFileHeader; +import org.openjdk.jigsaw.ModuleFileParser; +import org.openjdk.jigsaw.ModuleFileParser.Event; +import static org.openjdk.jigsaw.ModuleFileParser.Event.END_FILE; +import static org.openjdk.jigsaw.ModuleFileParser.Event.END_SECTION; +import org.openjdk.jigsaw.ModuleFileParserException; + +public class ModuleFileParserTest { + public static void main(String[] args) throws Exception { + if (args.length != 1) { + usage(); + return; + } + File jmod = new File(args[0]); + + list(jmod); + getClasses(jmod); + getOneClass(jmod); + getlibs(jmod); + verify(jmod); + } + + /* + * List the sections of the given module file. + */ + static void list(File jmod) { + out.format("Listing sections of %s%n", jmod); + + try (FileInputStream fis = new FileInputStream(jmod)) { + ModuleFileParser parser = ModuleFile.newParser(fis); + while (parser.skipToNextStartSection()) { + SectionHeader header = parser.getSectionHeader(); + SectionType type = header.getType(); + switch (type) { + case MODULE_INFO: + out.format("%s section, %s%n", type, header); break; + case SIGNATURE: + out.format("%s section, %s%n", type, header); break; + case CLASSES: + out.format("%s section, %s%n", type, header); break; + case RESOURCES: + out.format("%s section, %s%n", type, header); break; + case NATIVE_LIBS: + out.format("%s section, %s%n", type, header); break; + case NATIVE_CMDS: + out.format("%s section, %s%n", type, header); break; + case CONFIG: + out.format("%s section, %s%n", type, header); break; + default: + throw new IOException("Unknown section type"); + } + } + } catch (IOException | ModuleFileParserException e) { + out.format("%s%n", e); + } + } + + /* + * Extract classes from the given module file. + */ + static void getClasses(File jmod) { + out.format("Reading classes from %s%n", jmod); + + try (FileInputStream fis = new FileInputStream(jmod)) { + ModuleFileParser parser = ModuleFile.newParser(fis); + while (parser.skipToNextStartSection()) { + SectionHeader header = parser.getSectionHeader(); + if (header.getType() == CLASSES) { + out.format("Has %s section%n", header.getType()); + Iterator> classes = parser.getClasses(); + while (classes.hasNext()) { + Entry entry = classes.next(); + try (OutputStream os = createFile(jmod.getName() + + File.separator + "classes" + File.separator + + entry.getKey())) { + copyStream(entry.getValue(), os); + } + } + break; + } + } + } catch (IOException | ModuleFileParserException e) { + out.format("%s%n", e); + } + } + + /* + * Extracts the first class from the CLASSES section of the given module file. + */ + static void getOneClass(File jmod) { + out.format("Reading one classes from %s%n", jmod); + + try (FileInputStream fis = new FileInputStream(jmod)) { + ModuleFileParser parser = ModuleFile.newParser(fis); + while (parser.skipToNextStartSection()) { + SectionHeader header = parser.getSectionHeader(); + if (header.getType() == CLASSES) { + out.format("Has %s section%n", header.getType()); + Iterator> classes = parser.getClasses(); + if (classes.hasNext()) { + Entry entry = classes.next(); + try (OutputStream os = createFile(jmod.getName() + + File.separator + "classes" + File.separator + + entry.getKey())) { + copyStream(entry.getValue(), os); + } + } + break; + } + } + } catch (IOException | ModuleFileParserException e) { + out.format("%s%n", e); + } + } + + /* + * Extract the native libs from the given module file. + */ + static void getlibs(File jmod) { + out.format("Reading libs from %s%n", jmod); + + try (FileInputStream fis = new FileInputStream(jmod)) { + ModuleFileParser parser = ModuleFile.newParser(fis); + while (parser.skipToNextStartSection()) { + SectionHeader header = parser.getSectionHeader(); + if (header.getType() == NATIVE_LIBS) { + out.format("Has %s section%n", header.getType()); + while (parser.skipToNextStartSubSection()) { + SubSectionFileHeader subHeader = parser.getSubSectionFileHeader(); + String path = subHeader.getPath(); + try (OutputStream os = createFile(jmod.getName() + + File.separator + "lib" + File.separator + path)) { + copyStream(parser.getContentStream(), os); + } + } + break; + } + } + } catch (IOException | ModuleFileParserException e) { + out.format("%s%n", e); + } + } + + /* + * Verify the integraty of the given module file. + */ + static void verify(File jmod) { + out.format("Verifying %s%n", jmod); + + try (FileInputStream fis = new FileInputStream(jmod)) { + ModuleFileParser parser = ModuleFile.newParser(fis); + while (parser.hasNext()) { + Event event = parser.next(); + if (event == END_SECTION) { + SectionHeader header = parser.getSectionHeader(); + // compare hash in header to actual hash of content + if (!Arrays.equals(header.getHash(), parser.getHash())) + throw new RuntimeException("Verifying hash failed for " + + header.getType()); + } else if (event == END_FILE) { + // compare hash in header to actual hash of file content + if (!Arrays.equals(parser.fileHeader().getHash(), parser.getHash())) + throw new RuntimeException("Verifying hash failed for File"); + } + } + } catch (IOException | ModuleFileParserException e) { + out.format("%s%n", e); + } + } + + /* + * Helper method to create sub directories (if necessary) + */ + private static OutputStream createFile(String pathName) throws IOException { + File path = new File(pathName); + File parent = new File(path.getParent()); + if (!parent.exists()) + parent.mkdirs(); + FileOutputStream fos = new FileOutputStream(path); + return new BufferedOutputStream(fos); + } + + private static void copyStream(InputStream in, OutputStream out) + throws IOException + { + byte[] buf = new byte[8192]; + int read = 0; + while ((read = in.read(buf)) > 0) + out.write(buf, 0, read); + } + + private static void usage() { + out.format("Usage: java ModuleFileTest %n"); + } +}