View Javadoc
1   package org.codehaus.plexus.util.dag;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.HashMap;
20  import java.util.LinkedList;
21  import java.util.List;
22  import java.util.Map;
23  
24  /**
25   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
26   *
27   */
28  public class TopologicalSorter {
29  
30      private static final Integer NOT_VISITED = 0;
31  
32      private static final Integer VISITING = 1;
33  
34      private static final Integer VISITED = 2;
35  
36      /**
37       * @param graph the graph
38       * @return List of String (vertex labels)
39       */
40      public static List<String> sort(final DAG graph) {
41          return dfs(graph);
42      }
43  
44      public static List<String> sort(final Vertex vertex) {
45          // we need to use addFirst method so we will use LinkedList explicitly
46          final List<String> retValue = new LinkedList<>();
47  
48          dfsVisit(vertex, new HashMap<Vertex, Integer>(), retValue);
49  
50          return retValue;
51      }
52  
53      private static List<String> dfs(final DAG graph) {
54          // we need to use addFirst method so we will use LinkedList explicitly
55          final List<String> retValue = new LinkedList<>();
56          final Map<Vertex, Integer> vertexStateMap = new HashMap<>();
57  
58          for (Vertex vertex : graph.getVertices()) {
59              if (isNotVisited(vertex, vertexStateMap)) {
60                  dfsVisit(vertex, vertexStateMap, retValue);
61              }
62          }
63  
64          return retValue;
65      }
66  
67      private static boolean isNotVisited(final Vertex vertex, final Map<Vertex, Integer> vertexStateMap) {
68          final Integer state = vertexStateMap.get(vertex);
69  
70          return (state == null) || NOT_VISITED.equals(state);
71      }
72  
73      private static void dfsVisit(
74              final Vertex vertex, final Map<Vertex, Integer> vertexStateMap, final List<String> list) {
75          vertexStateMap.put(vertex, VISITING);
76  
77          for (Vertex v : vertex.getChildren()) {
78              if (isNotVisited(v, vertexStateMap)) {
79                  dfsVisit(v, vertexStateMap, list);
80              }
81          }
82  
83          vertexStateMap.put(vertex, VISITED);
84  
85          list.add(vertex.getLabel());
86      }
87  }