mirror of https://github.com/pf4j/pf4j.git
Decebal Suiu
10 years ago
47 changed files with 510 additions and 510 deletions
@ -1,93 +1,93 @@ |
|||||||
/* |
/* |
||||||
* Copyright 2012 Decebal Suiu |
* Copyright 2012 Decebal Suiu |
||||||
* |
* |
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||||
* |
* |
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* |
* |
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
* specific language governing permissions and limitations under the License. |
* specific language governing permissions and limitations under the License. |
||||||
*/ |
*/ |
||||||
package ro.fortsoft.pf4j.demo; |
package ro.fortsoft.pf4j.demo; |
||||||
|
|
||||||
import java.util.List; |
import java.util.List; |
||||||
import java.util.Set; |
import java.util.Set; |
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils; |
import org.apache.commons.lang.StringUtils; |
||||||
|
|
||||||
import ro.fortsoft.pf4j.DefaultPluginManager; |
import ro.fortsoft.pf4j.DefaultPluginManager; |
||||||
import ro.fortsoft.pf4j.PluginManager; |
import ro.fortsoft.pf4j.PluginManager; |
||||||
import ro.fortsoft.pf4j.PluginWrapper; |
import ro.fortsoft.pf4j.PluginWrapper; |
||||||
import ro.fortsoft.pf4j.demo.api.Greeting; |
import ro.fortsoft.pf4j.demo.api.Greeting; |
||||||
|
|
||||||
/** |
/** |
||||||
* A boot class that start the demo. |
* A boot class that start the demo. |
||||||
* |
* |
||||||
* @author Decebal Suiu |
* @author Decebal Suiu |
||||||
*/ |
*/ |
||||||
public class Boot { |
public class Boot { |
||||||
|
|
||||||
public static void main(String[] args) { |
public static void main(String[] args) { |
||||||
// print logo
|
// print logo
|
||||||
printLogo(); |
printLogo(); |
||||||
|
|
||||||
// create the plugin manager
|
// create the plugin manager
|
||||||
final PluginManager pluginManager = new DefaultPluginManager(); |
final PluginManager pluginManager = new DefaultPluginManager(); |
||||||
|
|
||||||
// load the plugins
|
// load the plugins
|
||||||
pluginManager.loadPlugins(); |
pluginManager.loadPlugins(); |
||||||
|
|
||||||
// enable a disabled plugin
|
// enable a disabled plugin
|
||||||
// pluginManager.enablePlugin("welcome-plugin");
|
// pluginManager.enablePlugin("welcome-plugin");
|
||||||
|
|
||||||
// start (active/resolved) the plugins
|
// start (active/resolved) the plugins
|
||||||
pluginManager.startPlugins(); |
pluginManager.startPlugins(); |
||||||
|
|
||||||
// retrieves the extensions for Greeting extension point
|
// retrieves the extensions for Greeting extension point
|
||||||
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); |
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); |
||||||
System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName())); |
System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName())); |
||||||
for (Greeting greeting : greetings) { |
for (Greeting greeting : greetings) { |
||||||
System.out.println(">>> " + greeting.getGreeting()); |
System.out.println(">>> " + greeting.getGreeting()); |
||||||
} |
} |
||||||
|
|
||||||
// print extensions from classpath (non plugin)
|
// print extensions from classpath (non plugin)
|
||||||
System.out.println(String.format("Extensions added by classpath:")); |
System.out.println(String.format("Extensions added by classpath:")); |
||||||
Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null); |
Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null); |
||||||
for (String extension : extensionClassNames) { |
for (String extension : extensionClassNames) { |
||||||
System.out.println(" " + extension); |
System.out.println(" " + extension); |
||||||
} |
} |
||||||
|
|
||||||
// print extensions for each started plugin
|
// print extensions for each started plugin
|
||||||
List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins(); |
List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins(); |
||||||
for (PluginWrapper plugin : startedPlugins) { |
for (PluginWrapper plugin : startedPlugins) { |
||||||
String pluginId = plugin.getDescriptor().getPluginId(); |
String pluginId = plugin.getDescriptor().getPluginId(); |
||||||
System.out.println(String.format("Extensions added by plugin '%s':", pluginId)); |
System.out.println(String.format("Extensions added by plugin '%s':", pluginId)); |
||||||
extensionClassNames = pluginManager.getExtensionClassNames(pluginId); |
extensionClassNames = pluginManager.getExtensionClassNames(pluginId); |
||||||
for (String extension : extensionClassNames) { |
for (String extension : extensionClassNames) { |
||||||
System.out.println(" " + extension); |
System.out.println(" " + extension); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
// stop the plugins
|
// stop the plugins
|
||||||
pluginManager.stopPlugins(); |
pluginManager.stopPlugins(); |
||||||
/* |
/* |
||||||
Runtime.getRuntime().addShutdownHook(new Thread() { |
Runtime.getRuntime().addShutdownHook(new Thread() { |
||||||
|
|
||||||
@Override |
@Override |
||||||
public void run() { |
public void run() { |
||||||
pluginManager.stopPlugins(); |
pluginManager.stopPlugins(); |
||||||
} |
} |
||||||
|
|
||||||
}); |
}); |
||||||
*/ |
*/ |
||||||
} |
} |
||||||
|
|
||||||
private static void printLogo() { |
private static void printLogo() { |
||||||
System.out.println(StringUtils.repeat("#", 40)); |
System.out.println(StringUtils.repeat("#", 40)); |
||||||
System.out.println(StringUtils.center("PF4J-DEMO", 40)); |
System.out.println(StringUtils.center("PF4J-DEMO", 40)); |
||||||
System.out.println(StringUtils.repeat("#", 40)); |
System.out.println(StringUtils.repeat("#", 40)); |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,96 +1,96 @@ |
|||||||
/* |
/* |
||||||
* Copyright 2012 Decebal Suiu |
* Copyright 2012 Decebal Suiu |
||||||
* |
* |
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||||
* |
* |
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* |
* |
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
* specific language governing permissions and limitations under the License. |
* specific language governing permissions and limitations under the License. |
||||||
*/ |
*/ |
||||||
package ro.fortsoft.pf4j.demo; |
package ro.fortsoft.pf4j.demo; |
||||||
|
|
||||||
import java.util.List; |
import java.util.List; |
||||||
import java.util.Set; |
import java.util.Set; |
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils; |
import org.apache.commons.lang3.StringUtils; |
||||||
|
|
||||||
import ro.fortsoft.pf4j.DefaultPluginManager; |
import ro.fortsoft.pf4j.DefaultPluginManager; |
||||||
import ro.fortsoft.pf4j.PluginManager; |
import ro.fortsoft.pf4j.PluginManager; |
||||||
import ro.fortsoft.pf4j.PluginWrapper; |
import ro.fortsoft.pf4j.PluginWrapper; |
||||||
import ro.fortsoft.pf4j.demo.api.Greeting; |
import ro.fortsoft.pf4j.demo.api.Greeting; |
||||||
|
|
||||||
/** |
/** |
||||||
* A boot class that start the demo. |
* A boot class that start the demo. |
||||||
* |
* |
||||||
* @author Decebal Suiu |
* @author Decebal Suiu |
||||||
*/ |
*/ |
||||||
public class Boot { |
public class Boot { |
||||||
|
|
||||||
public static void main(String[] args) { |
public static void main(String[] args) { |
||||||
// print logo
|
// print logo
|
||||||
printLogo(); |
printLogo(); |
||||||
|
|
||||||
// create the plugin manager
|
// create the plugin manager
|
||||||
final PluginManager pluginManager = new DefaultPluginManager(); |
final PluginManager pluginManager = new DefaultPluginManager(); |
||||||
|
|
||||||
// load the plugins
|
// load the plugins
|
||||||
pluginManager.loadPlugins(); |
pluginManager.loadPlugins(); |
||||||
|
|
||||||
// enable a disabled plugin
|
// enable a disabled plugin
|
||||||
// pluginManager.enablePlugin("welcome-plugin");
|
// pluginManager.enablePlugin("welcome-plugin");
|
||||||
|
|
||||||
// start (active/resolved) the plugins
|
// start (active/resolved) the plugins
|
||||||
pluginManager.startPlugins(); |
pluginManager.startPlugins(); |
||||||
|
|
||||||
System.out.println("Plugindirectory: "); |
System.out.println("Plugindirectory: "); |
||||||
System.out.println("\t" + System.getProperty("pf4j.pluginsDir", "plugins") + "\n"); |
System.out.println("\t" + System.getProperty("pf4j.pluginsDir", "plugins") + "\n"); |
||||||
|
|
||||||
// retrieves the extensions for Greeting extension point
|
// retrieves the extensions for Greeting extension point
|
||||||
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); |
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); |
||||||
System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName())); |
System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName())); |
||||||
for (Greeting greeting : greetings) { |
for (Greeting greeting : greetings) { |
||||||
System.out.println(">>> " + greeting.getGreeting()); |
System.out.println(">>> " + greeting.getGreeting()); |
||||||
} |
} |
||||||
|
|
||||||
// // print extensions from classpath (non plugin)
|
// // print extensions from classpath (non plugin)
|
||||||
// System.out.println(String.format("Extensions added by classpath:"));
|
// System.out.println(String.format("Extensions added by classpath:"));
|
||||||
// Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
|
// Set<String> extensionClassNames = pluginManager.getExtensionClassNames(null);
|
||||||
// for (String extension : extensionClassNames) {
|
// for (String extension : extensionClassNames) {
|
||||||
// System.out.println(" " + extension);
|
// System.out.println(" " + extension);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// print extensions for each started plugin
|
// print extensions for each started plugin
|
||||||
List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins(); |
List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins(); |
||||||
for (PluginWrapper plugin : startedPlugins) { |
for (PluginWrapper plugin : startedPlugins) { |
||||||
String pluginId = plugin.getDescriptor().getPluginId(); |
String pluginId = plugin.getDescriptor().getPluginId(); |
||||||
System.out.println(String.format("Extensions added by plugin '%s':", pluginId)); |
System.out.println(String.format("Extensions added by plugin '%s':", pluginId)); |
||||||
// extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
|
// extensionClassNames = pluginManager.getExtensionClassNames(pluginId);
|
||||||
// for (String extension : extensionClassNames) {
|
// for (String extension : extensionClassNames) {
|
||||||
// System.out.println(" " + extension);
|
// System.out.println(" " + extension);
|
||||||
// }
|
// }
|
||||||
} |
} |
||||||
|
|
||||||
// stop the plugins
|
// stop the plugins
|
||||||
pluginManager.stopPlugins(); |
pluginManager.stopPlugins(); |
||||||
/* |
/* |
||||||
Runtime.getRuntime().addShutdownHook(new Thread() { |
Runtime.getRuntime().addShutdownHook(new Thread() { |
||||||
|
|
||||||
@Override |
@Override |
||||||
public void run() { |
public void run() { |
||||||
pluginManager.stopPlugins(); |
pluginManager.stopPlugins(); |
||||||
} |
} |
||||||
|
|
||||||
}); |
}); |
||||||
*/ |
*/ |
||||||
} |
} |
||||||
|
|
||||||
private static void printLogo() { |
private static void printLogo() { |
||||||
System.out.println(StringUtils.repeat("#", 40)); |
System.out.println(StringUtils.repeat("#", 40)); |
||||||
System.out.println(StringUtils.center("PF4J-DEMO", 40)); |
System.out.println(StringUtils.center("PF4J-DEMO", 40)); |
||||||
System.out.println(StringUtils.repeat("#", 40)); |
System.out.println(StringUtils.repeat("#", 40)); |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,171 +1,171 @@ |
|||||||
/* |
/* |
||||||
* Copyright 2012 Decebal Suiu |
* Copyright 2012 Decebal Suiu |
||||||
* |
* |
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||||
* |
* |
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* |
* |
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
* specific language governing permissions and limitations under the License. |
* specific language governing permissions and limitations under the License. |
||||||
*/ |
*/ |
||||||
package ro.fortsoft.pf4j.util; |
package ro.fortsoft.pf4j.util; |
||||||
|
|
||||||
import java.util.ArrayList; |
import java.util.ArrayList; |
||||||
import java.util.Collections; |
import java.util.Collections; |
||||||
import java.util.HashMap; |
import java.util.HashMap; |
||||||
import java.util.List; |
import java.util.List; |
||||||
import java.util.Map; |
import java.util.Map; |
||||||
import java.util.Stack; |
import java.util.Stack; |
||||||
|
|
||||||
/** |
/** |
||||||
* @author Decebal Suiu |
* @author Decebal Suiu |
||||||
*/ |
*/ |
||||||
public class DirectedGraph<V> { |
public class DirectedGraph<V> { |
||||||
|
|
||||||
/** |
/** |
||||||
* The implementation here is basically an adjacency list, but instead |
* The implementation here is basically an adjacency list, but instead |
||||||
* of an array of lists, a Map is used to map each vertex to its list of |
* of an array of lists, a Map is used to map each vertex to its list of |
||||||
* adjacent vertices. |
* adjacent vertices. |
||||||
*/ |
*/ |
||||||
private Map<V, List<V>> neighbors = new HashMap<V, List<V>>(); |
private Map<V, List<V>> neighbors = new HashMap<V, List<V>>(); |
||||||
|
|
||||||
/** |
/** |
||||||
* Add a vertex to the graph. Nothing happens if vertex is already in graph. |
* Add a vertex to the graph. Nothing happens if vertex is already in graph. |
||||||
*/ |
*/ |
||||||
public void addVertex(V vertex) { |
public void addVertex(V vertex) { |
||||||
if (neighbors.containsKey(vertex)) { |
if (neighbors.containsKey(vertex)) { |
||||||
return; |
return; |
||||||
} |
} |
||||||
neighbors.put(vertex, new ArrayList<V>()); |
neighbors.put(vertex, new ArrayList<V>()); |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* True if graph contains vertex. |
* True if graph contains vertex. |
||||||
*/ |
*/ |
||||||
public boolean containsVertex(V vertex) { |
public boolean containsVertex(V vertex) { |
||||||
return neighbors.containsKey(vertex); |
return neighbors.containsKey(vertex); |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Add an edge to the graph; if either vertex does not exist, it's added. |
* Add an edge to the graph; if either vertex does not exist, it's added. |
||||||
* This implementation allows the creation of multi-edges and self-loops. |
* This implementation allows the creation of multi-edges and self-loops. |
||||||
*/ |
*/ |
||||||
public void addEdge(V from, V to) { |
public void addEdge(V from, V to) { |
||||||
this.addVertex(from); |
this.addVertex(from); |
||||||
this.addVertex(to); |
this.addVertex(to); |
||||||
neighbors.get(from).add(to); |
neighbors.get(from).add(to); |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Remove an edge from the graph. Nothing happens if no such edge. |
* Remove an edge from the graph. Nothing happens if no such edge. |
||||||
* @throws IllegalArgumentException if either vertex doesn't exist. |
* @throws IllegalArgumentException if either vertex doesn't exist. |
||||||
*/ |
*/ |
||||||
public void remove(V from, V to) { |
public void remove(V from, V to) { |
||||||
if (!(this.containsVertex(from) && this.containsVertex(to))) { |
if (!(this.containsVertex(from) && this.containsVertex(to))) { |
||||||
throw new IllegalArgumentException("Nonexistent vertex"); |
throw new IllegalArgumentException("Nonexistent vertex"); |
||||||
} |
} |
||||||
neighbors.get(from).remove(to); |
neighbors.get(from).remove(to); |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Report (as a Map) the out-degree of each vertex. |
* Report (as a Map) the out-degree of each vertex. |
||||||
*/ |
*/ |
||||||
public Map<V, Integer> outDegree() { |
public Map<V, Integer> outDegree() { |
||||||
Map<V, Integer> result = new HashMap<V, Integer>(); |
Map<V, Integer> result = new HashMap<V, Integer>(); |
||||||
for (V vertex : neighbors.keySet()) { |
for (V vertex : neighbors.keySet()) { |
||||||
result.put(vertex, neighbors.get(vertex).size()); |
result.put(vertex, neighbors.get(vertex).size()); |
||||||
} |
} |
||||||
|
|
||||||
return result; |
return result; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Report (as a Map) the in-degree of each vertex. |
* Report (as a Map) the in-degree of each vertex. |
||||||
*/ |
*/ |
||||||
public Map<V,Integer> inDegree() { |
public Map<V,Integer> inDegree() { |
||||||
Map<V, Integer> result = new HashMap<V, Integer>(); |
Map<V, Integer> result = new HashMap<V, Integer>(); |
||||||
for (V vertex : neighbors.keySet()) { |
for (V vertex : neighbors.keySet()) { |
||||||
result.put(vertex, 0); // all in-degrees are 0
|
result.put(vertex, 0); // all in-degrees are 0
|
||||||
} |
} |
||||||
for (V from : neighbors.keySet()) { |
for (V from : neighbors.keySet()) { |
||||||
for (V to : neighbors.get(from)) { |
for (V to : neighbors.get(from)) { |
||||||
result.put(to, result.get(to) + 1); // increment in-degree
|
result.put(to, result.get(to) + 1); // increment in-degree
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return result; |
return result; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Report (as a List) the topological sort of the vertices; null for no such sort. |
* Report (as a List) the topological sort of the vertices; null for no such sort. |
||||||
*/ |
*/ |
||||||
public List<V> topologicalSort() { |
public List<V> topologicalSort() { |
||||||
Map<V, Integer> degree = inDegree(); |
Map<V, Integer> degree = inDegree(); |
||||||
|
|
||||||
// determine all vertices with zero in-degree
|
// determine all vertices with zero in-degree
|
||||||
Stack<V> zeroVertices = new Stack<V>(); // stack as good as any here
|
Stack<V> zeroVertices = new Stack<V>(); // stack as good as any here
|
||||||
for (V v : degree.keySet()) { |
for (V v : degree.keySet()) { |
||||||
if (degree.get(v) == 0) { |
if (degree.get(v) == 0) { |
||||||
zeroVertices.push(v); |
zeroVertices.push(v); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
// determine the topological order
|
// determine the topological order
|
||||||
List<V> result = new ArrayList<V>(); |
List<V> result = new ArrayList<V>(); |
||||||
while (!zeroVertices.isEmpty()) { |
while (!zeroVertices.isEmpty()) { |
||||||
V vertex = zeroVertices.pop(); // choose a vertex with zero in-degree
|
V vertex = zeroVertices.pop(); // choose a vertex with zero in-degree
|
||||||
result.add(vertex); // vertex 'v' is next in topological order
|
result.add(vertex); // vertex 'v' is next in topological order
|
||||||
// "remove" vertex 'v' by updating its neighbors
|
// "remove" vertex 'v' by updating its neighbors
|
||||||
for (V neighbor : neighbors.get(vertex)) { |
for (V neighbor : neighbors.get(vertex)) { |
||||||
degree.put(neighbor, degree.get(neighbor) - 1); |
degree.put(neighbor, degree.get(neighbor) - 1); |
||||||
// remember any vertices that now have zero in-degree
|
// remember any vertices that now have zero in-degree
|
||||||
if (degree.get(neighbor) == 0) { |
if (degree.get(neighbor) == 0) { |
||||||
zeroVertices.push(neighbor); |
zeroVertices.push(neighbor); |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
// check that we have used the entire graph (if not, there was a cycle)
|
// check that we have used the entire graph (if not, there was a cycle)
|
||||||
if (result.size() != neighbors.size()) { |
if (result.size() != neighbors.size()) { |
||||||
return null; |
return null; |
||||||
} |
} |
||||||
|
|
||||||
return result; |
return result; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Report (as a List) the reverse topological sort of the vertices; null for no such sort. |
* Report (as a List) the reverse topological sort of the vertices; null for no such sort. |
||||||
*/ |
*/ |
||||||
public List<V> reverseTopologicalSort() { |
public List<V> reverseTopologicalSort() { |
||||||
List<V> list = topologicalSort(); |
List<V> list = topologicalSort(); |
||||||
if (list == null) { |
if (list == null) { |
||||||
return null; |
return null; |
||||||
} |
} |
||||||
Collections.reverse(list); |
Collections.reverse(list); |
||||||
|
|
||||||
return list; |
return list; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* True if graph is a dag (directed acyclic graph). |
* True if graph is a dag (directed acyclic graph). |
||||||
*/ |
*/ |
||||||
public boolean isDag () { |
public boolean isDag () { |
||||||
return topologicalSort() != null; |
return topologicalSort() != null; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* String representation of graph. |
* String representation of graph. |
||||||
*/ |
*/ |
||||||
@Override |
@Override |
||||||
public String toString() { |
public String toString() { |
||||||
StringBuffer sb = new StringBuffer(); |
StringBuffer sb = new StringBuffer(); |
||||||
for (V vertex : neighbors.keySet()) { |
for (V vertex : neighbors.keySet()) { |
||||||
sb.append("\n " + vertex + " -> " + neighbors.get(vertex)); |
sb.append("\n " + vertex + " -> " + neighbors.get(vertex)); |
||||||
} |
} |
||||||
|
|
||||||
return sb.toString(); |
return sb.toString(); |
||||||
} |
} |
||||||
|
|
||||||
} |
} |
||||||
|
Loading…
Reference in new issue