View Javadoc

1   package org.apache.maven.repository.metadata;
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.ArrayList;
23  import java.util.Arrays;
24  import java.util.Comparator;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.ArtifactScopeEnum;
28  import org.codehaus.plexus.component.annotations.Component;
29  import org.codehaus.plexus.component.annotations.Requirement;
30  
31  /**
32   * default implementation of the metadata classpath transformer
33   *
34   * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
35   *
36   */
37  @Component( role = ClasspathTransformation.class )
38  public class DefaultClasspathTransformation
39      implements ClasspathTransformation
40  {
41      @Requirement
42      GraphConflictResolver conflictResolver;
43  
44      //----------------------------------------------------------------------------------------------------
45      public ClasspathContainer transform( MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve )
46          throws MetadataGraphTransformationException
47      {
48          try
49          {
50              if ( dirtyGraph == null || dirtyGraph.isEmpty() )
51              {
52                  return null;
53              }
54  
55              MetadataGraph cleanGraph = conflictResolver.resolveConflicts( dirtyGraph, scope );
56  
57              if ( cleanGraph == null || cleanGraph.isEmpty() )
58              {
59                  return null;
60              }
61  
62              ClasspathContainer cpc = new ClasspathContainer( scope );
63              if ( cleanGraph.isEmptyEdges() )
64              {
65                  // single entry in the classpath, populated from itself
66                  ArtifactMetadata amd = cleanGraph.getEntry().getMd();
67                  cpc.add( amd );
68              }
69              else
70              {
71                  ClasspathGraphVisitor v = new ClasspathGraphVisitor( cleanGraph, cpc );
72                  MetadataGraphVertex entry = cleanGraph.getEntry();
73                  ArtifactMetadata md = entry.getMd();
74                  // entry point
75                  v.visit( entry ); // , md.getVersion(), md.getArtifactUri() );
76              }
77  
78              return cpc;
79          }
80          catch ( GraphConflictResolutionException e )
81          {
82              throw new MetadataGraphTransformationException( e );
83          }
84      }
85  
86      //===================================================================================================
87      /**
88       * Helper class to traverse graph. Required to make the containing method thread-safe
89       * and yet use class level data to lessen stack usage in recursion
90       */
91      private class ClasspathGraphVisitor
92      {
93          MetadataGraph graph;
94  
95          ClasspathContainer cpc;
96  
97          List<MetadataGraphVertex> visited;
98  
99          // -----------------------------------------------------------------------
100         protected ClasspathGraphVisitor( MetadataGraph cleanGraph, ClasspathContainer cpc )
101         {
102             this.cpc = cpc;
103             this.graph = cleanGraph;
104 
105             visited = new ArrayList<MetadataGraphVertex>( cleanGraph.getVertices().size() );
106         }
107 
108         // -----------------------------------------------------------------------
109         protected void visit( MetadataGraphVertex node ) // , String version, String artifactUri )
110         {
111             ArtifactMetadata md = node.getMd();
112             if ( visited.contains( node ) )
113             {
114                 return;
115             }
116 
117             cpc.add( md );
118 //
119 //            TreeSet<MetadataGraphEdge> deps = new TreeSet<MetadataGraphEdge>(
120 //                        new Comparator<MetadataGraphEdge>()
121 //                        {
122 //                            public int compare( MetadataGraphEdge e1
123 //                                              , MetadataGraphEdge e2
124 //                                              )
125 //                            {
126 //                                if( e1.getDepth() == e2.getDepth() )
127 //                                {
128 //                                    if( e2.getPomOrder() == e1.getPomOrder() )
129 //                                        return e1.getTarget().toString().compareTo(e2.getTarget().toString() );
130 //
131 //                                    return e2.getPomOrder() - e1.getPomOrder();
132 //                                }
133 //
134 //                                return e2.getDepth() - e1.getDepth();
135 //                            }
136 //                        }
137 //                    );
138 
139             List<MetadataGraphEdge> exits = graph.getExcidentEdges( node );
140 
141             if ( exits != null && exits.size() > 0 )
142             {
143                 MetadataGraphEdge[] sortedExits = exits.toArray( new MetadataGraphEdge[exits.size()] );
144                 Arrays.sort( sortedExits
145                         ,
146                         new Comparator<MetadataGraphEdge>()
147                         {
148                             public int compare( MetadataGraphEdge e1
149                                             , MetadataGraphEdge e2
150                                             )
151                             {
152                                 if ( e1.getDepth() == e2.getDepth() )
153                                 {
154                                     if ( e2.getPomOrder() == e1.getPomOrder() )
155                                     {
156                                         return e1.getTarget().toString().compareTo( e2.getTarget().toString() );
157                                     }
158                                     return e2.getPomOrder() - e1.getPomOrder();
159                                 }
160 
161                                 return e2.getDepth() - e1.getDepth();
162                             }
163                         }
164                 );
165 
166                 for ( MetadataGraphEdge e : sortedExits )
167                 {
168                     MetadataGraphVertex targetNode = e.getTarget();
169                     targetNode.getMd().setArtifactScope( e.getScope() );
170                     targetNode.getMd().setWhy( e.getSource().getMd().toString() );
171                     visit( targetNode );
172                 }
173             }
174 
175         }
176         //-----------------------------------------------------------------------
177         //-----------------------------------------------------------------------
178     }
179     //----------------------------------------------------------------------------------------------------
180     //----------------------------------------------------------------------------------------------------
181 }
182 
183 
184