[modules-dev] Initial repository management tool

Dave Bristor David.Bristor at Sun.COM
Fri Jul 13 14:48:23 PDT 2007


Stanley M. Ho wrote:
> Hi Dave,
> 
> Looks like a good start. Several comments inline:
> 
> - src/share/classes/sun/module/tools/ToolBase.java
> 
> 35 public class ToolBase {
> 
> Should be package private.

Fixed.

> 
> - src/share/classes/sun/module/tools/JRepo.java
> 
> Remove empty line at #43 and #46.

Fixed.

> 
>   76             usage = "Usage: jrepo <cmd>, where cmd is follows one 
> of the patterns below";
> 
> Perhaps "command" instead of "cmd".

Fixed.

> 
>  68     private static final Map<String, Command> commands = new 
> LinkedHashMap<String, Command>();
>   75         if (usage == null) {
>   76             usage = "Usage: jrepo <cmd>, where cmd is follows one 
> of the patterns below";
>   77             new ListCommand();
>   78             new FindCommand();
>   79             new QueryCommand();
>   80         }
>  167             commands.put(name, this);
>  168             String u = usage();
>  169             if (u != null) {
>  170                 usage += "\n\t" + usage();
>  171             }
>  330         for (Map.Entry<String, Command> entry : commands.entrySet()) {
>  331             if (entry.getKey().startsWith(args[0])) {
>  332                 cmd = entry.getValue();
>  333                 break;
>  334             }
>  335         }
>  416     void usageError() {
>  417         error(usage);
>  418     }
> 
> I don't like the idea of having the Command constructor to bring side 
> effect to "usage" and "commands" in the outer class. I think removing 
> these side effects could simply the code and make it more readable, e.g.
> 
> private state final List<Command> commands = new ArrayList<Command>();
> ...
>     commands.add(new ListCommand());
>     commands.add(new FindCommand());
>     commands.add(new QueryCommand());
> ...
> for (Command command : commands) {
>    if (command.getName().startsWith(args[0])) {
>         cmd = entry.getValue();
>         break;
>    }
> }
> ...
> private void usageError() {
>    StringBuilder builder = new StringBuilder();
>    builder.append("Usage: jrepo <command>, where command follows one of 
> the patterns below\n");
>    for (Command command : commands) {
>        builder.append(command.getUsage());
>         builder.append("\n");
>    }
>    error(builder.toString());
> }

I refactored it all slightly differently, but definitely removed the 
side-effect-ness.

> 
>  165     abstract class Command {
>  223     class ListCommand extends Command {
>  261     class FindCommand extends Command {
>  303     class QueryCommand extends FindCommand {
> 
> These classes should be private static if possible.

private: fixed.

static: harder: They're making use of usageError, which is inherited from 
Toolbase...the output methods in ToolBase depend on being initialized with 
streams during construction.  So for now, just private abstract.

>  103         if (repo == null) {
>  104             err.println("can't access repository " + 
> repositoryLocation);
>  105             return false;
>  106         }
> 
> Is this check really necessary? I would have assumed the method has 
> already returned if there was exception in #95-#100.

Fixed.

> I'm surprised we have to configure the metadata directory in the 
> repository in #139-#145. I think the URLRepository implementation should 
> do this automatically by default if no metadata directory is specified.

If not configured, it will do so automatically.  But currently, the 
automatically determined directory is always the same one, and so might result 
in inadvertent sharing or other bizarre behavior.  Probably, the default 
directories for the repository classes should be based on temporary names.  If 
that seems right to you, I'll file a bug for it and remove the configuration 
in JRepo.

> 
>  246                 List<ModuleArchiveInfo> installed = repo.list();
>  247                 for (ModuleArchiveInfo mai : installed)
> 
> Should combine into
> 
>     for (ModuleArchiveInfo mai : repo.list())

Fixed.

> 
>  308         String usage() { return null; }
> 
> Should either not override the method, or return usage string specific 
> for "query".

Not really: by explicitly returning null, find and query have the same usage 
String, provided by find.

> The getRepositoryText method looks like something Repository.toString() 
> should provide. If not, at least we could clean it up as:
> 
>  private String getRepositoryText(Repository repo) {
>      URL u = repo.getSourceLocation();
>         if (u == null) {
>             return "Bootstrap repository";
>         } else {
>         return "Repository " + u.toExternalForm();
>     }
>  }

I prefer to avoid multiple returns, hence the current approach.  Not a big 
deal here; I can change it if it's important.  Also, I propose to move this 
method as you suggest, but want to keep that separate fromt he current 
examination of JRepo.

One more thing, I renamed "Curser" to "RepositoryVisitor", and changed the 
method name recurse -> visit.  I just couldn't think of the right name at first!

Do you have any suggestions for writing tests?  I've written a very basic one 
for now.  Perhaps in the fullness of time, SQE can do a much better job.

Webrev updated, includes test

http://javaweb.sfbay/java/jdk/ws/libs/rev/6559117/


Thanks,
	Dave

> 
> That's it for now.
> 
> - Stanley
> 



More information about the modules-dev mailing list