1 /*
   2  * Copyright (c) 2010, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package org.openjdk.jigsaw.cli;
  27 
  28 import java.lang.module.*;
  29 import java.io.*;
  30 import java.util.*;
  31 import java.util.regex.*;
  32 
  33 import static java.lang.System.out;
  34 import static java.lang.System.err;
  35 
  36 import org.openjdk.jigsaw.*;
  37 import org.openjdk.internal.joptsimple.*;
  38 
  39 
  40 /**
  41  * Commands shared by multiple CLIs
  42  */
  43 
  44 class Commands {
  45 
  46     private static final JigsawModuleSystem jms
  47         = JigsawModuleSystem.instance();
  48 
  49     private static void formatCommaList(PrintStream out,
  50                                         String prefix,
  51                                         Collection<?> list)
  52     {
  53         if (list.isEmpty())
  54             return;
  55         out.format("  %s", prefix);
  56         boolean first = true;
  57         for (Object ob : list) {
  58             if (first) {
  59                 out.format(" %s", ob);
  60                 first = false;
  61             } else {
  62                 out.format(", %s", ob);
  63             }
  64         }
  65         out.format("%n");
  66     }
  67 
  68     private static void formatModuleView(PrintStream out,
  69                                          ModuleView view,
  70                                          String indent) {
  71         formatCommaList(out, indent + "provides",
  72                         view.aliases());
  73         formatCommaList(out, indent + "permits",
  74                         view.permits());
  75         Map<String,Set<String>> services = view.services();
  76         for (Map.Entry<String,Set<String>> entry: services.entrySet()) {
  77             String sn = entry.getKey();
  78             for (String impl: entry.getValue()) {
  79                 out.format("%s  provides service %s with %s%n", indent, sn, impl);
  80             }
  81         }
  82 
  83         if (!view.exports().isEmpty()) {
  84             out.format("  %sexports%n", indent);
  85             Set<String> exports = new TreeSet<>(view.exports());
  86             for (String pn : exports) {
  87                 out.format("  %s  %s%n", indent, pn);
  88             }
  89         }
  90     }
  91 
  92     protected static void formatModule(PrintStream out, ModuleInfo mi,
  93                                        boolean verbose)

  94     {




















  95         // print module and its views
  96         out.format("%s%n", mi.id());
  97 
  98         if (verbose) {
  99             for (ViewDependence d : mi.requiresModules()) {
 100                 out.format("  %s%n", d);
 101             }
 102             for (ServiceDependence sd: mi.requiresServices()) {
 103                 out.format("  %s%n", sd);
 104             }
 105             formatModuleView(out, mi.defaultView(), "");
 106 
 107             for (ModuleView mv : mi.views()) {
 108                 if (mv == mi.defaultView())
 109                     continue;
 110 
 111                 out.format("  view %s%n", mv.id().name());
 112                 formatModuleView(out, mv, "  ");
 113             }
 114         }
 115     }
 116 
 117     private static void listCommand(Catalog cat, ModuleIdQuery midq,
 118                                     boolean parents, boolean verbose)
 119         throws Command.Exception
 120     {
 121         int n = 0;
 122         try {
 123             List<ModuleId> mids;
 124             if (midq == null) {
 125                 mids = parents ? cat.listDeclaringModuleIds()
 126                                : cat.listLocalDeclaringModuleIds();
 127             } else {
 128                 List<ModuleId> list = parents ? cat.listModuleIds()
 129                                               : cat.listLocalModuleIds();
 130                 mids = new ArrayList<>();
 131                 for (ModuleId mid : list) {
 132                     if (midq.matches(mid))
 133                         mids.add(mid);
 134                 }
 135             }
 136             for (ModuleId mid : mids) {
 137                 if (verbose)
 138                     out.format("%n");
 139                 formatModule(out, cat.readModuleInfo(mid), verbose);
 140                 n++;
 141             }
 142         } catch (IOException x) {
 143             throw new Command.Exception(x);
 144         }
 145         if (verbose && n > 0)
 146             out.format("%n");
 147     }
 148 
 149     private static Catalog compose(ModuleIdQuery midq,
 150                                    List<? extends Catalog> cats)
 151         throws IOException
 152     {
 153 
 154         final Set<ModuleId> modules = new HashSet<>();
 155         final Map<ModuleId,ModuleInfo> mods = new HashMap<>();
 156         for (Catalog c : cats) {
 157             List<ModuleId> mids = c.listDeclaringModuleIds();
 158             modules.addAll(mids);
 159             for (ModuleId mid : mids) {
 160                 if (mods.containsKey(mid))
 161                     continue;
 162 
 163                 ModuleInfo mi = c.readModuleInfo(mid);
 164                 for (ModuleView mv : mi.views()) {
 165                     mods.put(mid, mi);
 166                     for (ModuleId alias : mv.aliases()) {
 167                         mods.put(alias, mi);
 168                     }
 169                 }
 170             }
 171         }
 172 
 173         return new Catalog() {
 174 
 175             public String name() { return "composite"; }
 176 
 177             public Catalog parent() { return null; }
 178 
 179             protected void gatherLocalModuleIds(String moduleName,
 180                                                 Set<ModuleId> ids)
 181                 throws IOException
 182             {
 183                 ids.addAll(mods.keySet());
 184             }
 185 
 186             protected void gatherLocalDeclaringModuleIds(Set<ModuleId> mids)
 187                 throws IOException
 188             {
 189                 mids.addAll(modules);
 190             }
 191 
 192             protected ModuleInfo readLocalModuleInfo(ModuleId mid)
 193                 throws IOException
 194             {
 195                 return mods.get(mid);
 196             }
 197 
 198         };
 199 
 200     }
 201 
 202     // ## There must be a better way to do this!
 203 
 204     static class ListLibrary extends Command<SimpleLibrary> {
 205         protected void go(SimpleLibrary lib)
 206             throws Command.Exception
 207         {
 208             ModuleIdQuery midq;
 209             if (hasArg())
 210                 midq = jms.parseModuleIdQuery(takeArg());
 211             else
 212                 midq = null;
 213             finishArgs();
 214             boolean parents = opts.has("p");
 215             Catalog cat = lib;
 216             try {
 217                 if (opts.has("R"))
 218                     cat = compose(midq, lib.repositoryList().repositories());
 219             } catch (IOException x) {
 220                 throw new Command.Exception(x);
 221             }
 222             listCommand(cat, midq, parents, verbose);
 223         }
 224     }
 225 
 226     static class ListRepository extends Command<Repository> {
 227         protected void go(Repository repo)
 228             throws Command.Exception
 229         {
 230             ModuleIdQuery midq;
 231             if (hasArg())
 232                 midq = jms.parseModuleIdQuery(takeArg());
 233             else
 234                 midq = null;
 235             finishArgs();
 236             listCommand(repo, midq, false, verbose);
 237         }
 238     }
 239 
 240 }
--- EOF ---