/* * Copyright (c) 2009, 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. */ package com.sun.classanalyzer; import java.io.*; import java.util.*; /** * A simple tool to check module dependencies against a known list of * dependencies. The tool fails (by throwing a RuntimeException) is an * unexpected dependency is detected. */ public class CheckDeps { /** * Represents a dependency from one module to another module. The dependency * may be optional. */ static class Dependency { private final String module; private final String other; private final boolean optional; private Dependency(String module, String other, boolean optional) { this.module = module; this.other = other; this.optional = optional; } String module() { return module; } String other() { return other; } boolean isOptional() { return optional; } /** * Parses a dependency in one of the following forms: * a -> b * [optional] a -> b */ static Dependency fromString(String s) { String[] components = s.split(" "); int count = components.length; if (count != 3 && count != 4) throw new IllegalArgumentException(s); boolean optional = (count == 4); if (optional && !components[0].equals("[optional]")) throw new IllegalArgumentException(s); String arrow = optional ? components[2] : components[1]; if (!arrow.equals("->")) throw new IllegalArgumentException(s); String module = optional ? components[1] : components[0]; String other = optional ? components[3] : components[2]; return new Dependency(module, other, optional); } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (optional) sb.append("[optional] "); sb.append(module); sb.append(" -> "); sb.append(other); return sb.toString(); } } /** * Represents the "tail" */ static class DependencyTail { private final String module; private final boolean optional; DependencyTail(String module, boolean optional) { this.module = module; this.optional = optional; } String module() { return module; } boolean isOptional() { return optional; } } static void usage() { System.out.println("java CheckDeps file1 file2"); System.out.println(" where file1 is the expected dependencies and file2 is"); System.out.println(" the actual dependencies. Both files are assumed to be"); System.out.println(" in modules.summary format (see ClassAnalyzer tool)."); System.out.println(); System.out.println("Example usages:"); System.out.println(" java CheckDeps make/modules/modules.summary " + "$(OUTPUTDIR)/modules.summary"); System.exit(-1); } public static void main(String[] args) throws IOException { if (args.length != 2) usage(); // maps a module to the list of modules that it depends on Map> expected = new HashMap>(); // parse the expected dependencies file Scanner s; s = new Scanner(new FileInputStream(args[0])); try { while (s.hasNextLine()) { Dependency ref = Dependency.fromString(s.nextLine()); if (ref != null) { String module = ref.module(); List list = expected.get(module); if (list == null) { list = new ArrayList(); expected.put(module, list); } list.add(new DependencyTail(ref.other(), ref.isOptional())); } } } finally { s.close(); } // parse the actual dependencies file, checking each dependency // against the expected list. boolean fail = false; s = new Scanner(new FileInputStream(args[1])); try { while (s.hasNextLine()) { Dependency dep = Dependency.fromString(s.nextLine()); // check if this dependency is expected List list = expected.get(dep.module()); DependencyTail tail = null; if (list != null) { for (DependencyTail t: list) { if (t.module().equals(dep.other())) { tail = t; break; } } } if (tail == null) { System.err.println("Unexpected dependency: " + dep); fail = true; } else { // hard dependency when optional dependency is expected if (tail.isOptional() != dep.isOptional()) { if (tail.isOptional()) { System.err.println("Unexpected dependency: " + dep); fail = true; } } } } } finally { s.close(); } if (fail) throw new RuntimeException("Unexpected dependencies found"); } }