View Javadoc
1   package org.apache.maven.plugins.dependency.tree;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.eclipse.aether.artifact.Artifact;
23  import org.eclipse.aether.graph.DependencyNode;
24  
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.LinkedList;
28  import java.util.Map;
29  import java.util.Queue;
30  import java.util.Set;
31  
32  /**
33   * Parses dependency graph and outputs in DOT format for end user to review.
34   */
35  class VerboseGraphDotSerializer extends AbstractVerboseGraphSerializer
36  {
37      @Override
38      public String serialize( DependencyNode root )
39      {
40          Set<String> coordinateStrings = new HashSet<>();
41          Map<String, String> coordinateVersionMap = new HashMap<>();
42          Map<DependencyNode, String> nodeErrors = getNodeConflictMessagesBfs( root, coordinateStrings,
43                  coordinateVersionMap );
44          Set<DependencyNode> visitedNodes = new HashSet<>();
45          Queue<DependencyNode> queue = new LinkedList<>();
46          queue.add( root );
47          Artifact rootArtifact = root.getArtifact();
48  
49          StringBuilder result = new StringBuilder( "digraph" );
50          result.append( " \"" ).append( rootArtifact.getGroupId() ).append( ":" ).append(
51                  rootArtifact.getArtifactId() ).append( ":" ).append( rootArtifact.getExtension() ).append( ":" ).append(
52                  rootArtifact.getVersion() );
53  
54          if ( root.getData().containsKey( "ContainsModule" ) )
55          {
56              result.append( " WARNING: this tree contains a submodule. Once it reaches the submodule will print "
57                      + "in nonVerbose fashion, to see the actual submodule verbose output refer to the "
58                      + "rest of the output" );
59          }
60  
61          result.append( "\" {" ).append( "\n" );
62  
63          while ( !queue.isEmpty() )
64          {
65              DependencyNode node = queue.poll();
66              for ( DependencyNode child : node.getChildren() )
67              {
68                  result.append( " \"" );
69                  String coordString = "";
70                  boolean messageAdded = false;
71  
72                  if ( child.getArtifact().getProperties().containsKey( PRE_MANAGED_VERSION ) )
73                  {
74                      coordString +=
75                              " - version managed from " + child.getArtifact().getProperties().get(
76                                      PRE_MANAGED_VERSION );
77                      messageAdded = true;
78                  }
79                  if ( child.getArtifact().getProperties().containsKey( PRE_MANAGED_SCOPE ) )
80                  {
81                      if ( messageAdded )
82                      {
83                          coordString += "; ";
84                      }
85                      else
86                      {
87                          coordString += " - ";
88                          messageAdded = true;
89                      }
90                      coordString +=
91                              "scope managed from " + child.getArtifact().getProperties().get( PRE_MANAGED_SCOPE );
92                  }
93                  coordString = getDependencyCoordinate( child ) + coordString;
94                  result.append( getDependencyCoordinate( node ) ).append( "\"" ).append( " -> \"" ).append(
95                          coordString );
96                  if ( child.getArtifact().getProperties().containsKey( "Cycle" ) )
97                  {
98                      if ( !messageAdded )
99                      {
100                         result.append( " -" );
101                     }
102                     result.append( " omitted due to cycle" );
103                 }
104                 else if ( nodeErrors.get( child ) != null )
105                 {
106                     if ( !messageAdded )
107                     {
108                         result.append( " - " );
109                     }
110                     result.append( nodeErrors.get( child ) );
111                 }
112                 else if ( !visitedNodes.contains( child ) )
113                 {
114                     visitedNodes.add( child );
115                     queue.add( child );
116                 }
117                 result.append( "\" ;" ).append( "\n" );
118             }
119         }
120         result.append( "}" );
121         return result.toString();
122     }
123 }