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