src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsWriter.java
author serb
Sat, 09 Jun 2018 13:33:35 -0700
changeset 50647 a98ff7c2103d
parent 47216 71c04702a3d5
child 52649 e00cf18e2593
permissions -rw-r--r--
6608234: SwingWorker.get throws CancellationException Reviewed-by: psadhukhan, kaddepalli, prr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     1
/*
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     4
 *
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    10
 *
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    15
 * accompanied this code).
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    16
 *
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    20
 *
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    23
 * questions.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    24
 */
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    25
package com.sun.tools.jdeps;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    26
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    27
import static com.sun.tools.jdeps.Analyzer.Type.*;
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    28
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    29
import java.io.IOException;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    30
import java.io.PrintWriter;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    31
import java.io.UncheckedIOException;
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    32
import java.lang.module.ModuleDescriptor.Requires;
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    33
import java.nio.file.Files;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    34
import java.nio.file.Path;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    35
import java.util.Collection;
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    36
import java.util.Comparator;
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    37
import java.util.HashMap;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    38
import java.util.Map;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    39
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    40
public abstract class JdepsWriter {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    41
    public static JdepsWriter newDotWriter(Path outputdir, Analyzer.Type type) {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    42
        return new DotFileWriter(outputdir, type, false, true, false);
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    43
    }
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    44
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    45
    public static JdepsWriter newSimpleWriter(PrintWriter writer,  Analyzer.Type type) {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    46
        return new SimpleWriter(writer, type, false, true);
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    47
    }
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    48
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    49
    final Analyzer.Type type;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    50
    final boolean showProfile;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    51
    final boolean showModule;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    52
41860
906670ff49c7 8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents: 38524
diff changeset
    53
    JdepsWriter(Analyzer.Type type, boolean showProfile, boolean showModule) {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    54
        this.type = type;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    55
        this.showProfile = showProfile;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    56
        this.showModule = showModule;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    57
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    58
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    59
    abstract void generateOutput(Collection<Archive> archives, Analyzer analyzer) throws IOException;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    60
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    61
    static class DotFileWriter extends JdepsWriter {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    62
        final boolean showLabel;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    63
        final Path outputDir;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    64
        DotFileWriter(Path dir, Analyzer.Type type,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    65
                      boolean showProfile, boolean showModule, boolean showLabel) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    66
            super(type, showProfile, showModule);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    67
            this.showLabel = showLabel;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    68
            this.outputDir = dir;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    69
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    70
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    71
        @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    72
        void generateOutput(Collection<Archive> archives, Analyzer analyzer)
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    73
                throws IOException
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    74
        {
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    75
            Files.createDirectories(outputDir);
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    76
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    77
            // output individual .dot file for each archive
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
    78
            if (type != SUMMARY && type != MODULE) {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    79
                archives.stream()
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    80
                        .filter(analyzer::hasDependences)
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    81
                        .forEach(archive -> {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    82
                            Path dotfile = outputDir.resolve(archive.getName() + ".dot");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    83
                            try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile));
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    84
                                 DotFileFormatter formatter = new DotFileFormatter(pw, archive)) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    85
                                analyzer.visitDependences(archive, formatter);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    86
                            } catch (IOException e) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    87
                                throw new UncheckedIOException(e);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    88
                            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    89
                        });
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    90
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    91
            // generate summary dot file
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    92
            generateSummaryDotFile(archives, analyzer);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    93
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    94
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    95
        private void generateSummaryDotFile(Collection<Archive> archives, Analyzer analyzer)
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    96
                throws IOException
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    97
        {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    98
            // If verbose mode (-v or -verbose option),
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
    99
            // the summary.dot file shows package-level dependencies.
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   100
            boolean isSummary =  type == PACKAGE || type == SUMMARY || type == MODULE;
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   101
            Analyzer.Type summaryType = isSummary ? SUMMARY : PACKAGE;
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   102
            Path summary = outputDir.resolve("summary.dot");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   103
            try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary));
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   104
                 SummaryDotFile dotfile = new SummaryDotFile(sw, summaryType)) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   105
                for (Archive archive : archives) {
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   106
                    if (isSummary) {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   107
                        if (showLabel) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   108
                            // build labels listing package-level dependencies
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   109
                            analyzer.visitDependences(archive, dotfile.labelBuilder(), PACKAGE);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   110
                        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   111
                    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   112
                    analyzer.visitDependences(archive, dotfile, summaryType);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   113
                }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   114
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   115
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   116
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   117
        class DotFileFormatter implements Analyzer.Visitor, AutoCloseable {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   118
            private final PrintWriter writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   119
            private final String name;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   120
            DotFileFormatter(PrintWriter writer, Archive archive) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   121
                this.writer = writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   122
                this.name = archive.getName();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   123
                writer.format("digraph \"%s\" {%n", name);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   124
                writer.format("    // Path: %s%n", archive.getPathName());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   125
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   126
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   127
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   128
            public void close() {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   129
                writer.println("}");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   130
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   131
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   132
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   133
            public void visitDependence(String origin, Archive originArchive,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   134
                                        String target, Archive targetArchive) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   135
                String tag = toTag(originArchive, target, targetArchive);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   136
                writer.format("   %-50s -> \"%s\";%n",
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   137
                              String.format("\"%s\"", origin),
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   138
                              tag.isEmpty() ? target
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   139
                                            : String.format("%s (%s)", target, tag));
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   140
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   141
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   142
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   143
        class SummaryDotFile implements Analyzer.Visitor, AutoCloseable {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   144
            private final PrintWriter writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   145
            private final Analyzer.Type type;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   146
            private final Map<Archive, Map<Archive,StringBuilder>> edges = new HashMap<>();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   147
            SummaryDotFile(PrintWriter writer, Analyzer.Type type) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   148
                this.writer = writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   149
                this.type = type;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   150
                writer.format("digraph \"summary\" {%n");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   151
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   152
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   153
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   154
            public void close() {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   155
                writer.println("}");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   156
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   157
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   158
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   159
            public void visitDependence(String origin, Archive originArchive,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   160
                                        String target, Archive targetArchive) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   161
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   162
                String targetName = type == PACKAGE ? target : targetArchive.getName();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   163
                if (targetArchive.getModule().isJDK()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   164
                    Module m = (Module)targetArchive;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   165
                    String n = showProfileOrModule(m);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   166
                    if (!n.isEmpty()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   167
                        targetName += " (" + n + ")";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   168
                    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   169
                } else if (type == PACKAGE) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   170
                    targetName += " (" + targetArchive.getName() + ")";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   171
                }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   172
                String label = getLabel(originArchive, targetArchive);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   173
                writer.format("  %-50s -> \"%s\"%s;%n",
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   174
                        String.format("\"%s\"", origin), targetName, label);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   175
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   176
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   177
            String getLabel(Archive origin, Archive target) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   178
                if (edges.isEmpty())
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   179
                    return "";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   180
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   181
                StringBuilder label = edges.get(origin).get(target);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   182
                return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   183
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   184
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   185
            Analyzer.Visitor labelBuilder() {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   186
                // show the package-level dependencies as labels in the dot graph
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   187
                return new Analyzer.Visitor() {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   188
                    @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   189
                    public void visitDependence(String origin, Archive originArchive,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   190
                                                String target, Archive targetArchive)
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   191
                    {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   192
                        edges.putIfAbsent(originArchive, new HashMap<>());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   193
                        edges.get(originArchive).putIfAbsent(targetArchive, new StringBuilder());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   194
                        StringBuilder sb = edges.get(originArchive).get(targetArchive);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   195
                        String tag = toTag(originArchive, target, targetArchive);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   196
                        addLabel(sb, origin, target, tag);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   197
                    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   198
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   199
                    void addLabel(StringBuilder label, String origin, String target, String tag) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   200
                        label.append(origin).append(" -> ").append(target);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   201
                        if (!tag.isEmpty()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   202
                            label.append(" (" + tag + ")");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   203
                        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   204
                        label.append("\\n");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   205
                    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   206
                };
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   207
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   208
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   209
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   210
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   211
    static class SimpleWriter extends JdepsWriter {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   212
        final PrintWriter writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   213
        SimpleWriter(PrintWriter writer, Analyzer.Type type,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   214
                     boolean showProfile, boolean showModule) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   215
            super(type, showProfile, showModule);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   216
            this.writer = writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   217
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   218
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   219
        @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   220
        void generateOutput(Collection<Archive> archives, Analyzer analyzer) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   221
            RawOutputFormatter depFormatter = new RawOutputFormatter(writer);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   222
            RawSummaryFormatter summaryFormatter = new RawSummaryFormatter(writer);
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   223
            archives.stream()
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   224
                .filter(analyzer::hasDependences)
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   225
                .sorted(Comparator.comparing(Archive::getName))
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   226
                .forEach(archive -> {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   227
                    if (showModule && archive.getModule().isNamed() && type != SUMMARY) {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   228
                        // print module-info except -summary
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   229
                        summaryFormatter.printModuleDescriptor(archive.getModule());
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   230
                    }
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   231
                    // print summary
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   232
                    analyzer.visitDependences(archive, summaryFormatter, SUMMARY);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   233
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   234
                    if (analyzer.hasDependences(archive) && type != SUMMARY) {
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   235
                        // print the class-level or package-level dependences
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   236
                        analyzer.visitDependences(archive, depFormatter);
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   237
                    }
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   238
            });
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   239
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   240
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   241
        class RawOutputFormatter implements Analyzer.Visitor {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   242
            private final PrintWriter writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   243
            private String pkg = "";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   244
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   245
            RawOutputFormatter(PrintWriter writer) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   246
                this.writer = writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   247
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   248
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   249
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   250
            public void visitDependence(String origin, Archive originArchive,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   251
                                        String target, Archive targetArchive) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   252
                String tag = toTag(originArchive, target, targetArchive);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   253
                if (showModule || type == VERBOSE) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   254
                    writer.format("   %-50s -> %-50s %s%n", origin, target, tag);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   255
                } else {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   256
                    if (!origin.equals(pkg)) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   257
                        pkg = origin;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   258
                        writer.format("   %s (%s)%n", origin, originArchive.getName());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   259
                    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   260
                    writer.format("      -> %-50s %s%n", target, tag);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   261
                }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   262
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   263
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   264
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   265
        class RawSummaryFormatter implements Analyzer.Visitor {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   266
            private final PrintWriter writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   267
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   268
            RawSummaryFormatter(PrintWriter writer) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   269
                this.writer = writer;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   270
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   271
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   272
            @Override
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   273
            public void visitDependence(String origin, Archive originArchive,
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   274
                                        String target, Archive targetArchive) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   275
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   276
                String targetName = targetArchive.getPathName();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   277
                if (targetArchive.getModule().isNamed()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   278
                    targetName = targetArchive.getModule().name();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   279
                }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   280
                writer.format("%s -> %s", originArchive.getName(), targetName);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   281
                if (showProfile && targetArchive.getModule().isJDK()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   282
                    writer.format(" (%s)", target);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   283
                }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   284
                writer.format("%n");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   285
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   286
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   287
            public void printModuleDescriptor(Module module) {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   288
                if (!module.isNamed())
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   289
                    return;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   290
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   291
                writer.format("%s%s%n", module.name(), module.isAutomatic() ? " automatic" : "");
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   292
                writer.format(" [%s]%n", module.location());
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   293
                module.descriptor().requires()
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   294
                        .stream()
38524
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   295
                        .sorted(Comparator.comparing(Requires::name))
badd925c1d2f 8156680: jdeps implementation refresh
mchung
parents: 36526
diff changeset
   296
                        .forEach(req -> writer.format("   requires %s%n", req));
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   297
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   298
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   299
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   300
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   301
    /**
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   302
     * If the given archive is JDK archive, this method returns the profile name
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   303
     * only if -profile option is specified; it accesses a private JDK API and
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   304
     * the returned value will have "JDK internal API" prefix
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   305
     *
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   306
     * For non-JDK archives, this method returns the file name of the archive.
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   307
     */
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   308
    String toTag(Archive source, String name, Archive target) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   309
        if (source == target || !target.getModule().isNamed()) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   310
            return target.getName();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   311
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   312
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   313
        Module module = target.getModule();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   314
        String pn = name;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   315
        if ((type == CLASS || type == VERBOSE)) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   316
            int i = name.lastIndexOf('.');
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   317
            pn = i > 0 ? name.substring(0, i) : "";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   318
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   319
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   320
        // exported API
41860
906670ff49c7 8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents: 38524
diff changeset
   321
        if (module.isExported(pn) && !module.isJDKUnsupported()) {
36526
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   322
            return showProfileOrModule(module);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   323
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   324
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   325
        // JDK internal API
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   326
        if (!source.getModule().isJDK() && module.isJDK()){
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   327
            return "JDK internal API (" + module.name() + ")";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   328
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   329
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   330
        // qualified exports or inaccessible
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   331
        boolean isExported = module.isExported(pn, source.getModule().name());
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   332
        return module.name() + (isExported ?  " (qualified)" : " (internal)");
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   333
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   334
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   335
    String showProfileOrModule(Module m) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   336
        String tag = "";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   337
        if (showProfile) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   338
            Profile p = Profile.getProfile(m);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   339
            if (p != null) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   340
                tag = p.profileName();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   341
            }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   342
        } else if (showModule) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   343
            tag = m.name();
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   344
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   345
        return tag;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   346
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   347
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   348
    Profile getProfile(String name) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   349
        String pn = name;
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   350
        if (type == CLASS || type == VERBOSE) {
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   351
            int i = name.lastIndexOf('.');
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   352
            pn = i > 0 ? name.substring(0, i) : "";
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   353
        }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   354
        return Profile.getProfile(pn);
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   355
    }
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   356
3b41f1c69604 8142968: Module System implementation
alanb
parents:
diff changeset
   357
}