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 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     private static void listCommand(Catalog cat, ModuleIdQuery midq,
  93                                     boolean parents, boolean verbose)
  94         throws Command.Exception
  95     {
  96         int n = 0;
  97         try {
  98             List<ModuleId> mids;
  99             if (midq == null) {
 100                 mids = parents ? cat.listDeclaringModuleIds() : cat.listLocalDeclaringModuleIds();
 101             } else { 
 102                 List<ModuleId> list = parents ? cat.listModuleIds()
 103                                               : cat.listLocalModuleIds();
 104                 mids = new ArrayList<>();
 105                 for (ModuleId mid : list) {
 106                     if (midq.matches(mid))
 107                         mids.add(mid);
 108                 }
 109             }
 110             for (ModuleId mid : mids) {
 111                 ModuleInfo mi = cat.readModuleInfo(mid);
 112                 if (verbose) {
 113                     out.format("%n");
 114                 }
 115 
 116                 // print module and its views
 117                 out.format("%s%n", mi.id());
 118                 n++;
 119                 if (verbose) {
 120                     for (ViewDependence d : mi.requiresModules()) {
 121                         out.format("  %s%n", d);
 122                     }
 123                     for (ServiceDependence sd: mi.requiresServices()) {
 124                         out.format("  %s%n", sd);
 125                     }
 126                     formatModuleView(out, mi.defaultView(), "");
 127 
 128                     for (ModuleView mv : mi.views()) {
 129                         if (mv == mi.defaultView())
 130                             continue;
 131 
 132                         out.format("  view %s%n", mv.id().name());
 133                         formatModuleView(out, mv, "  ");
 134                     }
 135                 }
 136             }


























 137         } catch (IOException x) {
 138             throw new Command.Exception(x);
 139         }
 140         if (verbose && n > 0)
 141             out.format("%n");
 142     }
 143 
 144     private static Catalog compose(ModuleIdQuery midq,
 145                                    List<? extends Catalog> cats)
 146         throws IOException
 147     {
 148 
 149         final Set<ModuleId> modules = new HashSet<>();
 150         final Map<ModuleId,ModuleInfo> mods = new HashMap<>();
 151         for (Catalog c : cats) {
 152             List<ModuleId> mids = c.listDeclaringModuleIds();
 153             modules.addAll(mids);
 154             for (ModuleId mid : mids) {
 155                 if (mods.containsKey(mid))
 156                     continue;
 157                 
 158                 ModuleInfo mi = c.readModuleInfo(mid);
 159                 for (ModuleView mv : mi.views()) {
 160                     mods.put(mid, mi);
 161                     for (ModuleId alias : mv.aliases()) {
 162                         mods.put(alias, mi);
 163                     }
 164                 }
 165             }
 166         }
 167 
 168         return new Catalog() {
 169 
 170             public String name() { return "composite"; }
 171 
 172             public Catalog parent() { return null; }
 173 
 174             protected void gatherLocalModuleIds(String moduleName,
 175                                                 Set<ModuleId> ids)
 176                 throws IOException
 177             {
 178                 ids.addAll(mods.keySet());
 179             }
 180 
 181             protected void gatherLocalDeclaringModuleIds(Set<ModuleId> mids)
 182                 throws IOException
 183             {
 184                 mids.addAll(modules);
 185             }
 186             
 187             protected ModuleInfo readLocalModuleInfo(ModuleId mid)
 188                 throws IOException
 189             {
 190                 return mods.get(mid);
 191             }
 192 
 193         };
 194 
 195     }
 196 
 197     // ## There must be a better way to do this!
 198 
 199     static class ListLibrary extends Command<SimpleLibrary> {
 200         protected void go(SimpleLibrary lib)
 201             throws Command.Exception
 202         {
 203             ModuleIdQuery midq;
 204             if (hasArg())
 205                 midq = jms.parseModuleIdQuery(takeArg());
 206             else
 207                 midq = null;
 208             finishArgs();
 209             boolean parents = opts.has("p");
 210             Catalog cat = lib;
 211             try {
 212                 if (opts.has("R"))
 213                     cat = compose(midq, lib.repositoryList().repositories());
 214             } catch (IOException x) {
 215                 throw new Command.Exception(x);
 216             }
 217             listCommand(cat, midq, parents, verbose);
 218         }
 219     }
 220 
 221     static class ListRepository extends Command<Repository> {
 222         protected void go(Repository repo)
 223             throws Command.Exception
 224         {
 225             ModuleIdQuery midq;
 226             if (hasArg())
 227                 midq = jms.parseModuleIdQuery(takeArg());
 228             else
 229                 midq = null;
 230             finishArgs();
 231             listCommand(repo, midq, false, verbose);
 232         }
 233     }
 234 
 235 }
--- EOF ---