1 package org.apache.maven.repository.metadata;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.TreeSet;
25
26 import org.apache.maven.artifact.ArtifactScopeEnum;
27 import org.codehaus.plexus.component.annotations.Component;
28 import org.codehaus.plexus.component.annotations.Requirement;
29
30
31
32
33
34
35
36 @Component( role = GraphConflictResolver.class )
37 public class DefaultGraphConflictResolver
38 implements GraphConflictResolver
39 {
40
41
42
43 @Requirement( role = GraphConflictResolutionPolicy.class )
44 protected GraphConflictResolutionPolicy policy;
45
46
47
48 public MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
49 throws GraphConflictResolutionException
50 {
51 if ( policy == null )
52 {
53 throw new GraphConflictResolutionException( "no GraphConflictResolutionPolicy injected" );
54 }
55
56 if ( graph == null )
57 {
58 return null;
59 }
60
61 final MetadataGraphVertex entry = graph.getEntry();
62 if ( entry == null )
63 {
64 return null;
65 }
66
67 if ( graph.isEmpty() )
68 {
69 throw new GraphConflictResolutionException( "graph with an entry, but not vertices do not exist" );
70 }
71
72 if ( graph.isEmptyEdges() )
73 {
74 return null;
75 }
76
77 final TreeSet<MetadataGraphVertex> vertices = graph.getVertices();
78
79 try
80 {
81
82 if ( vertices.size() == 1 )
83 {
84 return new MetadataGraph( entry );
85 }
86
87 final ArtifactScopeEnum requestedScope = ArtifactScopeEnum.checkScope( scope );
88
89 MetadataGraph res = new MetadataGraph( vertices.size() );
90 res.setVersionedVertices( false );
91 res.setScopedVertices( false );
92
93 MetadataGraphVertex resEntry = res.addVertex( entry.getMd() );
94 res.setEntry( resEntry );
95
96 res.setScope( requestedScope );
97
98 for ( MetadataGraphVertex v : vertices )
99 {
100 final List<MetadataGraphEdge> ins = graph.getIncidentEdges( v );
101 final MetadataGraphEdge edge = cleanEdges( v, ins, requestedScope );
102
103 if ( edge == null )
104 {
105 if ( entry.equals( v ) )
106 {
107
108 res.getEntry().getMd().setWhy( "This is a graph entry point. No links." );
109 }
110 else
111 {
112
113
114
115
116
117 }
118 }
119 else
120 {
121
122
123 ArtifactMetadata md = v.getMd();
124 ArtifactMetadata newMd =
125 new ArtifactMetadata( md.getGroupId(), md.getArtifactId(), edge.getVersion(), md.getType(),
126 md.getScopeAsEnum(), md.getClassifier(), edge.getArtifactUri(),
127 edge.getSource() == null ? "" : edge.getSource().getMd().toString(),
128 edge.isResolved(), edge.getTarget() == null ? null
129 : edge.getTarget().getMd().getError() );
130 MetadataGraphVertex newV = res.addVertex( newMd );
131 MetadataGraphVertex sourceV = res.addVertex( edge.getSource().getMd() );
132
133 res.addEdge( sourceV, newV, edge );
134 }
135 }
136 MetadataGraph linkedRes = findLinkedSubgraph( res );
137
138
139
140
141 return linkedRes;
142 }
143 catch ( MetadataResolutionException e )
144 {
145 throw new GraphConflictResolutionException( e );
146 }
147 }
148
149
150 private MetadataGraph findLinkedSubgraph( MetadataGraph g )
151 {
152 if ( g.getVertices().size() == 1 )
153 {
154 return g;
155 }
156
157 List<MetadataGraphVertex> visited = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
158 visit( g.getEntry(), visited, g );
159
160 List<MetadataGraphVertex> dropList = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
161
162
163 for ( MetadataGraphVertex v : g.getVertices() )
164 {
165 if ( !visited.contains( v ) )
166 {
167 dropList.add( v );
168 }
169 }
170
171 if ( dropList.size() < 1 )
172 {
173 return g;
174 }
175
176
177 TreeSet<MetadataGraphVertex> vertices = g.getVertices();
178 for ( MetadataGraphVertex v : dropList )
179 {
180 vertices.remove( v );
181 }
182
183 return g;
184 }
185
186
187 private void visit( MetadataGraphVertex from, List<MetadataGraphVertex> visited, MetadataGraph graph )
188 {
189 if ( visited.contains( from ) )
190 {
191 return;
192 }
193
194 visited.add( from );
195
196 List<MetadataGraphEdge> exitList = graph.getExcidentEdges( from );
197
198 if ( exitList != null && exitList.size() > 0 )
199 {
200 for ( MetadataGraphEdge e : graph.getExcidentEdges( from ) )
201 {
202 visit( e.getTarget(), visited, graph );
203 }
204 }
205 }
206
207
208 private MetadataGraphEdge cleanEdges( MetadataGraphVertex v, List<MetadataGraphEdge> edges,
209 ArtifactScopeEnum scope )
210 {
211 if ( edges == null || edges.isEmpty() )
212 {
213 return null;
214 }
215
216 if ( edges.size() == 1 )
217 {
218 MetadataGraphEdge e = edges.get( 0 );
219 if ( scope.encloses( e.getScope() ) )
220 {
221 return e;
222 }
223
224 return null;
225 }
226
227 MetadataGraphEdge res = null;
228
229 for ( MetadataGraphEdge e : edges )
230 {
231 if ( !scope.encloses( e.getScope() ) )
232 {
233 continue;
234 }
235
236 if ( res == null )
237 {
238 res = e;
239 }
240 else
241 {
242 res = policy.apply( e, res );
243 }
244 }
245
246 return res;
247 }
248
249
250 }