001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.resolver.examples.util; 020 021import java.io.PrintStream; 022import java.util.ArrayList; 023import java.util.Iterator; 024import java.util.List; 025 026import org.eclipse.aether.artifact.Artifact; 027import org.eclipse.aether.graph.Dependency; 028import org.eclipse.aether.graph.DependencyNode; 029import org.eclipse.aether.graph.DependencyVisitor; 030import org.eclipse.aether.util.artifact.ArtifactIdUtils; 031import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; 032import org.eclipse.aether.util.graph.transformer.ConflictResolver; 033 034/** 035 * A dependency visitor that dumps the graph to the console. 036 */ 037public class ConsoleDependencyGraphDumper implements DependencyVisitor { 038 039 private final PrintStream out; 040 041 private final List<ChildInfo> childInfos = new ArrayList<>(); 042 043 public ConsoleDependencyGraphDumper() { 044 this(null); 045 } 046 047 public ConsoleDependencyGraphDumper(PrintStream out) { 048 this.out = (out != null) ? out : System.out; 049 } 050 051 public boolean visitEnter(DependencyNode node) { 052 out.println(formatIndentation() + formatNode(node)); 053 childInfos.add(new ChildInfo(node.getChildren().size())); 054 return true; 055 } 056 057 private String formatIndentation() { 058 StringBuilder buffer = new StringBuilder(128); 059 for (Iterator<ChildInfo> it = childInfos.iterator(); it.hasNext(); ) { 060 buffer.append(it.next().formatIndentation(!it.hasNext())); 061 } 062 return buffer.toString(); 063 } 064 065 private String formatNode(DependencyNode node) { 066 StringBuilder buffer = new StringBuilder(128); 067 Artifact a = node.getArtifact(); 068 Dependency d = node.getDependency(); 069 buffer.append(a); 070 if (d != null && d.getScope().length() > 0) { 071 buffer.append(" [").append(d.getScope()); 072 if (d.isOptional()) { 073 buffer.append(", optional"); 074 } 075 buffer.append("]"); 076 } 077 String premanaged = DependencyManagerUtils.getPremanagedVersion(node); 078 if (premanaged != null && !premanaged.equals(a.getBaseVersion())) { 079 buffer.append(" (version managed from ").append(premanaged).append(")"); 080 } 081 082 premanaged = DependencyManagerUtils.getPremanagedScope(node); 083 if (premanaged != null && !premanaged.equals(d.getScope())) { 084 buffer.append(" (scope managed from ").append(premanaged).append(")"); 085 } 086 DependencyNode winner = (DependencyNode) node.getData().get(ConflictResolver.NODE_DATA_WINNER); 087 if (winner != null && !ArtifactIdUtils.equalsId(a, winner.getArtifact())) { 088 Artifact w = winner.getArtifact(); 089 buffer.append(" (conflicts with "); 090 if (ArtifactIdUtils.toVersionlessId(a).equals(ArtifactIdUtils.toVersionlessId(w))) { 091 buffer.append(w.getVersion()); 092 } else { 093 buffer.append(w); 094 } 095 buffer.append(")"); 096 } 097 return buffer.toString(); 098 } 099 100 public boolean visitLeave(DependencyNode node) { 101 if (!childInfos.isEmpty()) { 102 childInfos.remove(childInfos.size() - 1); 103 } 104 if (!childInfos.isEmpty()) { 105 childInfos.get(childInfos.size() - 1).index++; 106 } 107 return true; 108 } 109 110 private static class ChildInfo { 111 112 final int count; 113 114 int index; 115 116 ChildInfo(int count) { 117 this.count = count; 118 } 119 120 public String formatIndentation(boolean end) { 121 boolean last = index + 1 >= count; 122 if (end) { 123 return last ? "\\- " : "+- "; 124 } 125 return last ? " " : "| "; 126 } 127 } 128}