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