Skip to content

Java17 upgrade#79

Merged
rostam merged 9 commits intomasterfrom
java17-upgrade
Mar 16, 2026
Merged

Java17 upgrade#79
rostam merged 9 commits intomasterfrom
java17-upgrade

Conversation

@rostam
Copy link
Owner

@rostam rostam commented Mar 16, 2026

No description provided.

rostam and others added 9 commits March 16, 2026 10:08
- Replace Vector with ArrayList in GraphSaveObject
- Replace deprecated javax.xml.bind.DatatypeConverter with java.util.Base64
- Replace raw Enumeration/Class types with typed generics in ExtensionClassLoader
- Add try-with-resources for FileInputStream and ZipFile in ExtensionClassLoader
- Replace string concatenation in loops with StringBuilder in AlgorithmUtils
- Simplify isConnected() to use stream().distinct().count()
- Fix raw ArrayX types to ArrayX<?> across preferences classes (AbstractPreference,
  GraphPreferences, UserDefinedEligiblity, ArrowHandler)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the legacy BareBonesBrowserLaunch helper (which used reflection
to call java.awt.Desktop and fell back to long-removed com.apple.eio
and OS-specific exec hacks) with a direct Desktop.getDesktop().browse()
call, available since Java 6. Drop the now-unused Arrays import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…index reports

PiIndex, SzegedIndex, WeightedPiIndex, WeightedSzegedIndex, MostarIndex,
and RevisedSzegedIndex all shared identical Floyd-Warshall + nu/nv loop
logic. Extract that into EdgePartitionIndexBase.sum() with a functional
Contribution interface; each report now delegates with a one-liner lambda.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aph products

- Add setCircularPositions() helper + concrete setPositions() to GProduct;
  GCartesianProduct and GStrongProduct now inherit it, GTensorProduct and
  GSymmDiff override only what differs (directed flag / radius 200).
- Extract GProductAction abstract base with shared @parameter fields,
  action(), checkParameters(), getCategory(); CartesianProduct, TensorProduct,
  StrongProduct and SymDiff each reduce to getName/getDescription/createProduct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…otalGraph, EdgeSemitotalGraph, VertexSemitotalGraph

All three shared the same vertex-copy loop, edge-subdivision loop, and
curved-edge helper. They differ only in three boolean features: whether
to mark subdivision vertices with their edge, whether to add a curved
original edge, and whether to connect subdivision vertices of adjacent
edges. Extract these into SubdividedGraphBase with overridable hook
methods; each subclass is now getName/getDescription + 1-3 boolean flags.
Also removes the unused `dis` variable and deduplicates edgeConnects().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…al overrides

The vast majority of Parametrizable implementations return null unchanged.
Adding a default makes the override opt-in for classes that have real
validation, eliminating the boilerplate for all others. Existing non-null
overrides (generators, etc.) are unaffected. Remove the now-redundant
null overrides from GProductAction and SubdividedGraphBase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nergy reports

DistanceEnergy, TransmissionEnergy, DistanceLaplacianEnergy, and
DistanceSignlessLaplacianEnergy all shared the same eigenvalue-sum loop
differing only in the matrix source and an optional shift value.
Extract AlgorithmUtils.spectralEnergy(Matrix, shift) and reduce each
calculate() to a two-liner. Also removes unused `n` variable in the
two Laplacian energy reports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ibuteSetImpl.put()

- Add AlgorithmUtils.getAllPairsDistances(GraphModel) as a one-line
  convenience wrapper for the FloydWarshall two-liner that appears 40+
  times in the codebase. Migrate all 5 internal usages in AlgorithmUtils.
- NotifiableAttributeSetImpl.put() duplicated the null-check from the
  parent by bypassing super.put(). Fix: read the old value via get(),
  delegate to super.put() for the null-guard + map update, then fire.
  Also remove the trivial get() override that just calls super.get().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@qodo-code-review
Copy link

Review Summary by Qodo

Java 17 upgrade with code modernization and refactoring

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Upgrade Java source/target from 11 to 17 in build configuration
• Modernize legacy APIs: replace Vector with ArrayList, deprecated DatatypeConverter with Base64
• Extract EdgePartitionIndexBase to eliminate duplication across six topological index reports
• Refactor graph product and subdivision actions into reusable base classes
• Add helper methods for common patterns: getAllPairsDistances, spectralEnergy, setCircularPositions
• Improve type safety with generics: replace raw Class/Enumeration types with typed versions
• Add try-with-resources for FileInputStream and ZipFile in ExtensionClassLoader
• Replace legacy BareBonesBrowserLaunch with direct Desktop API call
Diagram
flowchart LR
  A["Java 11 codebase"] -->|"Upgrade JDK"| B["Java 17 target"]
  A -->|"Replace deprecated APIs"| C["Modern Java APIs"]
  A -->|"Extract duplication"| D["Reusable base classes"]
  C --> E["Base64 instead of DatatypeConverter"]
  C --> F["ArrayList instead of Vector"]
  C --> G["Direct Desktop API"]
  D --> H["EdgePartitionIndexBase"]
  D --> I["SubdividedGraphBase"]
  D --> J["GProductAction"]
  H --> K["6 topological indices simplified"]
  I --> L["3 graph transformations simplified"]
  J --> M["4 product actions simplified"]
Loading

Grey Divider

File Changes

1. src/graphtea/extensions/AlgorithmUtils.java ✨ Enhancement +66/-36

Add utility methods and improve string building

src/graphtea/extensions/AlgorithmUtils.java


2. src/graphtea/extensions/actions/EdgeSemitotalGraph.java ✨ Enhancement +5/-95

Refactor to extend SubdividedGraphBase

src/graphtea/extensions/actions/EdgeSemitotalGraph.java


3. src/graphtea/extensions/actions/SubdividedGraphBase.java ✨ Enhancement +118/-0

Extract shared subdivision logic into base class

src/graphtea/extensions/actions/SubdividedGraphBase.java


View more (34)
4. src/graphtea/extensions/actions/TotalGraph.java ✨ Enhancement +6/-105

Refactor to extend SubdividedGraphBase

src/graphtea/extensions/actions/TotalGraph.java


5. src/graphtea/extensions/actions/VertexSemitotalGraph.java ✨ Enhancement +4/-75

Refactor to extend SubdividedGraphBase

src/graphtea/extensions/actions/VertexSemitotalGraph.java


6. src/graphtea/extensions/actions/product/CartesianProduct.java ✨ Enhancement +4/-37

Refactor to extend GProductAction

src/graphtea/extensions/actions/product/CartesianProduct.java


7. src/graphtea/extensions/actions/product/GCartesianProduct.java ✨ Enhancement +3/-13

Use inherited setCircularPositions helper

src/graphtea/extensions/actions/product/GCartesianProduct.java


8. src/graphtea/extensions/actions/product/GProduct.java ✨ Enhancement +16/-1

Add setCircularPositions helper method

src/graphtea/extensions/actions/product/GProduct.java


9. src/graphtea/extensions/actions/product/GProductAction.java ✨ Enhancement +37/-0

Extract shared product action boilerplate

src/graphtea/extensions/actions/product/GProductAction.java


10. src/graphtea/extensions/actions/product/GStrongProduct.java ✨ Enhancement +4/-14

Use inherited setCircularPositions helper

src/graphtea/extensions/actions/product/GStrongProduct.java


11. src/graphtea/extensions/actions/product/GSymmDiff.java ✨ Enhancement +3/-13

Use inherited setCircularPositions helper

src/graphtea/extensions/actions/product/GSymmDiff.java


12. src/graphtea/extensions/actions/product/GTensorProduct.java ✨ Enhancement +2/-10

Use inherited setCircularPositions helper

src/graphtea/extensions/actions/product/GTensorProduct.java


13. src/graphtea/extensions/actions/product/StrongProduct.java ✨ Enhancement +4/-37

Refactor to extend GProductAction

src/graphtea/extensions/actions/product/StrongProduct.java


14. src/graphtea/extensions/actions/product/SymDiff.java ✨ Enhancement +4/-38

Refactor to extend GProductAction

src/graphtea/extensions/actions/product/SymDiff.java


15. src/graphtea/extensions/actions/product/TensorProduct.java ✨ Enhancement +4/-38

Refactor to extend GProductAction

src/graphtea/extensions/actions/product/TensorProduct.java


16. src/graphtea/extensions/io/GraphSaveObject.java 🐞 Bug fix +7/-7

Replace Vector with ArrayList and deprecated Base64 API

src/graphtea/extensions/io/GraphSaveObject.java


17. src/graphtea/extensions/reports/others/EdgePartitionIndexBase.java ✨ Enhancement +50/-0

Extract shared edge partition computation logic

src/graphtea/extensions/reports/others/EdgePartitionIndexBase.java


18. src/graphtea/extensions/reports/others/MostarIndex.java ✨ Enhancement +4/-29

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/MostarIndex.java


19. src/graphtea/extensions/reports/others/PiIndex.java ✨ Enhancement +4/-31

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/PiIndex.java


20. src/graphtea/extensions/reports/others/RevisedSzegedIndex.java ✨ Enhancement +5/-33

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/RevisedSzegedIndex.java


21. src/graphtea/extensions/reports/others/SzegedIndex.java ✨ Enhancement +4/-31

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/SzegedIndex.java


22. src/graphtea/extensions/reports/others/WeightedPiIndex.java ✨ Enhancement +7/-34

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/WeightedPiIndex.java


23. src/graphtea/extensions/reports/others/WeightedSzegedIndex.java ✨ Enhancement +7/-34

Simplify using EdgePartitionIndexBase

src/graphtea/extensions/reports/others/WeightedSzegedIndex.java


24. src/graphtea/extensions/reports/spectralreports/DistanceEnergy.java ✨ Enhancement +5/-29

Use new spectralEnergy helper method

src/graphtea/extensions/reports/spectralreports/DistanceEnergy.java


25. src/graphtea/extensions/reports/spectralreports/DistanceLaplacianEnergy.java ✨ Enhancement +6/-32

Use new spectralEnergy helper method

src/graphtea/extensions/reports/spectralreports/DistanceLaplacianEnergy.java


26. src/graphtea/extensions/reports/spectralreports/DistanceSignlessLaplacianEnergy.java ✨ Enhancement +6/-32

Use new spectralEnergy helper method

src/graphtea/extensions/reports/spectralreports/DistanceSignlessLaplacianEnergy.java


27. src/graphtea/extensions/reports/spectralreports/TransmissionEnergy.java ✨ Enhancement +5/-29

Use new spectralEnergy helper method

src/graphtea/extensions/reports/spectralreports/TransmissionEnergy.java


28. src/graphtea/graph/old/ArrowHandler.java ✨ Enhancement +2/-2

Add generic type parameters to ArrayX

src/graphtea/graph/old/ArrowHandler.java


29. src/graphtea/platform/StaticUtils.java 🐞 Bug fix +3/-37

Replace BareBonesBrowserLaunch with Desktop API

src/graphtea/platform/StaticUtils.java


30. src/graphtea/platform/attribute/NotifiableAttributeSetImpl.java ✨ Enhancement +2/-10

Simplify put method implementation

src/graphtea/platform/attribute/NotifiableAttributeSetImpl.java


31. src/graphtea/platform/extension/ExtensionClassLoader.java ✨ Enhancement +38/-47

Add generics and try-with-resources for resource management

src/graphtea/platform/extension/ExtensionClassLoader.java


32. src/graphtea/platform/parameter/Parametrizable.java ✨ Enhancement +3/-1

Add default implementation to checkParameters

src/graphtea/platform/parameter/Parametrizable.java


33. src/graphtea/platform/preferences/AbstractPreference.java ✨ Enhancement +2/-2

Add generic type parameters to ArrayX

src/graphtea/platform/preferences/AbstractPreference.java


34. src/graphtea/platform/preferences/GraphPreferences.java ✨ Enhancement +3/-3

Add generic type parameters to ArrayX

src/graphtea/platform/preferences/GraphPreferences.java


35. src/graphtea/platform/preferences/UserDefinedEligiblity.java ✨ Enhancement +1/-1

Add generic type parameters to ArrayX

src/graphtea/platform/preferences/UserDefinedEligiblity.java


36. .github/workflows/ant.yml ⚙️ Configuration changes +2/-2

Update CI Java version to 17

.github/workflows/ant.yml


37. build.xml ⚙️ Configuration changes +2/-2

Update build source and target to Java 17

build.xml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 16, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. SubdividedGraphBase.action() too nested 📘 Rule violation ⛯ Reliability
Description
The new SubdividedGraphBase.action() implementation contains control-flow nesting deeper than 4
levels due to nested loops and conditionals. This violates the configured complexity limits and
makes the method harder to read and maintain.
Code

src/graphtea/extensions/actions/SubdividedGraphBase.java[R82-94]

+        if (addSubdivisionVertexEdges()) {
+            for (Vertex v1 : g2.getVertexArray()) {
+                for (Vertex v2 : g2.getVertexArray()) {
+                    if (v1.getProp().obj != null && v2.getProp().obj != null) {
+                        Edge e1 = (Edge) v1.getProp().obj;
+                        Edge e2 = (Edge) v2.getProp().obj;
+                        if (edgeConnects(e1, e2)) {
+                            addCurvedEdge(g2, v1, v2);
+                        }
+                    }
+                }
+            }
+        }
Evidence
PR Compliance ID 9 requires nesting depth ≤ 4 for new/modified methods. The added block in
SubdividedGraphBase.action() nests if (addSubdivisionVertexEdges()) -> for -> for -> if ->
if, exceeding depth 4.

CLAUDE.md
src/graphtea/extensions/actions/SubdividedGraphBase.java[82-94]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SubdividedGraphBase.action()` exceeds the allowed nesting depth (must be ≤ 4) due to multiple nested loops and conditionals.

## Issue Context
The compliance checklist enforces nesting depth limits for new/modified methods. The newly added `if (addSubdivisionVertexEdges())` block introduces nesting deeper than 4.

## Fix Focus Areas
- src/graphtea/extensions/actions/SubdividedGraphBase.java[82-94]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Old .tea files unreadable 🐞 Bug ⛯ Reliability
Description
GraphSaveObject’s serialized field types were changed (Vector→ArrayList) without preserving
serialization compatibility, so ObjectInputStream deserialization of previously saved “.tea” files
can fail and LoadGraph.read will return null instead of loading the graph.
Code

src/graphtea/extensions/io/GraphSaveObject.java[R25-26]

+    public ArrayList<VertexSaveObject> vs = new ArrayList<>();
+    ArrayList<EdgeSaveObject> es = new ArrayList<>();
Evidence
GraphTea’s “.tea” format is implemented via Java ObjectOutputStream/ObjectInputStream of
GraphSaveObject. Changing the serialized field types changes the class’s serialization
descriptor/UID, which can make older files fail to deserialize in LoadGraph.read().

src/graphtea/extensions/io/GraphSaveObject.java[16-29]
src/graphtea/extensions/io/SaveGraph.java[28-34]
src/graphtea/extensions/io/LoadGraph.java[35-44]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
GraphTea &quot;.tea&quot; files are serialized instances of `GraphSaveObject`. The PR changes `GraphSaveObject` field types (`Vector` -&gt; `ArrayList`) without maintaining Java serialization compatibility, which can make previously saved &quot;.tea&quot; files fail to load.

### Issue Context
`SaveGraph` writes `new GraphSaveObject(graph)` via `ObjectOutputStream`, and `LoadGraph` reads it back via `ObjectInputStream`. Compatibility depends on the serialized class descriptor/`serialVersionUID`.

### Fix Focus Areas
- src/graphtea/extensions/io/GraphSaveObject.java[16-29]
- src/graphtea/extensions/io/SaveGraph.java[28-34]
- src/graphtea/extensions/io/LoadGraph.java[35-44]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Browse failure is silent 🐞 Bug ⛯ Reliability
Description
StaticUtils.browse catches and ignores all exceptions from Desktop.getDesktop().browse, so when
Desktop browsing isn’t supported the app’s external links simply do nothing with no user-visible
indication.
Code

src/graphtea/platform/StaticUtils.java[R267-270]

+        try {
+            Desktop.getDesktop().browse(java.net.URI.create(url));
+        } catch (Exception ignored) {
        }
Evidence
StaticUtils.browse is the single entry point used by UI code to open external links. If Desktop
browsing is unsupported or fails, the exception is swallowed and callers receive no feedback, so
About/hyperlink actions appear broken.

src/graphtea/platform/StaticUtils.java[266-271]
src/graphtea/graph/ui/ExternalLinkHandler.java[16-21]
src/graphtea/plugins/main/core/actions/ShowAboutDialog.java[16-29]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`StaticUtils.browse` swallows all exceptions from `Desktop.getDesktop().browse(...)`, which causes external link actions to become silent no-ops when browsing is unsupported or fails.

### Issue Context
This method is called by UI actions like About dialog and hyperlink handlers. Without feedback, users can’t tell whether the click worked.

### Fix Focus Areas
- src/graphtea/platform/StaticUtils.java[266-271]
- src/graphtea/graph/ui/ExternalLinkHandler.java[16-21]
- src/graphtea/plugins/main/core/actions/ShowAboutDialog.java[16-29]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@rostam rostam merged commit 8007671 into master Mar 16, 2026
3 of 4 checks passed
Comment on lines +82 to +94
if (addSubdivisionVertexEdges()) {
for (Vertex v1 : g2.getVertexArray()) {
for (Vertex v2 : g2.getVertexArray()) {
if (v1.getProp().obj != null && v2.getProp().obj != null) {
Edge e1 = (Edge) v1.getProp().obj;
Edge e2 = (Edge) v2.getProp().obj;
if (edgeConnects(e1, e2)) {
addCurvedEdge(g2, v1, v2);
}
}
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. subdividedgraphbase.action() too nested 📘 Rule violation ⛯ Reliability

The new SubdividedGraphBase.action() implementation contains control-flow nesting deeper than 4
levels due to nested loops and conditionals. This violates the configured complexity limits and
makes the method harder to read and maintain.
Agent Prompt
## Issue description
`SubdividedGraphBase.action()` exceeds the allowed nesting depth (must be ≤ 4) due to multiple nested loops and conditionals.

## Issue Context
The compliance checklist enforces nesting depth limits for new/modified methods. The newly added `if (addSubdivisionVertexEdges())` block introduces nesting deeper than 4.

## Fix Focus Areas
- src/graphtea/extensions/actions/SubdividedGraphBase.java[82-94]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +25 to +26
public ArrayList<VertexSaveObject> vs = new ArrayList<>();
ArrayList<EdgeSaveObject> es = new ArrayList<>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Old .tea files unreadable 🐞 Bug ⛯ Reliability

GraphSaveObject’s serialized field types were changed (Vector→ArrayList) without preserving
serialization compatibility, so ObjectInputStream deserialization of previously saved “.tea” files
can fail and LoadGraph.read will return null instead of loading the graph.
Agent Prompt
### Issue description
GraphTea ".tea" files are serialized instances of `GraphSaveObject`. The PR changes `GraphSaveObject` field types (`Vector` -> `ArrayList`) without maintaining Java serialization compatibility, which can make previously saved ".tea" files fail to load.

### Issue Context
`SaveGraph` writes `new GraphSaveObject(graph)` via `ObjectOutputStream`, and `LoadGraph` reads it back via `ObjectInputStream`. Compatibility depends on the serialized class descriptor/`serialVersionUID`.

### Fix Focus Areas
- src/graphtea/extensions/io/GraphSaveObject.java[16-29]
- src/graphtea/extensions/io/SaveGraph.java[28-34]
- src/graphtea/extensions/io/LoadGraph.java[35-44]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant