From 8cdd39d5269259fd9a0f1ef7b04884e1deae1dae Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 26 Apr 2026 20:47:39 +0200 Subject: [PATCH 1/8] Upgrade pom and GH actions to gephi 0.11-SNAPSHOT --- .github/workflows/ci.yml | 8 ++--- .github/workflows/pr.yml | 6 ++-- pom.xml | 66 +++++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c1ceb3..28957f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,13 +8,13 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Maven Central Repository - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: - java-version: '11' + java-version: '17' distribution: 'temurin' - server-id: ossrh + server-id: central server-username: OSSRH_USER server-password: OSSRH_PASS gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c856f3d..dd051cf 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,16 +8,16 @@ jobs: strategy: matrix: os: [ubuntu-latest] - java: ['11', '17'] + java: ['17'] distribution: ['temurin'] fail-fast: false name: ${{ matrix.os }} JDK ${{ matrix.distribution }} ${{ matrix.java }} steps: - name: Git checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Set up JDK id: setupjdk - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: distribution: ${{ matrix.distribution }} java-version: ${{ matrix.java }} diff --git a/pom.xml b/pom.xml index 983a0e5..9b0e068 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.gephi gephi-toolkit - 0.10.2-SNAPSHOT + 0.11.0-SNAPSHOT jar gephi-toolkit @@ -60,13 +60,13 @@ ${netbeans.run.params.ide} - RELEASE160 + RELEASE290 ${project.version} - 11 + 17 -Xlint:all true true @@ -75,11 +75,7 @@ 768M ${project.build.directory}/surefire-reports/plain - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - + git @@ -88,23 +84,23 @@ - 3.3.0 + 3.7.1 - 3.10.0 + 3.13.0 3.0.1 - 3.4.1 + 3.7.0 - 2.22.2 + 3.2.5 - 3.11.0 - - 1.6.12 + 3.12.1 4.1 - 3.2.1 + 3.5.0 + + 0.10.0 @@ -117,22 +113,17 @@ - oss-sonatype - oss-sonatype - https://oss.sonatype.org/content/repositories/snapshots/ + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + true - - - - - ${gephi.ossrh.repository.id} - ${gephi.ossrh.repository.url} - - @@ -362,6 +353,12 @@ maven-enforcer-plugin ${gephi.maven-enforcer-plugin.version} + + org.sonatype.central + central-publishing-maven-plugin + ${gephi.central-publishing-maven-plugin.version} + true + @@ -416,7 +413,7 @@ true false none - 11 + 17 Gephi Toolkit ${project.version} API Index @@ -453,16 +450,15 @@ - - + + - org.sonatype.plugins - nexus-staging-maven-plugin + org.sonatype.central + central-publishing-maven-plugin true - ossrh - https://oss.sonatype.org/ - true + central + true From d968a70a621409d9209f75aa06e7eb8bef87254d Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sat, 2 May 2026 14:00:08 +0200 Subject: [PATCH 2/8] Simplify the tests with new Workspace option from process() --- src/test/java/org/gephi/toolkit/GeneratorTest.java | 12 +++++------- src/test/java/org/gephi/toolkit/ImportTest.java | 13 +++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/gephi/toolkit/GeneratorTest.java b/src/test/java/org/gephi/toolkit/GeneratorTest.java index 022be5c..c0d9cd4 100644 --- a/src/test/java/org/gephi/toolkit/GeneratorTest.java +++ b/src/test/java/org/gephi/toolkit/GeneratorTest.java @@ -36,6 +36,7 @@ */ package org.gephi.toolkit; +import org.gephi.graph.api.GraphModel; import org.gephi.io.generator.plugin.DynamicGraph; import org.gephi.io.generator.plugin.RandomGraph; import org.gephi.io.importer.api.Container; @@ -50,8 +51,6 @@ public class GeneratorTest extends ToolkitTest { @Test public void testGenerate() { - Workspace workspace = Utils.newWorkspace(); - //Generate a new random graph into a container Container container = Lookup.getDefault().lookup(Container.Factory.class).newContainer(); RandomGraph randomGraph = new RandomGraph(); @@ -60,7 +59,7 @@ public void testGenerate() { randomGraph.generate(container.getLoader()); //Append container to graph structure - importController.process(container, new DefaultProcessor(), workspace); + Workspace workspace = importController.process(container); Assert.assertEquals(randomGraph.getNumberOfNodes(), graphController.getGraphModel(workspace).getGraph().getNodeCount()); @@ -68,15 +67,14 @@ public void testGenerate() { @Test public void testGenerateDynamicGraph() { - Workspace workspace = Utils.newWorkspace(); - //Generate dynamic graph into workspace Container container = Lookup.getDefault().lookup(Container.Factory.class).newContainer(); DynamicGraph dynamicGraph = new DynamicGraph(); dynamicGraph.generate(container.getLoader()); - importController.process(container, new DefaultProcessor(), workspace); + Workspace workspace = importController.process(container); - Assert.assertTrue(graphController.getGraphModel(workspace).isDynamic()); + GraphModel graphModel = graphController.getGraphModel(workspace); + Assert.assertTrue(graphModel.isDynamic()); } } diff --git a/src/test/java/org/gephi/toolkit/ImportTest.java b/src/test/java/org/gephi/toolkit/ImportTest.java index c3d64b0..3f2b78d 100644 --- a/src/test/java/org/gephi/toolkit/ImportTest.java +++ b/src/test/java/org/gephi/toolkit/ImportTest.java @@ -45,6 +45,7 @@ import org.gephi.io.processor.plugin.DefaultProcessor; import org.gephi.io.processor.plugin.MergeProcessor; import org.gephi.project.api.Project; +import org.gephi.project.api.Workspace; import org.junit.Assert; import org.junit.Test; @@ -52,8 +53,6 @@ public class ImportTest extends ToolkitTest { @Test public void testImport() throws IOException, URISyntaxException { - Project project = projectController.newProject(); - //Import file File file = new File(getClass().getResource("/org/gephi/toolkit/lesmiserables.gml").toURI()); Container container = importController.importFile(file); @@ -61,18 +60,16 @@ public void testImport() throws IOException, URISyntaxException { container.getLoader().setAllowAutoNode(false); //Don't create missing nodes //Append imported data to GraphAPI - importController.process(container, new DefaultProcessor(), project.getCurrentWorkspace()); + Workspace workspace = importController.process(container); //Assert - GraphModel graphModel = graphController.getGraphModel(project.getCurrentWorkspace()); + GraphModel graphModel = graphController.getGraphModel(workspace); Assert.assertEquals(77, graphModel.getGraph().getNodeCount()); Assert.assertEquals(254, graphModel.getGraph().getEdgeCount()); } @Test public void testImportSlices() throws IOException, URISyntaxException { - Project project = projectController.newProject(); - Container[] containers = new Container[3]; for (int i = 0; i < 3; i++) { File file = new File(getClass().getResource("/org/gephi/toolkit/timeframe" + (i + 1) + ".gexf").toURI()); @@ -80,10 +77,10 @@ public void testImportSlices() throws IOException, URISyntaxException { } // Process the container using the MergeProcessor - importController.process(containers, new MergeProcessor(), project.getCurrentWorkspace()); + Workspace workspace = importController.process(containers, new MergeProcessor(), null)[0]; // Assert proper merging - GraphModel graphModel = graphController.getGraphModel(project.getCurrentWorkspace()); + GraphModel graphModel = graphController.getGraphModel(workspace); Assert.assertEquals(4, graphModel.getGraph().getNodeCount()); Assert.assertEquals(4, graphModel.getGraph().getEdgeCount()); From eace69bb9e0461ee14fb734e70339b801dfb7017 Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:27:48 +0200 Subject: [PATCH 3/8] Add additional import test --- src/test/java/org/gephi/toolkit/ImportTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/org/gephi/toolkit/ImportTest.java b/src/test/java/org/gephi/toolkit/ImportTest.java index 3f2b78d..3f54dec 100644 --- a/src/test/java/org/gephi/toolkit/ImportTest.java +++ b/src/test/java/org/gephi/toolkit/ImportTest.java @@ -68,6 +68,23 @@ public void testImport() throws IOException, URISyntaxException { Assert.assertEquals(254, graphModel.getGraph().getEdgeCount()); } + @Test + public void testImportGexf() throws IOException, URISyntaxException { + //Import file + File file = new File(getClass().getResource("/org/gephi/toolkit/lesmiserables.gexf").toURI()); + Container container = importController.importFile(file); + container.getLoader().setEdgeDefault(EdgeDirectionDefault.DIRECTED); //Force DIRECTED + container.getLoader().setAllowAutoNode(false); //Don't create missing nodes + + //Append imported data to GraphAPI + Workspace workspace = importController.process(container); + + //Assert + GraphModel graphModel = graphController.getGraphModel(workspace); + Assert.assertEquals(77, graphModel.getGraph().getNodeCount()); + Assert.assertEquals(254, graphModel.getGraph().getEdgeCount()); + } + @Test public void testImportSlices() throws IOException, URISyntaxException { Container[] containers = new Container[3]; From cf806f004a61722854917343e7af5af13843ab89 Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:28:07 +0200 Subject: [PATCH 4/8] Add test for issue 52 --- .../java/org/gephi/toolkit/ProjectIOTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/java/org/gephi/toolkit/ProjectIOTest.java b/src/test/java/org/gephi/toolkit/ProjectIOTest.java index 64240c7..f83dcf0 100644 --- a/src/test/java/org/gephi/toolkit/ProjectIOTest.java +++ b/src/test/java/org/gephi/toolkit/ProjectIOTest.java @@ -39,11 +39,15 @@ import java.io.File; import java.io.IOException; import org.gephi.graph.GraphGenerator; +import org.gephi.preview.api.PreviewController; +import org.gephi.preview.api.PreviewModel; +import org.gephi.preview.api.PreviewProperty; import org.gephi.project.api.Project; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.openide.util.Lookup; public class ProjectIOTest extends ToolkitTest { @@ -70,6 +74,31 @@ public void testSave() throws IOException { assertTinyGraph(fileNotExisting); } + @Test + public void testSavePreviewModel() throws IOException { + Project project = projectController.newProject(); + + // Generate tiny graph + GraphGenerator.build(project.getCurrentWorkspace()).generateTinyGraph(); + + // Set a preview property + PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class); + PreviewModel previewModel = previewController.getModel(); + Assert.assertFalse(previewModel.getProperties().getBooleanValue(PreviewProperty.SHOW_NODE_LABELS)); + previewModel.getProperties().putValue(PreviewProperty.SHOW_NODE_LABELS, Boolean.TRUE); + + // Save + File file = new File(tempFolder.getRoot(), "testpreview.gephi"); + projectController.saveProject(project, file); + projectController.closeCurrentProject(); + + projectController.openProject(file); + PreviewModel readPreviewModel = previewController.getModel(); + Assert.assertNotSame(previewModel, readPreviewModel); + Assert.assertTrue(readPreviewModel.getProperties().getBooleanValue(PreviewProperty.SHOW_NODE_LABELS)); + projectController.closeCurrentProject(); + } + private void assertTinyGraph(File file) { projectController.closeCurrentProject(); Project project = projectController.openProject(file); From 668b4d0933c19ecfce0137d07fdad5306b190b0c Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:28:20 +0200 Subject: [PATCH 5/8] Upgrade to version 0.11.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b0e068..e5a453f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.gephi gephi-toolkit - 0.11.0-SNAPSHOT + 0.11.2 jar gephi-toolkit From 56ffc85373654c83cbc1c582ba8785794f3ad4dc Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:32:03 +0200 Subject: [PATCH 6/8] Correct URI for import test --- src/test/java/org/gephi/toolkit/ImportTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/gephi/toolkit/ImportTest.java b/src/test/java/org/gephi/toolkit/ImportTest.java index 3f54dec..dea8466 100644 --- a/src/test/java/org/gephi/toolkit/ImportTest.java +++ b/src/test/java/org/gephi/toolkit/ImportTest.java @@ -71,7 +71,7 @@ public void testImport() throws IOException, URISyntaxException { @Test public void testImportGexf() throws IOException, URISyntaxException { //Import file - File file = new File(getClass().getResource("/org/gephi/toolkit/lesmiserables.gexf").toURI()); + File file = new File(getClass().getResource("/org/gephi/toolkit/LesMiserables.gexf").toURI()); Container container = importController.importFile(file); container.getLoader().setEdgeDefault(EdgeDirectionDefault.DIRECTED); //Force DIRECTED container.getLoader().setAllowAutoNode(false); //Don't create missing nodes From 30a20b08e86b730d189cebbbc41421ff3538f2f4 Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:52:58 +0200 Subject: [PATCH 7/8] Add a bunch of additional tests --- .../java/org/gephi/toolkit/FilteringTest.java | 38 +++++++++++++++++++ .../java/org/gephi/toolkit/ImportTest.java | 14 +++++++ .../org/gephi/toolkit/singleNode.graphml | 6 +++ 3 files changed, 58 insertions(+) create mode 100644 src/test/resources/org/gephi/toolkit/singleNode.graphml diff --git a/src/test/java/org/gephi/toolkit/FilteringTest.java b/src/test/java/org/gephi/toolkit/FilteringTest.java index d77cd7b..41e4d0b 100644 --- a/src/test/java/org/gephi/toolkit/FilteringTest.java +++ b/src/test/java/org/gephi/toolkit/FilteringTest.java @@ -36,6 +36,8 @@ */ package org.gephi.toolkit; +import java.io.IOException; +import java.io.StringWriter; import org.gephi.appearance.api.AppearanceModel; import org.gephi.filters.api.Query; import org.gephi.filters.api.Range; @@ -47,6 +49,9 @@ import org.gephi.graph.api.Graph; import org.gephi.graph.api.GraphView; import org.gephi.graph.api.Node; +import org.gephi.io.exporter.plugin.ExporterGraphML; +import org.gephi.io.exporter.spi.CharacterExporter; +import org.gephi.io.exporter.spi.Exporter; import org.gephi.project.api.Project; import org.gephi.project.api.Workspace; import org.junit.Assert; @@ -111,6 +116,39 @@ public void testPartitionFilter() { Assert.assertTrue(filteredGraph.contains(graph.getNode(GraphGenerator.SECOND_NODE))); } + @Test + public void testExportToLabelVisible() { + // Reproduces gephi/gephi-toolkit-demos#5: filterController.exportToLabelVisible(query) + // should set label visibility to true for nodes matching the query and false for the rest. + Project project = projectController.newProject(); + Workspace workspace = project.getCurrentWorkspace(); + + Graph graph = GraphGenerator.build(workspace).generateTinyGraph().getGraph(); + + // Add one extra isolated node — degree filter will exclude it + Node isolated = graph.getModel().factory().newNode("isolated"); + graph.addNode(isolated); + + // Ensure all labels start visible + for (Node n : graph.getNodes()) { + n.getTextProperties().setVisible(true); + } + + DegreeRangeBuilder.DegreeRangeFilter degreeFilter = new DegreeRangeBuilder.DegreeRangeFilter(); + degreeFilter.init(graph); + degreeFilter.setRange(new Range(1, Integer.MAX_VALUE)); + Query query = filterController.createQuery(degreeFilter); + + filterController.exportToLabelVisible(query); + + Assert.assertFalse("Isolated node's label should be hidden after exportToLabelVisible", + isolated.getTextProperties().isVisible()); + Assert.assertTrue("Connected node's label should remain visible", + graph.getNode(GraphGenerator.FIRST_NODE).getTextProperties().isVisible()); + Assert.assertTrue("Connected node's label should remain visible", + graph.getNode(GraphGenerator.SECOND_NODE).getTextProperties().isVisible()); + } + @Test public void testAndOperator() { Project project = projectController.newProject(); diff --git a/src/test/java/org/gephi/toolkit/ImportTest.java b/src/test/java/org/gephi/toolkit/ImportTest.java index dea8466..ed2d3ae 100644 --- a/src/test/java/org/gephi/toolkit/ImportTest.java +++ b/src/test/java/org/gephi/toolkit/ImportTest.java @@ -85,6 +85,20 @@ public void testImportGexf() throws IOException, URISyntaxException { Assert.assertEquals(254, graphModel.getGraph().getEdgeCount()); } + @Test + public void testImportGraphMLSingleIsolatedNode() throws IOException, URISyntaxException { + // Reproduces gephi/gephi-toolkit-demos#8: a GraphML file with a single isolated node + // was reported to import as 0 nodes. + File file = new File(getClass().getResource("/org/gephi/toolkit/singleNode.graphml").toURI()); + Container container = importController.importFile(file); + + Workspace workspace = importController.process(container); + + GraphModel graphModel = graphController.getGraphModel(workspace); + Assert.assertEquals(1, graphModel.getGraph().getNodeCount()); + Assert.assertEquals(0, graphModel.getGraph().getEdgeCount()); + } + @Test public void testImportSlices() throws IOException, URISyntaxException { Container[] containers = new Container[3]; diff --git a/src/test/resources/org/gephi/toolkit/singleNode.graphml b/src/test/resources/org/gephi/toolkit/singleNode.graphml new file mode 100644 index 0000000..ec7499c --- /dev/null +++ b/src/test/resources/org/gephi/toolkit/singleNode.graphml @@ -0,0 +1,6 @@ + + + + + + From 0e439bd64fc7bb5ae031b9fa8d5a27cd7c5bbd46 Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 28 Jun 2026 16:58:43 +0200 Subject: [PATCH 8/8] Upgrade README --- README.md | 62 ++++++------------------------------------------------- 1 file changed, 6 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 46bf72a..6dd3c0e 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,14 @@ Best way to start is through examples on [Toolkit Demos](https://github.com/geph org.gephi gephi-toolkit - 0.10.1 + 0.11.2 ``` #### From a Gradle project ``` -compile 'org.gephi:gephi-toolkit:0.10.1' +compile 'org.gephi:gephi-toolkit:0.11.2' ``` #### From a Scala SBT Project @@ -39,57 +39,7 @@ resolvers ++= Seq( "gephi-thirdparty" at "https://raw.github.com/gephi/gephi/mvn-thirdparty-repo/" ) -libraryDependencies += "org.gephi" % "gephi-toolkit" % "0.10.1" classifier "all" -``` - -## Latest releases - -### Stable - -- Latest stable release on [gephi.org](http://gephi.org/toolkit). - -### Development Build - -- [gephi-toolkit-0.10.2-SNAPSHOT-all.jar](https://oss.sonatype.org/service/local/artifact/maven/content?r=snapshots&g=org.gephi&a=gephi-toolkit&v=0.10-2-SNAPSHOT&c=all) - -### Development Build (Maven) - -If you use Maven you can directly depend on the latest development version of the toolkit (i.e the -SNAPSHOT version). - -- Add the Gephi repository - -```xml - -... - - - oss-sonatype - oss-sonatype - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - -... - -``` - -- Add the dependency - -```xml - -... - - - org.gephi - gephi-toolkit - 0.10.2-SNAPSHOT - - ... - -... - +libraryDependencies += "org.gephi" % "gephi-toolkit" % "0.11.2" classifier "all" ``` ## Build @@ -100,7 +50,7 @@ It sources its Gephi dependencies from [Maven Central](https://central.sonatype. ### Requirements -- Java JDK 11. +- Java JDK 17. - [Apache Maven](http://maven.apache.org/) version 3.6.3 or later @@ -116,8 +66,8 @@ It sources its Gephi dependencies from [Maven Central](https://central.sonatype. ### Can the Toolkit use plugins? -Yes that is possible if the plug-in doesn’t depend on something not included in the Toolkit, for instance the UI. If that happens, it is likely that the plug-in has been divided in several modules, and in that case one need only the core and can exclude the UI. -Consult this [HowTo](https://github.com/gephi/gephi/wiki/How-to-use-plug-ins-with-the-Toolkit) page to know how to extract the plugin JARs from the NBM file. Once you have the JARs, include them in your project’s classpath, in addition of the Gephi Toolkit. +Yes, that is possible if the plug-in doesn’t depend on something not included in the Toolkit, for instance the UI. If that happens, it is likely that the plug-in has been divided in several modules, and in that case one need only the core and can exclude the UI. +We recommend pulling JAR dependencies directly from Maven Central. ### Can it depends on a development version of Gephi?