blob: 39bc1ed427441ab7b4a55b47f57110949188aa79 [file] [log] [blame]
package org.eclipse.aether.internal.impl;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyNode;
/**
* A helper to visualize dependency graphs.
*/
public class DependencyGraphDumper
{
public static void dump( PrintWriter writer, DependencyNode node )
{
Context context = new Context();
dump( context, node, 0, true );
LinkedList<Indent> indents = new LinkedList<Indent>();
for ( Line line : context.lines )
{
if ( line.depth > indents.size() )
{
if ( !indents.isEmpty() )
{
if ( indents.getLast() == Indent.CHILD )
{
indents.removeLast();
indents.addLast( Indent.CHILDREN );
}
else if ( indents.getLast() == Indent.LAST_CHILD )
{
indents.removeLast();
indents.addLast( Indent.NO_CHILDREN );
}
}
indents.addLast( line.last ? Indent.LAST_CHILD : Indent.CHILD );
}
else if ( line.depth < indents.size() )
{
while ( line.depth <= indents.size() )
{
indents.removeLast();
}
indents.addLast( line.last ? Indent.LAST_CHILD : Indent.CHILD );
}
else if ( line.last && !indents.isEmpty() )
{
indents.removeLast();
indents.addLast( Indent.LAST_CHILD );
}
for ( Indent indent : indents )
{
writer.print( indent );
}
line.print( writer );
}
writer.flush();
}
private static void dump( Context context, DependencyNode node, int depth, boolean last )
{
Line line = context.nodes.get( node );
if ( line != null )
{
if ( line.id <= 0 )
{
line.id = ++context.ids;
}
context.lines.add( new Line( null, line.id, depth, last ) );
return;
}
Dependency dependency = node.getDependency();
if ( dependency == null )
{
line = new Line( null, 0, depth, last );
}
else
{
line = new Line( dependency, 0, depth, last );
}
context.lines.add( line );
context.nodes.put( node, line );
depth++;
for ( Iterator<DependencyNode> it = node.getChildren().iterator(); it.hasNext(); )
{
DependencyNode child = it.next();
dump( context, child, depth, !it.hasNext() );
}
}
static enum Indent
{
NO_CHILDREN( " " ),
CHILDREN( "| " ),
CHILD( "+- " ),
LAST_CHILD( "\\- " );
private final String chars;
Indent( String chars )
{
this.chars = chars;
}
@Override
public String toString()
{
return chars;
}
}
static class Context
{
int ids;
List<Line> lines;
Map<DependencyNode, Line> nodes;
Context()
{
this.lines = new ArrayList<Line>();
this.nodes = new IdentityHashMap<DependencyNode, Line>( 1024 );
}
}
static class Line
{
Dependency dependency;
int id;
int depth;
boolean last;
Line( Dependency dependency, int id, int depth, boolean last )
{
this.dependency = dependency;
this.id = id;
this.depth = depth;
this.last = last;
}
void print( PrintWriter writer )
{
if ( dependency == null )
{
if ( id > 0 )
{
writer.print( "^" );
writer.print( id );
}
else
{
writer.print( "(null)" );
}
}
else
{
if ( id > 0 )
{
writer.print( "(" );
writer.print( id );
writer.print( ")" );
}
writer.print( dependency.getArtifact() );
if ( dependency.getScope().length() > 0 )
{
writer.print( ":" );
writer.print( dependency.getScope() );
}
}
writer.println();
}
}
}