src/share/classes/sun/module/tools/JRepo.java

Print this page

        

*** 28,53 **** import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.module.*; import java.security.AccessController; import java.text.DateFormat; import java.util.Arrays; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; ! import sun.module.JamUtils; import sun.module.repository.RepositoryConfig; import sun.security.action.GetPropertyAction; import sun.tools.jar.CommandLine; /** --- 28,58 ---- import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; + import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.module.*; + import java.module.annotation.ImportPolicyClass; import java.security.AccessController; + import java.security.PrivilegedAction; import java.text.DateFormat; import java.util.Arrays; import java.util.ArrayList; + import java.util.Collections; import java.util.Date; import java.util.HashMap; + import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; ! import java.util.Set; import sun.module.repository.RepositoryConfig; import sun.security.action.GetPropertyAction; import sun.tools.jar.CommandLine; /**
*** 75,90 **** private static final Map<String, Command> commands = new LinkedHashMap<String, Command>(); /** Usage message created from each command's usage. */ private static String usage = null; ! /** Format for module name & version. */ private static final String MAIFormat = "%-20s %-20s"; ! /** Format for additional/verbose module information. */ private static final String MAIFormatVerbose = " %-9s %-7s %-17s %s"; /** String containing column headings for name & version. */ private static final String maiHeading; /** String containing column headings for additional/verbose module information. */ private static final String maiHeadingVerbose; --- 80,101 ---- private static final Map<String, Command> commands = new LinkedHashMap<String, Command>(); /** Usage message created from each command's usage. */ private static String usage = null; ! /** Format for ModuleArchiveInfo name & version. */ private static final String MAIFormat = "%-20s %-20s"; ! /** Format for additional/verbose ModuleArchiveInfo details. */ private static final String MAIFormatVerbose = " %-9s %-7s %-17s %s"; + /** Format for ModuleDefinition name & version. */ + private static final String MDFormat = "%s-%s"; + + /** Format for additional/verbose ModuleDefinition details. */ + private static final String MDFormatVerbose = " %s"; + /** String containing column headings for name & version. */ private static final String maiHeading; /** String containing column headings for additional/verbose module information. */ private static final String maiHeadingVerbose;
*** 96,105 **** --- 107,122 ---- private static final Flag verboseFlag = new Flag('v'); /** Location of repository; if not given uses system repository. */ private static final RepositoryFlag repositoryFlag = new RepositoryFlag(); + /** Indicates dependencies command should display info on core modules. */ + private static final Flag javaseFlag = new Flag('j'); + + /** Provides way to specify platform binding fo dependencies command. */ + private static final BindingFlag bindingFlag = new BindingFlag(); + /** Contains the flags that are common to all commands. */ private static final HashMap<Character, Flag> commonFlags = new HashMap<Character, Flag>(); static { repositoryFlag.register(commonFlags);
*** 115,131 **** --- 132,153 ---- pw.printf(MAIFormat, "Name", "Version"); // XXX i18n pw.printf(MAIFormatVerbose, "Platform", "Arch", "Modified", "Filename"); // XXX i18n maiHeadingVerbose = sw.toString(); } + public JRepo(OutputStream out, OutputStream err, BufferedReader reader) { + this(new PrintStream(out), new PrintStream(err), reader); + } + public JRepo(PrintStream out, PrintStream err, BufferedReader reader) { msg = new Messenger("jrepo", out, err, reader); synchronized(commands) { if (commands.isEmpty()) { new ListCommand().register(commands); new InstallCommand().register(commands); new UninstallCommand().register(commands); + new DependenciesCommand().register(commands); } } reset(); }
*** 185,195 **** rc = Modules.newLocalRepository( RepositoryConfig.getSystemRepository(), "jrepo", f.getCanonicalFile()); } else { ! throw new IOException("Cannot access repository at " + repositoryLocation); } } } return rc; } --- 207,218 ---- rc = Modules.newLocalRepository( RepositoryConfig.getSystemRepository(), "jrepo", f.getCanonicalFile()); } else { ! throw new IOException("Cannot access repository at " // XXX i18n ! + repositoryLocation); } } } return rc; }
*** 258,279 **** return cmd; } /** Returns a user-grokkable description of the repository. */ ! private String getRepositoryText(Repository repo) { String rc; URL u = repo.getSourceLocation(); if (u == null) { rc = "Bootstrap repository"; } else { ! rc = "Repository " + u.toExternalForm(); } return rc; } ! private String getMAIText(ModuleArchiveInfo mai) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.printf(MAIFormat, mai.getName(), mai.getVersion()); if (verboseFlag.isEnabled()) { long t = mai.getLastModified(); --- 281,302 ---- return cmd; } /** Returns a user-grokkable description of the repository. */ ! private static String getRepositoryText(Repository repo) { String rc; URL u = repo.getSourceLocation(); if (u == null) { rc = "Bootstrap repository"; } else { ! rc = "Repository '" + repo.getName() + "' at " + u.toExternalForm(); } return rc; } ! private static String getMAIText(ModuleArchiveInfo mai) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.printf(MAIFormat, mai.getName(), mai.getVersion()); if (verboseFlag.isEnabled()) { long t = mai.getLastModified();
*** 289,306 **** ); } return sw.toString(); } void usageError() { usageError(msg); } static void usageError(Messenger msg) { if (usage == null) { StringBuilder ub = new StringBuilder( ! "Usage: jrepo <command>\nwhere <command> includes:"); for (Command c : commands.values()) { String u = c.usage(); if (u != null) { ub.append("\n ").append(c.usage()); } --- 312,345 ---- ); } return sw.toString(); } + private static String getMText(Module m) { + return getMDText(m.getModuleDefinition()); + } + + private static String getMDText(ModuleDefinition md) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.printf(MDFormat, md.getName(), md.getVersion()); + if (verboseFlag.isEnabled()) { + URL srcLoc = md.getRepository().getSourceLocation(); + pw.printf(MDFormatVerbose, + srcLoc == null ? "bootstrap" : srcLoc.toString()); + } + return sw.toString(); + } + void usageError() { usageError(msg); } static void usageError(Messenger msg) { if (usage == null) { StringBuilder ub = new StringBuilder( ! "Usage: jrepo <command>\nwhere <command> includes:"); // XXX i18n for (Command c : commands.values()) { String u = c.usage(); if (u != null) { ub.append("\n ").append(c.usage()); }
*** 311,321 **** } /** * Represents a flag given on the command line. Flags always are 2 * characters long, and start with a '-'. They can have additional ! * associated arguments (cf RepositoryFlag). */ private static class Flag { private final char name; private boolean enabled = false; --- 350,360 ---- } /** * Represents a flag given on the command line. Flags always are 2 * characters long, and start with a '-'. They can have additional ! * associated arguments (cf {@link #RepositoryFlag}). */ private static class Flag { private final char name; private boolean enabled = false;
*** 334,344 **** char getName() { return name; } /** @return the number of arguments consumed by this Flag. */ ! int set(String[] args, int pos) { enabled = true; return 1; } void reset() { --- 373,383 ---- char getName() { return name; } /** @return the number of arguments consumed by this Flag. */ ! int set(String[] args, int pos) throws IllegalArgumentException { enabled = true; return 1; } void reset() {
*** 359,384 **** RepositoryFlag() { super('r'); } ! int set(String[] args, int pos) { int rc = super.set(args, pos); location = args[pos + 1]; return rc + 1; } String getLocation() { return location; } void reset() { super.reset(); location = null; } } /* * Command types: An abstract base class, plus one concrete class for * each Command. */ --- 398,462 ---- RepositoryFlag() { super('r'); } ! @Override ! int set(String[] args, int pos) throws IllegalArgumentException { int rc = super.set(args, pos); location = args[pos + 1]; return rc + 1; } String getLocation() { return location; } + @Override void reset() { super.reset(); location = null; } } + private static class BindingFlag extends Flag { + String platform; + String arch; + + BindingFlag() { + super('b'); + } + + @Override + int set(String[] args, int pos) throws IllegalArgumentException { + int rc = super.set(args, pos); + String[] binding = args[pos + 1].split("-"); + if (binding.length != 2) { + throw new IllegalArgumentException( + "Must 2 and only 2 elements for platform-arch"); + } + platform = binding[0]; + arch = binding[1]; + return rc + 1; + } + + String getPlatform() { + return platform; + } + + String getArch() { + return arch; + } + + @Override + void reset() { + super.reset(); + platform = null; + arch = null; + } + } + /* * Command types: An abstract base class, plus one concrete class for * each Command. */
*** 422,432 **** if (f != null) { int numConsumed = f.set(args, i); i += numConsumed; // Increases at each iteration. rc += numConsumed; // Increases only when the arg is a flag. } else { ! throw new IllegalArgumentException("unrecognized flag: " + args[i]); } } else { i++; } } --- 500,511 ---- if (f != null) { int numConsumed = f.set(args, i); i += numConsumed; // Increases at each iteration. rc += numConsumed; // Increases only when the arg is a flag. } else { ! throw new IllegalArgumentException("unrecognized flag: " // XXX i18n ! + args[i]); } } else { i++; } }
*** 439,448 **** --- 518,528 ---- /** Returns a usage string describing this command, or null if the * command is a synonym for another command. */ abstract String usage(); + @Override public String toString() { return name; } /** * RepositoryVisitor types walk a parent chain of repositories, invoking * {@code doit} in each one. The abstract base class provides the recursion;
*** 451,463 **** * and the system repository is last. */ abstract class RepositoryVisitor { abstract void doit(Repository repo, Messenger msg); ! void doBefore(Messenger msg) { } ! void doAfter(Messenger msg) { } final void run(Repository repo, Messenger msg) { visit(repo, msg); } --- 531,543 ---- * and the system repository is last. */ abstract class RepositoryVisitor { abstract void doit(Repository repo, Messenger msg); ! void preVisit(Messenger msg) { } ! void postVisit(Messenger msg) { } final void run(Repository repo, Messenger msg) { visit(repo, msg); }
*** 464,480 **** private final void visit(Repository repo, Messenger msg) { Repository parent = parentFlag.isEnabled() ? repo.getParent() : null; if (parent != null) { visit(parent, msg); } ! doBefore(msg); doit(repo, msg); ! doAfter(msg); } } } /** Installs a JAM into a repository. */ private class InstallCommand extends Command { private String jamName; InstallCommand() { --- 544,726 ---- private final void visit(Repository repo, Messenger msg) { Repository parent = parentFlag.isEnabled() ? repo.getParent() : null; if (parent != null) { visit(parent, msg); } ! preVisit(msg); doit(repo, msg); ! postVisit(msg); } } } + + /** Lists dependencies of a module. */ + private class DependenciesCommand extends Command { + @SuppressWarnings("unchecked") + private final Map<Character, Flag> myFlags = (Map<Character, Flag>) commonFlags.clone(); + + private String name; + private Version version; + + // For printing module name, version. + private String moduleString; + + DependenciesCommand() { + super("dependencies"); + javaseFlag.register(myFlags); + bindingFlag.register(myFlags); + } + + @Override + void reset() { + javaseFlag.reset(); + bindingFlag.reset(); + } + + @Override + int parseFlags(String[] args, Map<Character, Flag> flags) { + return super.parseFlags(args, myFlags); + } + + boolean parseArgs(String[] args, Messenger msg) { + if (args.length > 0) { + name = args[0]; + } + if (args.length > 1) { + try { + version = Version.valueOf(args[1]); + } catch (IllegalArgumentException ex) { + return false; + } + } + if (args.length > 2) { + return false; + } + + if (DEBUG) debug("name: " + name + " ver: " + version + + " plat: " + bindingFlag.getPlatform() + + " arch: " + bindingFlag.getArch()); + return true; + } + + boolean run(Repository repo, Messenger msg) { + boolean rc = true; + if (name != null) { + VersionConstraint vc = (version == null + ? VersionConstraint.DEFAULT + : version.toVersionConstraint()); + printHeader(name, vc); + rc = depend(repo, name, vc, + bindingFlag.getPlatform(), bindingFlag.getArch()); + printTrailer(null); + } else { + for (ModuleArchiveInfo mai : repo.list()) { + reset(); + String maiName = mai.getName(); + VersionConstraint vc = mai.getVersion().toVersionConstraint(); + printHeader(maiName, vc); + rc &= depend(repo, maiName, vc, + mai.getPlatform(), mai.getArch()); + printTrailer("\n"); + } + } + return rc; + } + + boolean depend(Repository repo, String name, VersionConstraint constraint, + String platform, String arch) { + ImportTraverser iv = new JRepoImportTraverser(msg); + try { + iv.visit(repo, name, constraint, platform, arch); + for (Module dep : iv) { + // If any modules were found, traversal was successful + return true; + } + if (verboseFlag.isEnabled()) { + msg.error("Cannot find module " + name + " in " // XXX i18n + + getRepositoryText(repo)); + } + return false; + } catch (ModuleInitializationException ex) { + msg.error("Cannot instantiate module for " + name // XXX i18n + + ": " + ex); + return false; + } + } + + + void printHeader(String name, VersionConstraint vc) { + if (verboseFlag.isEnabled()) { + msg.println("Dependencies for " // XXXi18n + + name + "-" + vc + ":"); + } + } + + void printTrailer(String s) { + if (verboseFlag.isEnabled()) { + msg.print(s); + } + } + + // TBD support platform binding. Ideally, want to allow specifying + // version, or binding, or both. + String usage() { + return "dependencies [-v] [-r repositoryLocation] [-b platform-arch]"// XXX i18n + + " [moduleName [moduleVersion] ]\n" + + " Lists all modules on which identified modules depend.\n" + + " If no moduleName is given, lists dependencies of all" + + " modules in the repository."; + } + } + + + private static class JRepoImportTraverser extends ImportTraverser { + private final Messenger msg; + + private String indent = ""; + + JRepoImportTraverser(Messenger msg) { + this.msg = msg; + } + + @Override + protected void init(Module m) { + printModule(m); + } + + @Override + protected boolean preVisit(Module m) { + if (javaseFlag.isEnabled() == false + && "java.se".equals(m.getModuleDefinition().getName())) { + return false; + } else { + indent += " "; + return true; + } + } + + @Override + protected void visit(Module m) { + printModule(m); + } + + @Override + protected void postVisit(Module m) { + if (javaseFlag.isEnabled() == false + && "java.se".equals(m.getModuleDefinition().getName())) { + // empty + } else { + indent = indent.substring(4); + } + } + + void printModule(Module m) { + msg.println(indent + getMText(m)); + } + } + /** Installs a JAM into a repository. */ private class InstallCommand extends Command { private String jamName; InstallCommand() {
*** 526,536 **** } return false; } String usage() { ! return "install [-v] -r repositoryLocation jamFile | jamURL\n" + " installs a module into a repository"; } } /** Uninstalls a module from a repository. */ --- 772,782 ---- } return false; } String usage() { ! return "install [-v] -r repositoryLocation jamFile | jamURL\n" // XXX i18n + " installs a module into a repository"; } } /** Uninstalls a module from a repository. */
*** 552,568 **** --- 798,816 ---- super("uninstall"); forceFlag.register(myFlags); interactiveFlag.register(myFlags); } + @Override void reset() { version = null; platformBinding = null; forceFlag.reset(); interactiveFlag.reset(); } + @Override int parseFlags(String[] args, Map<Character, Flag> flags) { return super.parseFlags(args, myFlags); } boolean parseArgs(String[] args, Messenger msg) {
*** 645,655 **** } return rc; } String usage() { ! return "uninstall [-v] [-f | -i] -r repositoryLocation moduleName [moduleVersion] [modulePlatformBinding]\n" + " removes a module from a repository, along with associated files."; } /** Uninstall the ModuleArchiveInfo from the Repository. */ private boolean uninstall(Repository repo, ModuleArchiveInfo mai, Messenger msg) { --- 893,904 ---- } return rc; } String usage() { ! return "uninstall [-v] [-f | -i] -r repositoryLocation moduleName"// XXX i18n ! + " [moduleVersion] [modulePlatformBinding]\n" + " removes a module from a repository, along with associated files."; } /** Uninstall the ModuleArchiveInfo from the Repository. */ private boolean uninstall(Repository repo, ModuleArchiveInfo mai, Messenger msg) {
*** 657,669 **** if (DEBUG) debug("Uninstalling " + getMAIText(mai)); try { rc = repo.uninstall(mai); if (verboseFlag.isEnabled()) { if (rc) { ! msg.println("Uninstalled " + getMAIText(mai)); } else { ! msg.error("Failed to uninstall " + getMAIText(mai)); } } } catch (Exception ex) { msg.error("Exception while uninstalling " + getInfo() + ": " + ex.getMessage()); --- 906,918 ---- if (DEBUG) debug("Uninstalling " + getMAIText(mai)); try { rc = repo.uninstall(mai); if (verboseFlag.isEnabled()) { if (rc) { ! msg.println("Uninstalled " + getMAIText(mai)); // XXX i18n } else { ! msg.error("Failed to uninstall " + getMAIText(mai)); // XXX i18n } } } catch (Exception ex) { msg.error("Exception while uninstalling " + getInfo() + ": " + ex.getMessage());
*** 767,780 **** --- 1016,1031 ---- ListCommand() { super("list"); parentFlag.register(myFlags); } + @Override void reset() { parentFlag.reset(); } + @Override int parseFlags(String[] args, Map<Character, Flag> flags) { return super.parseFlags(args, myFlags); } boolean parseArgs(String[] args, Messenger msg){
*** 793,812 **** ListRepositoryVisitor visitor = new ListRepositoryVisitor(); visitor.run(repo, msg); boolean found = visitor.wasFound(); if (verboseFlag.isEnabled() && !found) { if (moduleName != null) { ! msg.error("Could not find module name starting with '" + moduleName + "'"); } else { ! msg.error("Could not find any modules"); } } return found; } String usage() { ! return "list [-v] [-p] [-r repositoryLocation] moduleName\n" + " lists the modules in the repository"; } class ListRepositoryVisitor extends RepositoryVisitor { private boolean found = false; --- 1044,1066 ---- ListRepositoryVisitor visitor = new ListRepositoryVisitor(); visitor.run(repo, msg); boolean found = visitor.wasFound(); if (verboseFlag.isEnabled() && !found) { if (moduleName != null) { ! msg.error("Could not find module name starting with '"// ! // XXX i18n ! + moduleName + "'"); } else { ! msg.error("Could not find any modules"); // XXX i18n } } return found; } String usage() { ! return "list [-v] [-p] [-r repositoryLocation] moduleName\n"// ! // XXX i18n + " lists the modules in the repository"; } class ListRepositoryVisitor extends RepositoryVisitor { private boolean found = false;
*** 813,822 **** --- 1067,1081 ---- boolean wasFound() { return found; } void doit(Repository repo, Messenger msg) { boolean printedHeader = false; + List<ModuleArchiveInfo> maiList = repo.list(); + if (maiList.size() == 0 && verboseFlag.isEnabled()) { + msg.println(getRepositoryText(repo)); + msg.println(" empty"); + } else { for (ModuleArchiveInfo mai : repo.list()) { if (moduleName == null || mai.getName().startsWith(moduleName)) { if (!printedHeader) { msg.println(getRepositoryText(repo)); msg.println(verboseFlag.isEnabled() ? maiHeadingVerbose : maiHeading);
*** 824,832 **** --- 1083,1092 ---- } msg.println(getMAIText(mai)); found = true; } } + } } } } }