]> source.dussan.org Git - archiva.git/blob
daae2e29fa05edea5dd643fafe9909b78cdc89c4
[archiva.git] /
1 package org.apache.maven.archiva.dependency;
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.apache.maven.archiva.dependency.graph.DependencyGraph;
23 import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
24 import org.apache.maven.archiva.dependency.graph.GraphListener;
25 import org.apache.maven.archiva.dependency.graph.GraphPhaseEvent;
26 import org.apache.maven.archiva.dependency.graph.GraphTask;
27 import org.apache.maven.archiva.dependency.graph.GraphTaskException;
28 import org.apache.maven.archiva.dependency.graph.PotentialCyclicEdgeProducer;
29 import org.apache.maven.archiva.dependency.graph.tasks.FlagCyclicEdgesTask;
30 import org.apache.maven.archiva.dependency.graph.tasks.FlagExcludedEdgesTask;
31 import org.apache.maven.archiva.dependency.graph.tasks.PopulateGraphMasterTask;
32 import org.apache.maven.archiva.dependency.graph.tasks.ReduceEnabledEdgesTask;
33 import org.apache.maven.archiva.dependency.graph.tasks.ReduceScopeTask;
34 import org.apache.maven.archiva.dependency.graph.tasks.ReduceTransitiveEdgesTask;
35 import org.apache.maven.archiva.dependency.graph.tasks.RefineConflictsTask;
36 import org.apache.maven.archiva.dependency.graph.tasks.UpdateScopesTask;
37 import org.apache.maven.archiva.model.DependencyScope;
38 import org.apache.maven.archiva.model.VersionedReference;
39
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 import java.util.List;
43
44 /**
45  * DependencyGraphFactory 
46  *
47  * @version $Id$
48  */
49 public class DependencyGraphFactory
50 {
51     private GraphTask taskFlagCyclicEdges;
52
53     private PopulateGraphMasterTask taskPopulateGraph;
54
55     private ReduceScopeTask taskReduceScope;
56
57     private List listeners;
58
59     private DependencyGraphBuilder graphBuilder;
60
61     private List tasks;
62
63     public DependencyGraphFactory()
64     {
65         listeners = new ArrayList();
66
67         taskFlagCyclicEdges = new FlagCyclicEdgesTask();
68         taskPopulateGraph = new PopulateGraphMasterTask();
69         taskReduceScope = new ReduceScopeTask( DependencyScope.TEST );
70
71         tasks = new ArrayList();
72
73         /* Take the basic graph, and expand the nodes fully, including depman.
74          */
75         tasks.add( taskPopulateGraph );
76
77         /* Identify, flag, and disable excluded edges.
78          */
79         tasks.add( new FlagExcludedEdgesTask() );
80
81         /* Reduce the edges of the graph to only those that are enabled.
82          */
83         tasks.add( new ReduceEnabledEdgesTask() );
84
85         /* Identify dependencies that conflict, resolve to single node.
86          * 
87          * This will ...
88          * 1) filter the distant conflicts away for the nearer ones.
89          * 2) same distance nodes will pick 'newest' version.
90          * 
91          * This can cause a collapsing of node versions.
92          */
93         tasks.add( new RefineConflictsTask() );
94
95         /* Reduce the scope of the graph to those visible by the 'test' scope.
96          */
97         tasks.add( taskReduceScope );
98
99         /* Reduce the edges of the graph.  Use the transitive reduction algorithm
100          * to remove redundant edges.
101          */
102         tasks.add( new ReduceTransitiveEdgesTask() );
103
104         /* Update the scopes of the edges to conform to the parent setting. 
105          */
106         tasks.add( new UpdateScopesTask() );
107     }
108
109     public void addGraphListener( GraphListener listener )
110     {
111         this.listeners.add( listener );
112     }
113
114     /**
115      * Get the Graph for a specific Versioned Project Reference.
116      * 
117      * @param versionedProjectReference
118      * @return
119      */
120     public DependencyGraph getGraph( VersionedReference versionedProjectReference )
121         throws GraphTaskException
122     {
123         DependencyGraph graph = graphBuilder.createGraph( versionedProjectReference );
124
125         triggerGraphPhase( GraphPhaseEvent.GRAPH_NEW, null, graph );
126
127         Iterator it = this.tasks.iterator();
128         while ( it.hasNext() )
129         {
130             GraphTask task = (GraphTask) it.next();
131             try
132             {
133                 triggerGraphPhase( GraphPhaseEvent.GRAPH_TASK_PRE, task, graph );
134                 task.executeTask( graph );
135                 if ( task instanceof PotentialCyclicEdgeProducer )
136                 {
137                     taskFlagCyclicEdges.executeTask( graph );
138                 }
139                 triggerGraphPhase( GraphPhaseEvent.GRAPH_TASK_POST, task, graph );
140             }
141             catch ( GraphTaskException e )
142             {
143                 triggerGraphError( e, graph );
144                 throw e;
145             }
146             catch ( Exception e )
147             {
148                 GraphTaskException gte = new GraphTaskException( e.getMessage(), e );
149                 triggerGraphError( gte, graph );
150                 throw gte;
151             }
152         }
153
154         triggerGraphPhase( GraphPhaseEvent.GRAPH_DONE, null, graph );
155
156         return graph;
157     }
158
159     public void removeGraphListener( GraphListener listener )
160     {
161         this.listeners.remove( listener );
162     }
163
164     public void setDesiredScope( String scope )
165     {
166         taskReduceScope.setScope( scope );
167     }
168
169     public void setGraphBuilder( DependencyGraphBuilder graphBuilder )
170     {
171         this.graphBuilder = graphBuilder;
172         taskPopulateGraph.setBuilder( graphBuilder );
173     }
174
175     private void triggerGraphError( GraphTaskException e, DependencyGraph graph )
176     {
177         Iterator it = listeners.iterator();
178         while ( it.hasNext() )
179         {
180             GraphListener listener = (GraphListener) it.next();
181             listener.graphError( e, graph );
182         }
183     }
184
185     private void triggerGraphPhase( int type, GraphTask task, DependencyGraph graph )
186     {
187         GraphPhaseEvent evt = new GraphPhaseEvent( type, task, graph );
188
189         Iterator it = listeners.iterator();
190         while ( it.hasNext() )
191         {
192             GraphListener listener = (GraphListener) it.next();
193             listener.graphPhaseEvent( evt );
194         }
195     }
196
197 }