diff --git a/klab.cli/pom.xml b/klab.cli/pom.xml index ac1bbf7d..3a6fca1b 100644 --- a/klab.cli/pom.xml +++ b/klab.cli/pom.xml @@ -44,14 +44,6 @@ - - - - com.github.vlsi.mxgraph - jgraphx - 4.2.2 - - org.integratedmodelling klab.modeler diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/observation/impl/ObservationImpl.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/observation/impl/ObservationImpl.java index 437dc7bf..56b11e6a 100644 --- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/observation/impl/ObservationImpl.java +++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/observation/impl/ObservationImpl.java @@ -232,15 +232,6 @@ public void setName(String name) { @Override public String toString() { - return "ObservationImpl{" + - "observable=" + observable + - ", geometry=" + geometry + - ", metadata=" + metadata + - ", id=" + id + - ", urn='" + urn + '\'' + - ", resolved=" + resolved + - ", value=" + value + - ", name='" + name + '\'' + - '}'; + return "(OBS) " + observable + " [#" + geometry.size() + "]"; } } diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/resolver/objects/ObservationStrategyImpl.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/resolver/objects/ObservationStrategyImpl.java index ea6e92f6..15260937 100644 --- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/resolver/objects/ObservationStrategyImpl.java +++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/resolver/objects/ObservationStrategyImpl.java @@ -61,6 +61,14 @@ public List> getContextualStrategies() { public void setContextualStrategies(List> contextualStrategies) { this.contextualStrategies = contextualStrategies; } + + @Override + public String toString() { + return type + + (observable != null ? (" " + observable) : "") + + (contextualizables.isEmpty() ? "" : (" " + contextualizables)) + + (contextualStrategies.isEmpty() ? "" : (" *->" + contextualStrategies.size())); + } } @Override @@ -118,15 +126,9 @@ public void setDocumentation(String documentation) { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ObservationStrategyImpl that = (ObservationStrategyImpl) o; - return Objects.equals(urn, that.urn); - } - - @Override - public int hashCode() { - return Objects.hashCode(urn); + public String toString() { + return "(S) " + + "urn='" + urn + '\'' + + ", operations=" + operations; } } diff --git a/klab.core.common/pom.xml b/klab.core.common/pom.xml index 972bbf38..3e7b691d 100644 --- a/klab.core.common/pom.xml +++ b/klab.core.common/pom.xml @@ -18,6 +18,14 @@ UTF-8 + + + + com.github.vlsi.mxgraph + jgraphx + 4.2.2 + + org.integratedmodelling klab.core.api diff --git a/klab.core.common/src/main/java/org/integratedmodelling/common/knowledge/ObservableImpl.java b/klab.core.common/src/main/java/org/integratedmodelling/common/knowledge/ObservableImpl.java index 785c7f8b..f00e7061 100644 --- a/klab.core.common/src/main/java/org/integratedmodelling/common/knowledge/ObservableImpl.java +++ b/klab.core.common/src/main/java/org/integratedmodelling/common/knowledge/ObservableImpl.java @@ -490,7 +490,7 @@ public boolean equals(Object obj) { @Override public String toString() { - return org.integratedmodelling.common.utils.Utils.Strings.capitalize(getDescriptionType().getVerbalForm().toLowerCase()) + " " + urn; + return "(O) " + urn; } } diff --git a/klab.core.common/src/main/java/org/integratedmodelling/common/utils/Utils.java b/klab.core.common/src/main/java/org/integratedmodelling/common/utils/Utils.java index 2f38ce9d..ca971dac 100644 --- a/klab.core.common/src/main/java/org/integratedmodelling/common/utils/Utils.java +++ b/klab.core.common/src/main/java/org/integratedmodelling/common/utils/Utils.java @@ -10,9 +10,11 @@ import com.google.common.net.HttpHeaders; import com.google.common.net.MediaType; import com.jcraft.jsch.JSch; +import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.view.mxGraph; import org.integratedmodelling.common.data.jackson.JacksonConfiguration; import org.integratedmodelling.common.logging.Logging; -import org.integratedmodelling.common.services.client.scope.ClientSessionScope; import org.integratedmodelling.klab.api.ServicesAPI; import org.integratedmodelling.klab.api.collections.Pair; import org.integratedmodelling.klab.api.collections.Parameters; @@ -25,15 +27,14 @@ import org.integratedmodelling.klab.api.scope.Scope; import org.integratedmodelling.klab.api.scope.SessionScope; import org.integratedmodelling.klab.api.services.KlabService; -import org.integratedmodelling.klab.api.services.resolver.ResolutionConstraint; import org.integratedmodelling.klab.api.services.runtime.Message; import org.integratedmodelling.klab.api.services.runtime.Notification; +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultDirectedGraph; import org.springframework.web.util.UriUtils; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import javax.swing.*; +import java.io.*; import java.lang.reflect.Array; import java.net.*; import java.net.http.HttpClient; @@ -45,6 +46,190 @@ public class Utils extends org.integratedmodelling.klab.api.utils.Utils { + public static class Graphs { + + public enum Layout { + HIERARCHICAL, RADIALTREE, SIMPLE, SPRING + } + + public static void show(Graph graph, String title) { + show(graph, title, Layout.SPRING); + } + + + /** + * Dump the graph on the console using ASCII only, ignoring cyclic relationships + * + * @param graph + */ + public static String dump(Graph graph) { + + /* + Find out which nodes are "root" + */ + List roots= new ArrayList<>(); + for (V vertex : graph.vertexSet()) { + if (graph.incomingEdgesOf(vertex).isEmpty()) { + roots.add(vertex); + } + } + + StringBuffer buffer = new StringBuffer(1024); + + for (V root : roots) { + if (!buffer.isEmpty()) { + buffer.append("\n"); + } + dump(root, graph, buffer, 0); + } + + return buffer.toString(); + + } + + private static void dump(V root, Graph graph, StringBuffer buffer, int offset) { + + var spacer = Utils.Strings.spaces(offset); + buffer.append(spacer).append(root.toString()).append("\n"); + for (E edge : graph.outgoingEdgesOf(root)) { + dump(graph.getEdgeTarget(edge), graph, buffer, offset + 3); + } + } + + + public static void show(Graph graph, String title, Layout layout) { + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + @SuppressWarnings("unchecked") + GraphPanel panel = new GraphPanel(title, (Graph) graph, layout); + panel.showGraph(); + } + + }); + } + + @SuppressWarnings("unchecked") + private static Graph adaptContribGraph(Graph graph, + Class edgeClass) { + + DefaultDirectedGraph ret = new DefaultDirectedGraph(edgeClass); + for (Object o : graph.vertexSet()) { + ret.addVertex(o); + } + for (Object e : graph.edgeSet()) { + ret.addEdge(graph.getEdgeSource((E) e), graph.getEdgeTarget((E) e), (E) e); + } + return ret; + } + +// /** +// * Show the dependency graph in the loader. +// */ +// public static void showDependencies() { +// show(((KimLoader) Resources.INSTANCE.getLoader()).getDependencyGraph(), "Dependencies", DefaultEdge.class); +// } + + /** + * Return whether precursor has a directed edge to dependent in graph. + * + * @param + * @param + * @param dependent + * @param precursor + * @param graph + * @return true if dependency exists + */ + public static boolean dependsOn(V dependent, V precursor, Graph graph) { + + for (E o : graph.incomingEdgesOf(dependent)) { + if (graph.getEdgeSource(o).equals(precursor)) { + return true; + } + } + return false; + } + + /** + * Shallow copy of graph into another. + * + * @param + * @param + * @param graph + * @param newGraph + * @return same graph passed as receiver + */ + public static Graph copy(Graph graph, Graph newGraph) { + for (V vertex : graph.vertexSet()) { + newGraph.addVertex(vertex); + } + for (E edge : graph.edgeSet()) { + newGraph.addEdge(graph.getEdgeSource(edge), graph.getEdgeTarget(edge), edge); + } + return newGraph; + } + + + static class GraphPanel extends JFrame { + + /** + * + */ + @Serial + private static final long serialVersionUID = -2707712944901661771L; + + public GraphPanel(String title, Graph sourceGraph, Graphs.Layout layout) { + + super(title); + + mxGraph graph = new mxGraph(); + Object parent = graph.getDefaultParent(); + graph.getModel().beginUpdate(); + + try { + + Map vertices = new HashMap<>(); + for (Object v : sourceGraph.vertexSet()) { + vertices.put(v, graph.insertVertex(parent, null, v.toString(), 20, 20, v.toString().length() * 6, 30)); + } + for (Object v : sourceGraph.edgeSet()) { + graph.insertEdge(parent, null, v.toString(), vertices.get(sourceGraph.getEdgeSource(v)), + vertices.get(sourceGraph.getEdgeTarget(v))); + } + + } finally { + graph.getModel().endUpdate(); + } + + switch (layout) { + case HIERARCHICAL: + break; + case RADIALTREE: + break; + case SIMPLE: + break; + case SPRING: + new mxHierarchicalLayout(graph).execute(graph.getDefaultParent()); + break; + default: + break; + + } + + mxGraphComponent graphComponent = new mxGraphComponent(graph); + getContentPane().add(graphComponent); + } + + public void showGraph() { + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setSize(400, 320); + setVisible(true); + } + } + } + public static class SSH { public static Collection readHostFile() { diff --git a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java index 35cb1cb8..c9dff5ce 100644 --- a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java +++ b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java @@ -2,6 +2,7 @@ import org.integratedmodelling.common.runtime.ActuatorImpl; import org.integratedmodelling.common.runtime.DataflowImpl; +import org.integratedmodelling.common.utils.Utils; import org.integratedmodelling.klab.api.collections.Pair; import org.integratedmodelling.klab.api.collections.Triple; import org.integratedmodelling.klab.api.geometry.Geometry; @@ -27,7 +28,7 @@ public Dataflow compile(ResolutionGraph resolutionGraph, ContextSco return Dataflow.empty(Observation.class); } - + System.out.println(Utils.Graphs.dump(resolutionGraph.graph())); var ret = new DataflowImpl(); for (var node : resolutionGraph.rootNodes()) { @@ -158,13 +159,13 @@ private Actuator compileActuator(Resolvable resolvable, ResolutionGraph resoluti // // TODO // return null; // } - - private ServiceCall getServiceCall(Contextualizable computation) { - if (computation.getServiceCall() != null) { - return computation.getServiceCall(); - } - return null; - } +// +// private ServiceCall getServiceCall(Contextualizable computation) { +// if (computation.getServiceCall() != null) { +// return computation.getServiceCall(); +// } +// return null; +// } /* * The actuator ID is also the observation ID when the actuator runs. It reflects the context diff --git a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolutionGraph.java b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolutionGraph.java index eba99901..298a5096 100644 --- a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolutionGraph.java +++ b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolutionGraph.java @@ -148,7 +148,7 @@ public boolean merge(ResolutionGraph childGraph) { */ this.graph.addVertex(this.target); this.graph.addVertex(childGraph.target); - this.graph.addEdge(childGraph.target, this.target, new ResolutionEdge(childGraph.targetCoverage)); + this.graph.addEdge(this.target, childGraph.target, new ResolutionEdge(childGraph.targetCoverage)); /* ...by the amount determined in its coverage, "painting" the incoming extents onto ours.