View Javadoc
1   package org.eclipse.aether.internal.impl;
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 java.util.Arrays;
23  
24  import org.eclipse.aether.artifact.Artifact;
25  import org.eclipse.aether.graph.DependencyNode;
26  
27  /**
28   * @see DefaultDependencyCollector
29   */
30  final class NodeStack
31  {
32  
33      private DependencyNode[] nodes = new DependencyNode[96];
34  
35      private int size;
36  
37      public DependencyNode top()
38      {
39          if ( size <= 0 )
40          {
41              throw new IllegalStateException( "stack empty" );
42          }
43          return nodes[size - 1];
44      }
45  
46      public void push( DependencyNode node )
47      {
48          if ( size >= nodes.length )
49          {
50              DependencyNode[] tmp = new DependencyNode[size + 64];
51              System.arraycopy( nodes, 0, tmp, 0, nodes.length );
52              nodes = tmp;
53          }
54          nodes[size++] = node;
55      }
56  
57      public void pop()
58      {
59          if ( size <= 0 )
60          {
61              throw new IllegalStateException( "stack empty" );
62          }
63          size--;
64      }
65  
66      public int find( Artifact artifact )
67      {
68          for ( int i = size - 1; i >= 0; i-- )
69          {
70              DependencyNode node = nodes[i];
71  
72              Artifact a = node.getArtifact();
73              if ( a == null )
74              {
75                  break;
76              }
77  
78              if ( !a.getArtifactId().equals( artifact.getArtifactId() ) )
79              {
80                  continue;
81              }
82              if ( !a.getGroupId().equals( artifact.getGroupId() ) )
83              {
84                  continue;
85              }
86              if ( !a.getExtension().equals( artifact.getExtension() ) )
87              {
88                  continue;
89              }
90              if ( !a.getClassifier().equals( artifact.getClassifier() ) )
91              {
92                  continue;
93              }
94              /*
95               * NOTE: While a:1 and a:2 are technically different artifacts, we want to consider the path a:2 -> b:2 ->
96               * a:1 a cycle in the current context. The artifacts themselves might not form a cycle but their producing
97               * projects surely do. Furthermore, conflict resolution will always have to consider a:1 a loser (otherwise
98               * its ancestor a:2 would get pruned and so would a:1) so there is no point in building the sub graph of
99               * a:1.
100              */
101 
102             return i;
103         }
104 
105         return -1;
106     }
107 
108     public int size()
109     {
110         return size;
111     }
112 
113     public DependencyNode get( int index )
114     {
115         return nodes[index];
116     }
117 
118     @Override
119     public String toString()
120     {
121         return Arrays.toString( nodes );
122     }
123 
124 }