View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.repository.metadata;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  
29  import org.apache.maven.artifact.ArtifactScopeEnum;
30  
31  /**
32   * default implementation of the metadata classpath transformer
33   *
34   *
35   */
36  @Named
37  @Singleton
38  @Deprecated
39  public class DefaultClasspathTransformation implements ClasspathTransformation {
40      @Inject
41      GraphConflictResolver conflictResolver;
42  
43      // ----------------------------------------------------------------------------------------------------
44      public ClasspathContainer transform(MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve)
45              throws MetadataGraphTransformationException {
46          try {
47              if (dirtyGraph == null || dirtyGraph.isEmpty()) {
48                  return null;
49              }
50  
51              MetadataGraph cleanGraph = conflictResolver.resolveConflicts(dirtyGraph, scope);
52  
53              if (cleanGraph == null || cleanGraph.isEmpty()) {
54                  return null;
55              }
56  
57              ClasspathContainer cpc = new ClasspathContainer(scope);
58              if (cleanGraph.isEmptyEdges()) {
59                  // single entry in the classpath, populated from itself
60                  ArtifactMetadata amd = cleanGraph.getEntry().getMd();
61                  cpc.add(amd);
62              } else {
63                  ClasspathGraphVisitor v = new ClasspathGraphVisitor(cleanGraph, cpc);
64                  MetadataGraphVertex entry = cleanGraph.getEntry();
65                  // entry point
66                  v.visit(entry);
67              }
68  
69              return cpc;
70          } catch (GraphConflictResolutionException e) {
71              throw new MetadataGraphTransformationException(e);
72          }
73      }
74  
75      // ===================================================================================================
76      /**
77       * Helper class to traverse graph. Required to make the containing method thread-safe
78       * and yet use class level data to lessen stack usage in recursion
79       */
80      private class ClasspathGraphVisitor {
81          MetadataGraph graph;
82  
83          ClasspathContainer cpc;
84  
85          List<MetadataGraphVertex> visited;
86  
87          // -----------------------------------------------------------------------
88          protected ClasspathGraphVisitor(MetadataGraph cleanGraph, ClasspathContainer cpc) {
89              this.cpc = cpc;
90              this.graph = cleanGraph;
91  
92              visited = new ArrayList<>(cleanGraph.getVertices().size());
93          }
94  
95          // -----------------------------------------------------------------------
96          protected void visit(MetadataGraphVertex node) // , String version, String artifactUri )
97                  {
98              ArtifactMetadata md = node.getMd();
99              if (visited.contains(node)) {
100                 return;
101             }
102 
103             cpc.add(md);
104             //
105             //            TreeSet<MetadataGraphEdge> deps = new TreeSet<MetadataGraphEdge>(
106             //                        new Comparator<MetadataGraphEdge>()
107             //                        {
108             //                            public int compare( MetadataGraphEdge e1
109             //                                              , MetadataGraphEdge e2
110             //                                              )
111             //                            {
112             //                                if( e1.getDepth() == e2.getDepth() )
113             //                                {
114             //                                    if( e2.getPomOrder() == e1.getPomOrder() )
115             //                                        return
116             // e1.getTarget().toString().compareTo(e2.getTarget().toString() );
117             //
118             //                                    return e2.getPomOrder() - e1.getPomOrder();
119             //                                }
120             //
121             //                                return e2.getDepth() - e1.getDepth();
122             //                            }
123             //                        }
124             //                    );
125 
126             List<MetadataGraphEdge> exits = graph.getExcidentEdges(node);
127 
128             if (exits != null && exits.size() > 0) {
129                 MetadataGraphEdge[] sortedExits = exits.toArray(new MetadataGraphEdge[0]);
130                 Arrays.sort(sortedExits, (e1, e2) -> {
131                     if (e1.getDepth() == e2.getDepth()) {
132                         if (e2.getPomOrder() == e1.getPomOrder()) {
133                             return e1.getTarget()
134                                     .toString()
135                                     .compareTo(e2.getTarget().toString());
136                         }
137                         return e2.getPomOrder() - e1.getPomOrder();
138                     }
139                     return e2.getDepth() - e1.getDepth();
140                 });
141 
142                 for (MetadataGraphEdge e : sortedExits) {
143                     MetadataGraphVertex targetNode = e.getTarget();
144                     targetNode.getMd().setArtifactScope(e.getScope());
145                     targetNode.getMd().setWhy(e.getSource().getMd().toString());
146                     visit(targetNode);
147                 }
148             }
149         }
150         // -----------------------------------------------------------------------
151         // -----------------------------------------------------------------------
152     }
153     // ----------------------------------------------------------------------------------------------------
154     // ----------------------------------------------------------------------------------------------------
155 }