diff --git a/src/utils/IdealGraphVisualizer/Coordinator/pom.xml b/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
index 4d773f0d8b3..fcfad0ba233 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/pom.xml
@@ -88,6 +88,11 @@
org-openide-util-lookup
${netbeans.version}
+
+ org.netbeans.api
+ org-openide-modules
+ ${netbeans.version}
+
org.netbeans.api
org-openide-util-ui
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
index d4764648adf..c66c40810c0 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,21 +28,32 @@ import com.sun.hotspot.igv.coordinator.actions.*;
import com.sun.hotspot.igv.data.ChangedListener;
import com.sun.hotspot.igv.data.GraphDocument;
import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.services.GroupCallback;
+import com.sun.hotspot.igv.data.serialization.ParseMonitor;
+import com.sun.hotspot.igv.data.serialization.Parser;
+import com.sun.hotspot.igv.data.serialization.Printer;
+import com.sun.hotspot.igv.data.serialization.Printer.GraphContext;
+import com.sun.hotspot.igv.data.services.GraphViewer;
import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.settings.Settings;
import com.sun.hotspot.igv.util.LookupHistory;
import com.sun.hotspot.igv.view.EditorTopComponent;
import java.awt.BorderLayout;
import java.awt.Dimension;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.HashSet;
-import java.util.Set;
-import javax.swing.UIManager;
+import java.io.*;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.swing.*;
import javax.swing.border.Border;
+import javax.swing.filechooser.FileFilter;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.ErrorManager;
-import org.openide.actions.GarbageCollectAction;
import org.openide.awt.Toolbar;
import org.openide.awt.ToolbarPool;
import org.openide.explorer.ExplorerManager;
@@ -50,7 +61,9 @@ import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
import org.openide.util.NbBundle;
+import org.openide.windows.Mode;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
@@ -60,97 +73,42 @@ import org.openide.windows.WindowManager;
*/
public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, ChangedListener {
- public static OutlineTopComponent instance;
public static final String PREFERRED_ID = "OutlineTopComponent";
+ private static final GraphDocument document = new GraphDocument();
+ private static final int WORK_UNITS = 10000;
+ private static final FileFilter xmlFileFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Graph files (*.xml)";
+ }
+ };
+ private static final Server server = new Server(document, OutlineTopComponent::loadContext);
+ public static OutlineTopComponent instance;
+ private final Set selectedFolders = new HashSet<>();
private ExplorerManager manager;
- private final GraphDocument document;
private FolderNode root;
- private SaveAllAction saveAllAction;
+ private SaveAction saveAction;
+ private SaveAsAction saveAsAction;
private RemoveAllAction removeAllAction;
private GraphNode[] selectedGraphs = new GraphNode[0];
- private final Set selectedFolders = new HashSet<>();
+ private Path documentPath = null;
private OutlineTopComponent() {
initComponents();
setName(NbBundle.getMessage(OutlineTopComponent.class, "CTL_OutlineTopComponent"));
setToolTipText(NbBundle.getMessage(OutlineTopComponent.class, "HINT_OutlineTopComponent"));
-
- document = new GraphDocument();
initListView();
initToolbar();
- initReceivers();
+ server.startServer();
}
- private void initListView() {
- manager = new ExplorerManager();
- root = new FolderNode(document);
- manager.setRootContext(root);
- ((BeanTreeView) this.treeView).setRootVisible(false);
-
- associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
- }
-
- private void initToolbar() {
- Toolbar toolbar = new Toolbar();
- toolbar.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border")); //NOI18N
- toolbar.setMinimumSize(new Dimension(0,0)); // MacOS BUG with ToolbarWithOverflow
-
- this.add(toolbar, BorderLayout.NORTH);
-
- toolbar.add(ImportAction.get(ImportAction.class));
- toolbar.add(SaveAsAction.get(SaveAsAction.class).createContextAwareInstance(this.getLookup()));
-
- saveAllAction = SaveAllAction.get(SaveAllAction.class);
- saveAllAction.setEnabled(false);
- toolbar.add(saveAllAction);
-
- toolbar.add(RemoveAction.get(RemoveAction.class).createContextAwareInstance(this.getLookup()));
-
- removeAllAction = RemoveAllAction.get(RemoveAllAction.class);
- removeAllAction.setEnabled(false);
- toolbar.add(removeAllAction);
-
- toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
-
- for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
- tb.setVisible(false);
- }
-
- document.getChangedEvent().addListener(g -> documentChanged());
- }
-
- private void documentChanged() {
- boolean enableButton = !document.getElements().isEmpty();
- saveAllAction.setEnabled(enableButton);
- removeAllAction.setEnabled(enableButton);
- }
-
- private void initReceivers() {
-
- final GroupCallback callback = g -> {
- synchronized(OutlineTopComponent.this) {
- g.setParent(getDocument());
- getDocument().addElement(g);
- }
- };
-
- new Server(callback);
- }
-
- public void clear() {
- document.clear();
- FolderNode.clearGraphNodeMap();
- root = new FolderNode(document);
- manager.setRootContext(root);
- }
-
- @Override
- public ExplorerManager getExplorerManager() {
- return manager;
- }
-
- public GraphDocument getDocument() {
+ public static GraphDocument getDocument() {
return document;
}
@@ -159,7 +117,7 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
* To obtain the singleton instance, use {@link #findInstance()}.
*/
- public static synchronized OutlineTopComponent getDefault() {
+ private static synchronized OutlineTopComponent getDefault() {
if (instance == null) {
instance = new OutlineTopComponent();
}
@@ -182,6 +140,97 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
return getDefault();
}
+ /**
+ * Stores the provided graph document to the designated file path with associated contexts.
+ */
+ private static void saveGraphDocument(GraphDocument doc, String path) throws IOException {
+ List saveContexts = new ArrayList<>();
+ WindowManager manager = WindowManager.getDefault();
+ for (Mode mode : manager.getModes()) {
+ List compList = new ArrayList<>(Arrays.asList(manager.getOpenedTopComponents(mode)));
+ for (TopComponent comp : compList) {
+ if (comp instanceof EditorTopComponent etc) {
+ InputGraph graph = etc.getModel().getGraph();
+ if (graph.isDiffGraph() && graph.getFirstGraph().getGroup() != graph.getSecondGraph().getGroup()) {
+ // don't save diff graphs comparing graphs from different groups
+ continue;
+ }
+ GraphContext graphContext = getGraphContext(etc);
+ saveContexts.add(graphContext);
+ }
+ }
+ }
+
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(path))) {
+ Printer.exportGraphDocument(writer, doc, saveContexts);
+ }
+ }
+
+ private static GraphContext getGraphContext(EditorTopComponent etc) {
+ InputGraph openedGraph = etc.getModel().getFirstGraph();
+ int posDiff = etc.getModel().getSecondPosition() - etc.getModel().getFirstPosition();
+ if (etc.getModel().getHiddenNodes().isEmpty()) {
+ return new GraphContext(openedGraph, new AtomicInteger(posDiff), new HashSet<>(), new AtomicBoolean(true));
+ } else {
+ Set visibleNodes = new HashSet<>(etc.getModel().getVisibleNodes());
+ return new GraphContext(openedGraph, new AtomicInteger(posDiff), visibleNodes, new AtomicBoolean(false));
+ }
+ }
+
+ private void initListView() {
+ setDocumentPath(null);
+ FolderNode.clearGraphNodeMap();
+ document.clear();
+ root = new FolderNode(document);
+ manager = new ExplorerManager();
+ manager.setRootContext(root);
+ ((BeanTreeView) this.treeView).setRootVisible(false);
+ associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+ }
+
+ private void initToolbar() {
+ Toolbar toolbar = new Toolbar();
+ toolbar.setBorder((Border) UIManager.get("Nb.Editor.Toolbar.border")); //NOI18N
+ toolbar.setMinimumSize(new Dimension(0, 0)); // MacOS BUG with ToolbarWithOverflow
+
+ this.add(toolbar, BorderLayout.NORTH);
+
+ toolbar.add(OpenAction.get(OpenAction.class));
+ toolbar.add(ImportAction.get(ImportAction.class));
+ toolbar.addSeparator();
+
+ saveAction = SaveAction.get(SaveAction.class);
+ saveAction.setEnabled(false);
+ toolbar.add(saveAction);
+ saveAsAction = SaveAsAction.get(SaveAsAction.class);
+ saveAsAction.setEnabled(false);
+ toolbar.add(saveAsAction);
+
+ toolbar.addSeparator();
+ toolbar.add(RemoveAction.get(RemoveAction.class).createContextAwareInstance(this.getLookup()));
+ removeAllAction = RemoveAllAction.get(RemoveAllAction.class);
+ removeAllAction.setEnabled(false);
+ toolbar.add(removeAllAction);
+
+ for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
+ tb.setVisible(false);
+ }
+
+ document.getChangedEvent().addListener(g -> documentChanged());
+ }
+
+ private void documentChanged() {
+ boolean enableButton = !document.getElements().isEmpty();
+ saveAction.setEnabled(enableButton);
+ saveAsAction.setEnabled(enableButton);
+ removeAllAction.setEnabled(enableButton);
+ }
+
+ @Override
+ public ExplorerManager getExplorerManager() {
+ return manager;
+ }
+
@Override
public int getPersistenceType() {
return TopComponent.PERSISTENCE_ALWAYS;
@@ -236,15 +285,12 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
InputGraph graph = lastProvider.getGraph();
if (graph != null) {
if (graph.isDiffGraph()) {
- EditorTopComponent editor = EditorTopComponent.getActive();
- if (editor != null) {
- InputGraph firstGraph = editor.getModel().getFirstGraph();
- GraphNode firstNode = FolderNode.getGraphNode(firstGraph);
- InputGraph secondGraph = editor.getModel().getSecondGraph();
- GraphNode secondNode = FolderNode.getGraphNode(secondGraph);
- if (firstNode != null && secondNode != null) {
- selectedGraphs = new GraphNode[]{firstNode, secondNode};
- }
+ InputGraph firstGraph = graph.getFirstGraph();
+ GraphNode firstNode = FolderNode.getGraphNode(firstGraph);
+ InputGraph secondGraph = graph.getSecondGraph();
+ GraphNode secondNode = FolderNode.getGraphNode(secondGraph);
+ if (firstNode != null && secondNode != null) {
+ selectedGraphs = new GraphNode[]{firstNode, secondNode};
}
} else {
GraphNode graphNode = FolderNode.getGraphNode(graph);
@@ -271,15 +317,229 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
}
@Override
- public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
- // Not called when user starts application for the first time
- super.readExternal(objectInput);
- ((BeanTreeView) this.treeView).setRootVisible(false);
+ public boolean canClose() {
+ SwingUtilities.invokeLater(() -> {
+ clearWorkspace();
+ open(); // Reopen the OutlineTopComponent
+ requestActive();
+ });
+ return true;
}
- @Override
- public void writeExternal(ObjectOutput objectOutput) throws IOException {
- super.writeExternal(objectOutput);
+ private void setDocumentPath(String path) {
+ if (path != null) {
+ documentPath = Paths.get(path);
+ setHtmlDisplayName("" + documentPath.getFileName().toString() + "");
+ setToolTipText("File: " + path);
+ } else {
+ documentPath = null;
+ setHtmlDisplayName("untitled");
+ setToolTipText("No file");
+ }
+
+ }
+
+ /**
+ * Clears the workspace by resetting the document path, clearing the document, and resetting the folder structure.
+ * After clearing the workspace, it will be ready for new documents.
+ */
+ public void clearWorkspace() {
+ setDocumentPath(null);
+ document.clear();
+ FolderNode.clearGraphNodeMap();
+ root = new FolderNode(document);
+ manager.setRootContext(root);
+ EditorTopComponent.closeAllInstances();
+ }
+
+ /**
+ * Opens a file dialog to select and load a graph document.
+ * Clears the workspace and adds the loaded document to the workspace.
+ **/
+ public void openFile() {
+ JFileChooser fc = new JFileChooser(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT));
+ fc.setFileFilter(xmlFileFilter);
+ if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+ clearWorkspace();
+ String path = fc.getSelectedFile().getAbsolutePath();
+ Settings.get().put(Settings.DIRECTORY, path);
+ setDocumentPath(path);
+ try {
+ loadGraphDocument(path, true);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private boolean overwriteDialog(String filename) {
+ JFrame frame = new JFrame();
+ String message = "Do you want to overwrite " + filename + "?";
+ int result = JOptionPane.showConfirmDialog(frame, message, "Confirm Overwrite", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
+ frame.dispose();
+ return result == JOptionPane.YES_OPTION;
+ }
+
+ /**
+ * Saves the current graph document.
+ * If the document has no location, let the user specify the file location.
+ */
+ public void save() {
+ if (documentPath == null) {
+ saveAs();
+ return;
+ }
+
+ String filePath = documentPath.toAbsolutePath().toString();
+ if (Files.exists(Paths.get(filePath)) && overwriteDialog(documentPath.getFileName().toString())) {
+ try {
+ saveGraphDocument(getDocument(), filePath);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ saveAs();
+ }
+ }
+
+ public void saveAs() {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Save As...");
+ fc.setFileFilter(xmlFileFilter);
+ fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+ if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getAbsolutePath();
+
+ // Ask if the user wants to overwrite the file if it already exists
+ if (Files.exists(Paths.get(path)) && !overwriteDialog(fc.getSelectedFile().getName())) {
+ return; // user does not want to overwrite
+ }
+
+ Settings.get().put(Settings.DIRECTORY, path);
+ setDocumentPath(path);
+ try {
+ saveGraphDocument(getDocument(), path);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Imports graph documents from one or more XML files.
+ * Displays a file chooser dialog to select one or multiple XML files for import.
+ * Each selected file is added to the workspace.
+ **/
+ public void importFromXML() {
+ JFileChooser fc = new JFileChooser();
+ fc.setFileFilter(xmlFileFilter);
+ fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+ fc.setMultiSelectionEnabled(true);
+ if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+ for (final File file : fc.getSelectedFiles()) {
+ String path = file.getAbsolutePath();
+ Settings.get().put(Settings.DIRECTORY, path);
+ try {
+ loadGraphDocument(path, false);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Loads and opens the given graph context (opened graphs and visible nodes).
+ */
+ private static void loadContext(GraphContext context) {
+ final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
+ if (viewer != null) {
+ final int difference = context.posDiff().get();
+ final InputGraph firstGraph = context.inputGraph();
+ final Set visibleNodes = context.visibleNodes();
+ final boolean showAll = context.showAll().get();
+
+ SwingUtilities.invokeLater(() -> {
+ InputGraph openedGraph = viewer.view(firstGraph, true);
+ if (openedGraph != null) {
+ EditorTopComponent etc = EditorTopComponent.findEditorForGraph(firstGraph);
+ if (etc != null) {
+ if (showAll) {
+ etc.getModel().setHiddenNodes(new HashSet<>());
+ } else {
+ etc.getModel().showOnly(visibleNodes);
+ }
+ int firstGraphIdx = firstGraph.getIndex();
+ if (difference > 0) {
+ etc.getModel().setPositions(firstGraphIdx, firstGraphIdx + difference);
+ } else if (difference < 0) {
+ etc.getModel().setPositions(firstGraphIdx + difference, firstGraphIdx);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Loads a graph document from the given file path, updating progress via a ProgressHandle.
+ * Parse the XML file, add the parsed document to the workspace, and load associated contexts if specified.
+ */
+ private void loadGraphDocument(String path, boolean loadContext) throws IOException {
+ if (Files.notExists(Path.of(path))) {
+ return;
+ }
+ File file = new File(path);
+ final FileChannel channel;
+ final long start;
+ try {
+ channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
+ start = channel.size();
+ } catch (Exception ex) {
+ Exceptions.printStackTrace(ex);
+ return;
+ }
+
+ final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
+ handle.start(WORK_UNITS);
+
+ ParseMonitor monitor = new ParseMonitor() {
+ @Override
+ public void updateProgress() {
+ try {
+ int prog = (int) (WORK_UNITS * (double) channel.position() / (double) start);
+ handle.progress(prog);
+ } catch (IOException ignored) {
+ }
+ }
+
+ @Override
+ public void setState(String state) {
+ updateProgress();
+ handle.progress(state);
+ }
+ };
+ try {
+ if (file.getName().endsWith(".xml")) {
+ ArrayList contexts = new ArrayList<>();
+ final Parser parser = new Parser(channel, monitor, document, loadContext ? contexts::add : null);
+ parser.parse();
+ SwingUtilities.invokeLater(() -> {
+ for (Node child : manager.getRootContext().getChildren().getNodes(true)) {
+ // Nodes are lazily created. By expanding and collapsing they are all initialized
+ ((BeanTreeView) this.treeView).expandNode(child);
+ ((BeanTreeView) this.treeView).collapseNode(child);
+ }
+ requestActive();
+ });
+ for (GraphContext ctx : contexts) {
+ loadContext(ctx);
+ }
+ }
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ handle.finish();
}
/** This method is called from within the constructor to
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/ImportAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/ImportAction.java
index 03d062d8041..f503e6c2eb7 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/ImportAction.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/ImportAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,24 +25,10 @@
package com.sun.hotspot.igv.coordinator.actions;
import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.serialization.GraphParser;
-import com.sun.hotspot.igv.data.serialization.ParseMonitor;
-import com.sun.hotspot.igv.data.serialization.Parser;
-import com.sun.hotspot.igv.settings.Settings;
-import java.io.File;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.StandardOpenOption;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.swing.Action;
-import javax.swing.JFileChooser;
-import javax.swing.SwingUtilities;
-import javax.swing.filechooser.FileFilter;
-import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
-import org.openide.util.*;
+import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
/**
@@ -51,89 +37,15 @@ import org.openide.util.actions.CallableSystemAction;
*/
public final class ImportAction extends CallableSystemAction {
- private static final int WORKUNITS = 10000;
- public static FileFilter getFileFilter() {
- return new FileFilter() {
-
- @Override
- public boolean accept(File f) {
- return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
- }
-
- @Override
- public String getDescription() {
- return "Graph files (*.xml)";
- }
- };
+ public ImportAction() {
+ putValue(Action.SHORT_DESCRIPTION, "Import from XML...");
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
}
@Override
public void performAction() {
- JFileChooser fc = new JFileChooser();
- fc.setFileFilter(ImportAction.getFileFilter());
- fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
- fc.setMultiSelectionEnabled(true);
-
- if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
- for (final File file : fc.getSelectedFiles()) {
- File dir = file;
- if (!dir.isDirectory()) {
- dir = dir.getParentFile();
- }
-
- Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
- try {
- final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
- final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
- handle.start(WORKUNITS);
- final long startTime = System.currentTimeMillis();
- final long start = channel.size();
- ParseMonitor monitor = new ParseMonitor() {
- @Override
- public void updateProgress() {
- try {
- int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
- handle.progress(prog);
- } catch (IOException ignored) {}
- }
- @Override
- public void setState(String state) {
- updateProgress();
- handle.progress(state);
- }
- };
- final GraphParser parser;
- final OutlineTopComponent component = OutlineTopComponent.findInstance();
- if (file.getName().endsWith(".xml")) {
- parser = new Parser(channel, monitor, null);
- } else {
- parser = null;
- }
- RequestProcessor.getDefault().post(new Runnable() {
- @Override
- public void run() {
- try {
- final GraphDocument document = parser.parse();
- if (document != null) {
- SwingUtilities.invokeLater(() -> {
- component.requestActive();
- component.getDocument().addGraphDocument(document);
- });
- }
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- handle.finish();
- long stop = System.currentTimeMillis();
- Logger.getLogger(getClass().getName()).log(Level.INFO, "Loaded in " + file + " in " + ((stop - startTime) / 1000.0) + " seconds");
- }
- });
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- }
+ OutlineTopComponent.findInstance().importFromXML();
}
@Override
@@ -141,12 +53,6 @@ public final class ImportAction extends CallableSystemAction {
return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
}
- public ImportAction() {
- putValue(Action.SHORT_DESCRIPTION, "Open");
- // D is the Control key on most platforms, the Command (meta) key on Macintosh
- putValue(Action.ACCELERATOR_KEY, Utilities.stringToKey("D-O"));
- }
-
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/OpenAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/OpenAction.java
new file mode 100644
index 00000000000..cd322efe619
--- /dev/null
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/OpenAction.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
+import javax.swing.Action;
+import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+import org.openide.util.actions.CallableSystemAction;
+
+public final class OpenAction extends CallableSystemAction {
+
+ public OpenAction() {
+ putValue(Action.SHORT_DESCRIPTION, "Open...");
+ // D is the Control key on most platforms, the Command (meta) key on Macintosh
+ putValue(Action.ACCELERATOR_KEY, Utilities.stringToKey("D-O"));
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
+ }
+
+ @Override
+ public void performAction() {
+ OutlineTopComponent.findInstance().openFile();
+ }
+
+ @Override
+ public String getName() {
+ return NbBundle.getMessage(OpenAction.class, "CTL_OpenAction");
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ protected boolean asynchronous() {
+ return false;
+ }
+
+ @Override
+ protected String iconResource() {
+ return "com/sun/hotspot/igv/coordinator/images/open.png";
+ }
+}
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java
index e1b3a62f0eb..9f2ac69aa64 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ import com.sun.hotspot.igv.coordinator.FolderNode;
import javax.swing.Action;
import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.actions.NodeAction;
@@ -37,6 +38,11 @@ import org.openide.util.actions.NodeAction;
*/
public final class RemoveAction extends NodeAction {
+ public RemoveAction() {
+ putValue(Action.SHORT_DESCRIPTION, getName());
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
+ }
+
@Override
protected void performAction(Node[] activatedNodes) {
for (Node n : activatedNodes) {
@@ -47,10 +53,6 @@ public final class RemoveAction extends NodeAction {
}
}
- public RemoveAction() {
- putValue(Action.SHORT_DESCRIPTION, getName());
- }
-
@Override
public String getName() {
return NbBundle.getMessage(RemoveAction.class, "CTL_RemoveAction");
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java
index e95099d0f97..04158b23b52 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@ package com.sun.hotspot.igv.coordinator.actions;
import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
import javax.swing.Action;
import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
@@ -42,7 +43,8 @@ public final class RemoveAllAction extends CallableSystemAction {
}
public RemoveAllAction() {
- putValue(Action.SHORT_DESCRIPTION, "Remove all graphs and groups");
+ putValue(Action.SHORT_DESCRIPTION, "Clear workspace");
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
}
@Override
@@ -62,6 +64,6 @@ public final class RemoveAllAction extends CallableSystemAction {
@Override
public void performAction() {
- OutlineTopComponent.findInstance().clear();
+ OutlineTopComponent.findInstance().clearWorkspace();
}
}
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAction.java
similarity index 77%
rename from src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java
rename to src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAction.java
index dde018f60e9..77ec88d0659 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,37 +27,34 @@ package com.sun.hotspot.igv.coordinator.actions;
import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
import javax.swing.Action;
import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.actions.CallableSystemAction;
-/**
- *
- * @author Thomas Wuerthinger
- */
-public final class SaveAllAction extends CallableSystemAction {
+public final class SaveAction extends CallableSystemAction {
+
+ public SaveAction() {
+ putValue(Action.SHORT_DESCRIPTION, "Save");
+ // D is the Control key on most platforms, the Command (meta) key on Macintosh
+ putValue(Action.ACCELERATOR_KEY, Utilities.stringToKey("D-S"));
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
+ }
@Override
public void performAction() {
- final OutlineTopComponent component = OutlineTopComponent.findInstance();
- SaveAsAction.save(component.getDocument());
+ OutlineTopComponent.findInstance().save();
}
@Override
public String getName() {
- return NbBundle.getMessage(SaveAllAction.class, "CTL_SaveAllAction");
- }
-
- public SaveAllAction() {
- putValue(Action.SHORT_DESCRIPTION, "Save all groups to XML file...");
- // D is the Control key on most platforms, the Command (meta) key on Macintosh
- putValue(Action.ACCELERATOR_KEY, Utilities.stringToKey("D-S"));
+ return NbBundle.getMessage(SaveAction.class, "CTL_SaveAction");
}
@Override
protected String iconResource() {
- return "com/sun/hotspot/igv/coordinator/images/saveall.gif";
+ return "com/sun/hotspot/igv/coordinator/images/save.png";
}
@Override
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java
index 4be57a51dba..65b13dfbf06 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,75 +24,27 @@
package com.sun.hotspot.igv.coordinator.actions;
-import com.sun.hotspot.igv.coordinator.FolderNode;
-import com.sun.hotspot.igv.data.Folder;
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.serialization.Printer;
-import com.sun.hotspot.igv.settings.Settings;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.file.Files;
+import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
import javax.swing.Action;
-import javax.swing.JFileChooser;
-import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
+import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
-import org.openide.util.actions.NodeAction;
+import org.openide.util.actions.CallableSystemAction;
/**
*
* @author Thomas Wuerthinger
*/
-public final class SaveAsAction extends NodeAction {
+public final class SaveAsAction extends CallableSystemAction {
public SaveAsAction() {
- putValue(Action.SHORT_DESCRIPTION, "Save selected groups to XML file...");
+ putValue(Action.SHORT_DESCRIPTION, "Save as...");
+ putValue(Action.SMALL_ICON, ImageUtilities.loadImageIcon(iconResource(), true));
}
@Override
- protected void performAction(Node[] activatedNodes) {
- GraphDocument doc = new GraphDocument();
- for (Node node : activatedNodes) {
- if (node instanceof FolderNode) {
- FolderNode folderNode = (FolderNode) node;
- Folder folder = folderNode.getFolder();
- if (folder instanceof Group) {
- Group group = (Group) folder;
- doc.addElement(group);
- }
- }
- }
- save(doc);
- }
-
- public static void save(GraphDocument doc) {
- JFileChooser fc = new JFileChooser();
- fc.setFileFilter(ImportAction.getFileFilter());
- fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
-
- if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
- if (!file.getName().contains(".")) {
- file = new File(file.getAbsolutePath() + ".xml");
- }
-
- File dir = file;
- if (!dir.isDirectory()) {
- dir = dir.getParentFile();
- }
- Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
- try {
- try (Writer writer = new OutputStreamWriter(Files.newOutputStream(file.toPath()))) {
- Printer p = new Printer();
- p.export(writer, doc);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ public void performAction() {
+ OutlineTopComponent.findInstance().saveAs();
}
@Override
@@ -102,7 +54,7 @@ public final class SaveAsAction extends NodeAction {
@Override
protected String iconResource() {
- return "com/sun/hotspot/igv/coordinator/images/save.png";
+ return "com/sun/hotspot/igv/coordinator/images/save_as.gif";
}
@Override
@@ -114,17 +66,4 @@ public final class SaveAsAction extends NodeAction {
protected boolean asynchronous() {
return false;
}
-
- @Override
- protected boolean enable(Node[] nodes) {
- if (nodes.length > 0) {
- for (Node n : nodes) {
- if (!(n instanceof FolderNode) || ((FolderNode) n).isRootNode()) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
}
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/Bundle.properties b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/Bundle.properties
index 1b17042508e..2bebc0e2797 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/Bundle.properties
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/Bundle.properties
@@ -1,6 +1,3 @@
-AdvancedOption_DisplayName_Coordinator=Settings
-AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
-CTL_OutlineTopComponent=Outline
-CTL_SomeAction=test
-HINT_OutlineTopComponent=Displays loaded groups of graphs.
+CTL_OutlineTopComponent=Workspace
+HINT_OutlineTopComponent=Opened groups of graphs.
OpenIDE-Module-Name=Coordinator
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/actions/Bundle.properties b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/actions/Bundle.properties
index de3aa509a31..f192e91fceb 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/actions/Bundle.properties
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/actions/Bundle.properties
@@ -1,8 +1,9 @@
-CTL_ImportAction=Open...
+CTL_ImportAction=Import...
+CTL_OpenAction=Open...
CTL_DiffGraphAction=Difference to current graph
CTL_RemoveAction=Remove selected graphs and groups
-CTL_RemoveAllAction=Remove all graphs and groups
-CTL_OutlineAction=Outline
-CTL_SaveAsAction=Save selected groups...
-CTL_SaveAllAction=Save all groups...
+CTL_RemoveAllAction=Clear workspace
+CTL_OutlineAction=Workspace
+CTL_SaveAction=Save
+CTL_SaveAsAction=Save as...
CTL_NewFilterAction=New filter...
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/import.png b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/import.png
index 7e4a6badcb1..d8c8c766b88 100644
Binary files a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/import.png and b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/import.png differ
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/open.png b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/open.png
new file mode 100644
index 00000000000..212763d1263
Binary files /dev/null and b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/open.png differ
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/saveall.gif b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/save_as.gif
similarity index 100%
rename from src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/saveall.gif
rename to src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/images/save_as.gif
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
index 60e73788c95..dd1a2c0d2ab 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/resources/com/sun/hotspot/igv/coordinator/layer.xml
@@ -26,8 +26,9 @@
+
+
-
@@ -55,6 +56,10 @@
+
+
+
+
@@ -71,13 +76,13 @@
+
+
+
+
-
-
-
-
-
+
@@ -105,8 +110,8 @@
-
+
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Folder.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Folder.java
index 9ff7c32bd1f..3bd92a49cbf 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Folder.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Folder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@ package com.sun.hotspot.igv.data;
import java.util.List;
-public interface Folder {
+public interface Folder extends Properties.Provider {
void setName(String name);
String getName();
String getDisplayName();
@@ -33,4 +33,5 @@ public interface Folder {
void removeElement(FolderElement element);
void addElement(FolderElement group);
ChangedEvent extends Folder> getChangedEvent();
+ Properties getProperties();
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/FolderElement.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/FolderElement.java
index eb0a874278f..2bf153674c7 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/FolderElement.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/FolderElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,12 @@
*/
package com.sun.hotspot.igv.data;
-public interface FolderElement {
+public interface FolderElement extends Properties.Provider {
ChangedEvent extends FolderElement> getDisplayNameChangedEvent();
void setName(String name);
String getName();
String getDisplayName();
void setParent(Folder parent);
Folder getParent();
+ Properties getProperties();
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/GraphDocument.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/GraphDocument.java
index 1f13cb3b433..4bf933d43c2 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/GraphDocument.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/GraphDocument.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@ public class GraphDocument extends Properties.Entity implements ChangedEventProv
public void addGraphDocument(GraphDocument document) {
if (document != this) {
- for (FolderElement e : document.elements) {
+ for (FolderElement e : document.getElements()) {
e.setParent(this);
this.addElement(e);
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Group.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Group.java
index 01af950a093..e98164409b6 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Group.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/Group.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -126,13 +126,22 @@ public class Group extends Properties.Entity implements ChangedEventProvider xmlDocument = new TopElementHandler<>();
+ private final TopElementHandler xmlData = new TopElementHandler<>();
private final Map differenceEncoding = new HashMap<>();
private final Map lastParsedGraph = new HashMap<>();
- private final GroupCallback groupCallback;
+ private final GraphDocument callbackDocument;
+ private final GraphContextAction contextAction;
+ private final ArrayList contexts = new ArrayList<>();
private final HashMap idCache = new HashMap<>();
private final ArrayList> blockConnections = new ArrayList<>();
- private int maxId = 0;
- private GraphDocument graphDocument;
private final ParseMonitor monitor;
private final ReadableByteChannel channel;
private boolean invokeLater = true;
- private int lookupID(String i) {
- try {
- return Integer.parseInt(i);
- } catch (NumberFormatException nfe) {
- // ignore
- }
- Integer id = idCache.get(i);
- if (id == null) {
- id = maxId++;
- idCache.put(i, id);
- }
- return id;
- }
-
- //
- private ElementHandler topHandler = new ElementHandler(TOP_ELEMENT) {
+ //
+ private final ElementHandler methodHandler = new XMLParser.ElementHandler<>(METHOD_ELEMENT) {
@Override
- protected GraphDocument start() throws SAXException {
+ protected InputMethod start() throws SAXException {
+ Group group = getParentObject();
+ InputMethod method = parseMethod(this, group);
+ group.setMethod(method);
+ return method;
+ }
+ };
+ //
+ private final HandoverElementHandler bytecodesHandler = new XMLParser.HandoverElementHandler<>(BYTECODES_ELEMENT, true) {
+
+ @Override
+ protected void end(String text) {
+ getParentObject().setBytecodes(text);
+ }
+ };
+ //
+ private final HandoverElementHandler inlinedHandler = new XMLParser.HandoverElementHandler<>(INLINE_ELEMENT);
+ //
+ private final ElementHandler inlinedMethodHandler = new XMLParser.ElementHandler<>(METHOD_ELEMENT) {
+
+ @Override
+ protected InputMethod start() throws SAXException {
+ InputMethod method = parseMethod(this, getParentObject().getGroup());
+ getParentObject().addInlined(method);
+ return method;
+ }
+ };
+ //
+ private final HandoverElementHandler nodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
+ //
+ private final HandoverElementHandler controlFlowHandler = new HandoverElementHandler<>(CONTROL_FLOW_ELEMENT);
+ private final HandoverElementHandler graphStatesHandler = new HandoverElementHandler<>(GRAPH_STATES_ELEMENT);
+ private final ElementHandler stateHandler = new ElementHandler<>(STATE_ELEMENT) {
+
+ @Override
+ protected GraphContext start() {
+ InputGraph inputGraph = getParentObject();
+ GraphContext graphContext = new GraphContext(inputGraph, new AtomicInteger(0), new HashSet<>(), new AtomicBoolean(false));
+ if (contextAction != null) {
+ contexts.add(graphContext);
+ }
+ return graphContext;
+ }
+ };
+ private final ElementHandler visibleNodesHandler = new ElementHandler<>(VISIBLE_NODES_ELEMENT) {
+
+ @Override
+ protected GraphContext start() throws SAXException {
+ String s = readRequiredAttribute(ALL_PROPERTY);
+ try {
+ boolean all = Boolean.parseBoolean(s);
+ getParentObject().showAll().set(all);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ return getParentObject();
+ }
+ };
+ private final ElementHandler visibleNodeHandler = new ElementHandler<>(NODE_ELEMENT) {
+
+ @Override
+ protected GraphContext start() throws SAXException {
+ String s = readRequiredAttribute(NODE_ID_PROPERTY);
+ int nodeID;
+ try {
+ nodeID = Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ getParentObject().visibleNodes().add(nodeID);
+ return getParentObject();
+ }
+ };
+ private final ElementHandler differenceHandler = new ElementHandler<>(STATE_POSITION_DIFFERENCE) {
+
+ @Override
+ protected GraphContext start() throws SAXException {
+ String s = readRequiredAttribute(POSITION_DIFFERENCE_PROPERTY);
+ int posDiff;
+ try {
+ posDiff = Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ getParentObject().posDiff().set(posDiff);
+ return getParentObject();
+ }
+ };
+ //
+ private final ElementHandler blockHandler = new ElementHandler<>(BLOCK_ELEMENT) {
+
+ @Override
+ protected InputBlock start() throws SAXException {
+ InputGraph graph = getParentObject();
+ String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+ InputBlock b = graph.addBlock(name);
+ for (InputNode n : b.getNodes()) {
+ assert graph.getBlock(n).equals(b);
+ }
+ return b;
+ }
+ };
+ //
+ private final HandoverElementHandler blockNodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
+ //
+ private final HandoverElementHandler successorsHandler = new HandoverElementHandler<>(SUCCESSORS_ELEMENT);
+ //
+ private final ElementHandler successorHandler = new ElementHandler<>(SUCCESSOR_ELEMENT) {
+
+ @Override
+ protected InputBlock start() throws SAXException {
+ String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+ blockConnections.add(new Pair<>(getParentObject().getName(), name));
+ return getParentObject();
+ }
+ };
+ //
+ private final HandoverElementHandler edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT);
+ //
+ private final EdgeElementHandler edgeHandler = new EdgeElementHandler(EDGE_ELEMENT) {
+
+ @Override
+ protected InputEdge start(InputEdge conn) {
+ InputGraph inputGraph = getParentObject();
+ inputGraph.addEdge(conn);
+ return conn;
+ }
+ };
+ //
+ private final EdgeElementHandler removeEdgeHandler = new EdgeElementHandler(REMOVE_EDGE_ELEMENT) {
+
+ @Override
+ protected InputEdge start(InputEdge conn) {
+ getParentObject().removeEdge(conn);
+ return conn;
+ }
+ };
+ //
+ private final HandoverElementHandler propertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT);
+ //
+ private final ElementHandler propertyHandler = new XMLParser.ElementHandler<>(PROPERTY_ELEMENT, true) {
+
+ @Override
+ public String start() throws SAXException {
+ return readRequiredAttribute(PROPERTY_NAME_PROPERTY);
+ }
+
+ @Override
+ public void end(String text) {
+ getParentObject().getProperties().setProperty(getObject(), text.trim());
+ }
+ };
+ private int maxId = 0;
+ //
+ private final ElementHandler blockNodeHandler = new ElementHandler<>(NODE_ELEMENT) {
+
+ @Override
+ protected InputBlock start() throws SAXException {
+ String s = readRequiredAttribute(NODE_ID_PROPERTY);
+
+ int id;
+ try {
+ id = lookupID(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ getParentObject().addNode(id);
+ return getParentObject();
+ }
+ };
+ //
+ private final ElementHandler nodeHandler = new ElementHandler<>(NODE_ELEMENT) {
+
+ @Override
+ protected InputNode start() throws SAXException {
+ String s = readRequiredAttribute(NODE_ID_PROPERTY);
+ int id;
+ try {
+ id = lookupID(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ InputNode node = new InputNode(id);
+ getParentObject().addNode(node);
+ return node;
+ }
+ };
+ //
+ private final ElementHandler removeNodeHandler = new ElementHandler<>(REMOVE_NODE_ELEMENT) {
+
+ @Override
+ protected InputNode start() throws SAXException {
+ String s = readRequiredAttribute(NODE_ID_PROPERTY);
+ int id;
+ try {
+ id = lookupID(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ return getParentObject().removeNode(id);
+ }
+ };
+ private GraphDocument graphDocument;
+ //
+ private final ElementHandler topHandler = new ElementHandler<>(TOP_ELEMENT) {
+
+ @Override
+ protected GraphDocument start() {
graphDocument = new GraphDocument();
return graphDocument;
}
};
//
- private ElementHandler groupHandler = new XMLParser.ElementHandler(GROUP_ELEMENT) {
+ private final ElementHandler groupHandler = new XMLParser.ElementHandler<>(GROUP_ELEMENT) {
@Override
- protected Group start() throws SAXException {
- final Group group = new Group(this.getParentObject());
+ protected Group start() {
+ final Folder folder = getParentObject();
+ final Group group = new Group(folder);
String differenceProperty = this.readAttribute(DIFFERENCE_PROPERTY);
Parser.this.differenceEncoding.put(group, (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))));
@@ -141,13 +334,11 @@ public class Parser implements GraphParser {
monitor.setState(group.getName());
}
- final Folder parent = getParentObject();
- if (groupCallback == null || parent instanceof Group) {
- Runnable addToParent = () -> parent.addElement(group);
+ if (callbackDocument == null || folder instanceof Group) {
if (invokeLater) {
- SwingUtilities.invokeLater(addToParent);
+ SwingUtilities.invokeLater(() -> folder.addElement(group));
} else {
- addToParent.run();
+ folder.addElement(group);
}
}
@@ -155,62 +346,20 @@ public class Parser implements GraphParser {
}
@Override
- protected void end(String text) throws SAXException {
- }
- };
- //
- private ElementHandler methodHandler = new XMLParser.ElementHandler(METHOD_ELEMENT) {
-
- @Override
- protected InputMethod start() throws SAXException {
-
- InputMethod method = parseMethod(this, getParentObject());
- getParentObject().setMethod(method);
- return method;
- }
- };
-
- private InputMethod parseMethod(XMLParser.ElementHandler,?> handler, Group group) throws SAXException {
- String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
- int bci = 0;
- try {
- bci = Integer.parseInt(s);
- } catch (NumberFormatException e) {
- throw new SAXException(e);
- }
- InputMethod method = new InputMethod(group, handler.readRequiredAttribute(METHOD_NAME_PROPERTY), handler.readRequiredAttribute(METHOD_SHORT_NAME_PROPERTY), bci);
- return method;
- }
- //
- private HandoverElementHandler bytecodesHandler = new XMLParser.HandoverElementHandler(BYTECODES_ELEMENT, true) {
-
- @Override
- protected void end(String text) throws SAXException {
- getParentObject().setBytecodes(text);
- }
- };
- //
- private HandoverElementHandler inlinedHandler = new XMLParser.HandoverElementHandler<>(INLINE_ELEMENT);
- //
- private ElementHandler inlinedMethodHandler = new XMLParser.ElementHandler(METHOD_ELEMENT) {
-
- @Override
- protected InputMethod start() throws SAXException {
- InputMethod method = parseMethod(this, getParentObject().getGroup());
- getParentObject().addInlined(method);
- return method;
+ protected void end(String text) {
}
};
//
- private ElementHandler graphHandler = new XMLParser.ElementHandler(GRAPH_ELEMENT) {
+ private final ElementHandler graphHandler = new XMLParser.ElementHandler<>(GRAPH_ELEMENT) {
@Override
- protected InputGraph start() throws SAXException {
+ protected InputGraph start() {
+ Group group = getParentObject();
String name = readAttribute(GRAPH_NAME_PROPERTY);
InputGraph curGraph = new InputGraph(name);
- if (differenceEncoding.get(getParentObject())) {
- InputGraph previous = lastParsedGraph.get(getParentObject());
- lastParsedGraph.put(getParentObject(), curGraph);
+ if (differenceEncoding.get(group)) {
+ InputGraph previous = lastParsedGraph.get(group);
+ lastParsedGraph.put(group, curGraph);
if (previous != null) {
for (InputNode n : previous.getNodes()) {
curGraph.addNode(n);
@@ -228,8 +377,8 @@ public class Parser implements GraphParser {
}
@Override
- protected void end(String text) throws SAXException {
- // NOTE: Some graphs intentionally don't provide blocks. Instead
+ protected void end(String text) {
+ // NOTE: Some graphs intentionally don't provide blocks. Instead,
// they later generate the blocks from other information such
// as node properties (example: ServerCompilerScheduler).
// Thus, we shouldn't assign nodes that don't belong to any
@@ -237,11 +386,12 @@ public class Parser implements GraphParser {
// defined and nodes are assigned to them.
final InputGraph graph = getObject();
+
final Group parent = getParentObject();
- if (graph.getBlocks().size() > 0) {
+ if (!graph.getBlocks().isEmpty()) {
boolean blocksContainNodes = false;
for (InputBlock b : graph.getBlocks()) {
- if (b.getNodes().size() > 0) {
+ if (!b.getNodes().isEmpty()) {
blocksContainNodes = true;
break;
}
@@ -252,7 +402,7 @@ public class Parser implements GraphParser {
blockConnections.clear();
} else {
// Blocks and their nodes defined: add other nodes to an
- // artificial "no block" block
+ // artificial "no block" block
InputBlock noBlock = null;
for (InputNode n : graph.getNodes()) {
if (graph.getBlock(n) == null) {
@@ -278,97 +428,154 @@ public class Parser implements GraphParser {
}
blockConnections.clear();
- Runnable addToParent = () -> parent.addElement(graph);
if (invokeLater) {
- SwingUtilities.invokeLater(addToParent);
+ SwingUtilities.invokeLater(() -> parent.addElement(graph));
} else {
- addToParent.run();
+ parent.addElement(graph);
+ }
+ if (contextAction != null) {
+ for (GraphContext ctx : contexts) {
+ contextAction.performAction(ctx);
+ }
+ }
+ contexts.clear();
+ }
+ };
+ //
+ private final HandoverElementHandler groupPropertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT) {
+
+ @Override
+ public void end(String text) {
+ final Group group = getParentObject();
+ if (callbackDocument != null && group.getParent() instanceof GraphDocument) {
+ group.setParent(callbackDocument);
+ if (invokeLater) {
+ SwingUtilities.invokeLater(() -> callbackDocument.addElement(group));
+ } else {
+ callbackDocument.addElement(group);
+ }
}
}
};
- //
- private HandoverElementHandler nodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
- //
- private HandoverElementHandler controlFlowHandler = new HandoverElementHandler<>(CONTROL_FLOW_ELEMENT);
- //
- private ElementHandler blockHandler = new ElementHandler(BLOCK_ELEMENT) {
- @Override
- protected InputBlock start() throws SAXException {
- InputGraph graph = getParentObject();
- String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
- InputBlock b = graph.addBlock(name);
- for (InputNode n : b.getNodes()) {
- assert graph.getBlock(n).equals(b);
+ public Parser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument callbackDocument, GraphContextAction contextAction) {
+ this.callbackDocument = callbackDocument;
+ this.contextAction = contextAction;
+ this.monitor = monitor;
+ this.channel = channel;
+
+ // Initialize dependencies
+ xmlData.addChild(topHandler);
+ topHandler.addChild(groupHandler);
+
+ groupHandler.addChild(methodHandler);
+ groupHandler.addChild(graphHandler);
+ groupHandler.addChild(groupHandler);
+
+ methodHandler.addChild(inlinedHandler);
+ methodHandler.addChild(bytecodesHandler);
+
+ inlinedHandler.addChild(inlinedMethodHandler);
+ inlinedMethodHandler.addChild(bytecodesHandler);
+ inlinedMethodHandler.addChild(inlinedHandler);
+
+ graphHandler.addChild(nodesHandler);
+ graphHandler.addChild(edgesHandler);
+ graphHandler.addChild(controlFlowHandler);
+ graphHandler.addChild(graphStatesHandler);
+
+ controlFlowHandler.addChild(blockHandler);
+
+ graphStatesHandler.addChild(stateHandler);
+ stateHandler.addChild(differenceHandler);
+ stateHandler.addChild(visibleNodesHandler);
+ visibleNodesHandler.addChild(visibleNodeHandler);
+
+ blockHandler.addChild(successorsHandler);
+ successorsHandler.addChild(successorHandler);
+ blockHandler.addChild(blockNodesHandler);
+ blockNodesHandler.addChild(blockNodeHandler);
+
+ nodesHandler.addChild(nodeHandler);
+ nodesHandler.addChild(removeNodeHandler);
+ edgesHandler.addChild(edgeHandler);
+ edgesHandler.addChild(removeEdgeHandler);
+
+ methodHandler.addChild(propertiesHandler);
+ inlinedMethodHandler.addChild(propertiesHandler);
+ topHandler.addChild(propertiesHandler);
+ groupHandler.addChild(groupPropertiesHandler);
+ graphHandler.addChild(propertiesHandler);
+ nodeHandler.addChild(propertiesHandler);
+ propertiesHandler.addChild(propertyHandler);
+ groupPropertiesHandler.addChild(propertyHandler);
+ }
+
+ private int lookupID(String i) {
+ try {
+ return Integer.parseInt(i);
+ } catch (NumberFormatException nfe) {
+ // ignore
+ }
+ Integer id = idCache.get(i);
+ if (id == null) {
+ id = maxId++;
+ idCache.put(i, id);
+ }
+ return id;
+ }
+
+ private InputMethod parseMethod(XMLParser.ElementHandler, ?> handler, Group group) throws SAXException {
+ String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
+ int bci;
+ try {
+ bci = Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ throw new SAXException(e);
+ }
+ return new InputMethod(group, handler.readRequiredAttribute(METHOD_NAME_PROPERTY), handler.readRequiredAttribute(METHOD_SHORT_NAME_PROPERTY), bci);
+ }
+
+ // Returns a new GraphDocument object deserialized from an XML input source.
+ @Override
+ public GraphDocument parse() throws IOException {
+ if (monitor != null) {
+ monitor.setState("Starting parsing");
+ }
+ try {
+ XMLReader reader = createReader();
+ // To enforce using English for non-English users, we must use Locale.ROOT rather than Locale.ENGLISH
+ reader.setProperty("http://apache.org/xml/properties/locale", Locale.ROOT);
+ reader.setContentHandler(new XMLParser(xmlData, monitor));
+ reader.parse(new InputSource(Channels.newInputStream(channel)));
+ } catch (SAXException ex) {
+ if (!(ex instanceof SAXParseException) || !"XML document structures must start and end within the same entity.".equals(ex.getMessage())) {
+ throw new IOException(ex);
}
- return b;
}
- };
- //
- private HandoverElementHandler blockNodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
- //
- private ElementHandler blockNodeHandler = new ElementHandler(NODE_ELEMENT) {
-
- @Override
- protected InputBlock start() throws SAXException {
- String s = readRequiredAttribute(NODE_ID_PROPERTY);
-
- int id = 0;
- try {
- id = lookupID(s);
- } catch (NumberFormatException e) {
- throw new SAXException(e);
- }
- getParentObject().addNode(id);
- return getParentObject();
+ if (monitor != null) {
+ monitor.setState("Finished parsing");
}
- };
- //
- private HandoverElementHandler successorsHandler = new HandoverElementHandler<>(SUCCESSORS_ELEMENT);
- //
- private ElementHandler successorHandler = new ElementHandler(SUCCESSOR_ELEMENT) {
- @Override
- protected InputBlock start() throws SAXException {
- String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
- blockConnections.add(new Pair<>(getParentObject().getName(), name));
- return getParentObject();
- }
- };
- //
- private ElementHandler nodeHandler = new ElementHandler(NODE_ELEMENT) {
+ return graphDocument;
+ }
- @Override
- protected InputNode start() throws SAXException {
- String s = readRequiredAttribute(NODE_ID_PROPERTY);
- int id = 0;
- try {
- id = lookupID(s);
- } catch (NumberFormatException e) {
- throw new SAXException(e);
- }
- InputNode node = new InputNode(id);
- getParentObject().addNode(node);
- return node;
- }
- };
- //
- private ElementHandler removeNodeHandler = new ElementHandler(REMOVE_NODE_ELEMENT) {
+ // Whether the parser is allowed to defer connecting the parsed elements.
+ // Setting to false is useful for synchronization in unit tests.
+ public void setInvokeLater(boolean invokeLater) {
+ this.invokeLater = invokeLater;
+ }
- @Override
- protected InputNode start() throws SAXException {
- String s = readRequiredAttribute(NODE_ID_PROPERTY);
- int id = 0;
- try {
- id = lookupID(s);
- } catch (NumberFormatException e) {
- throw new SAXException(e);
- }
- return getParentObject().removeNode(id);
+ private XMLReader createReader() throws SAXException {
+ try {
+ SAXParserFactory pFactory = SAXParserFactory.newInstance();
+ pFactory.setValidating(false);
+ pFactory.setNamespaceAware(true);
+ return pFactory.newSAXParser().getXMLReader();
+ } catch (ParserConfigurationException ex) {
+ throw new SAXException(ex);
}
- };
- //
- private HandoverElementHandler edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT);
+ }
// Local class for edge elements
private class EdgeElementHandler extends ElementHandler {
@@ -381,10 +588,10 @@ public class Parser implements GraphParser {
protected InputEdge start() throws SAXException {
int fromIndex = 0;
int toIndex = 0;
- int from = -1;
- int to = -1;
- String label = null;
- String type = null;
+ int from;
+ int to;
+ String label;
+ String type;
try {
String fromIndexString = readAttribute(FROM_INDEX_PROPERTY);
@@ -413,148 +620,8 @@ public class Parser implements GraphParser {
return start(conn);
}
- protected InputEdge start(InputEdge conn) throws SAXException {
+ protected InputEdge start(InputEdge conn) {
return conn;
}
}
- //
- private EdgeElementHandler edgeHandler = new EdgeElementHandler(EDGE_ELEMENT) {
-
- @Override
- protected InputEdge start(InputEdge conn) throws SAXException {
- getParentObject().addEdge(conn);
- return conn;
- }
- };
- //
- private EdgeElementHandler removeEdgeHandler = new EdgeElementHandler(REMOVE_EDGE_ELEMENT) {
-
- @Override
- protected InputEdge start(InputEdge conn) throws SAXException {
- getParentObject().removeEdge(conn);
- return conn;
- }
- };
- //
- private HandoverElementHandler propertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT);
- //
- private HandoverElementHandler groupPropertiesHandler = new HandoverElementHandler(PROPERTIES_ELEMENT) {
-
- @Override
- public void end(String text) throws SAXException {
- if (groupCallback != null && getParentObject().getParent() instanceof GraphDocument) {
- final Group group = getParentObject();
- Runnable addStarted = () -> groupCallback.started(group);
- if (invokeLater) {
- SwingUtilities.invokeLater(addStarted);
- } else {
- addStarted.run();
- }
- }
- }
- };
- //
- private ElementHandler propertyHandler = new XMLParser.ElementHandler(PROPERTY_ELEMENT, true) {
-
- @Override
- public String start() throws SAXException {
- return readRequiredAttribute(PROPERTY_NAME_PROPERTY);
- }
-
- @Override
- public void end(String text) {
- getParentObject().getProperties().setProperty(getObject(), text.trim());
- }
- };
-
- public Parser(ReadableByteChannel channel) {
- this(channel, null, null);
- }
-
- public Parser(ReadableByteChannel channel, ParseMonitor monitor, GroupCallback groupCallback) {
-
- this.groupCallback = groupCallback;
- this.monitor = monitor;
- this.channel = channel;
-
- // Initialize dependencies
- xmlDocument.addChild(topHandler);
- topHandler.addChild(groupHandler);
-
- groupHandler.addChild(methodHandler);
- groupHandler.addChild(graphHandler);
- groupHandler.addChild(groupHandler);
-
- methodHandler.addChild(inlinedHandler);
- methodHandler.addChild(bytecodesHandler);
-
- inlinedHandler.addChild(inlinedMethodHandler);
- inlinedMethodHandler.addChild(bytecodesHandler);
- inlinedMethodHandler.addChild(inlinedHandler);
-
- graphHandler.addChild(nodesHandler);
- graphHandler.addChild(edgesHandler);
- graphHandler.addChild(controlFlowHandler);
-
- controlFlowHandler.addChild(blockHandler);
-
- blockHandler.addChild(successorsHandler);
- successorsHandler.addChild(successorHandler);
- blockHandler.addChild(blockNodesHandler);
- blockNodesHandler.addChild(blockNodeHandler);
-
- nodesHandler.addChild(nodeHandler);
- nodesHandler.addChild(removeNodeHandler);
- edgesHandler.addChild(edgeHandler);
- edgesHandler.addChild(removeEdgeHandler);
-
- methodHandler.addChild(propertiesHandler);
- inlinedMethodHandler.addChild(propertiesHandler);
- topHandler.addChild(propertiesHandler);
- groupHandler.addChild(groupPropertiesHandler);
- graphHandler.addChild(propertiesHandler);
- nodeHandler.addChild(propertiesHandler);
- propertiesHandler.addChild(propertyHandler);
- groupPropertiesHandler.addChild(propertyHandler);
- }
-
- // Returns a new GraphDocument object deserialized from an XML input source.
- @Override
- public GraphDocument parse() throws IOException {
- if (monitor != null) {
- monitor.setState("Starting parsing");
- }
- try {
- XMLReader reader = createReader();
- // To enforce using English for non-English users, we must use Locale.ROOT rather than Locale.ENGLISH
- reader.setProperty("http://apache.org/xml/properties/locale", Locale.ROOT);
- reader.setContentHandler(new XMLParser(xmlDocument, monitor));
- reader.parse(new InputSource(Channels.newInputStream(channel)));
- } catch (SAXException ex) {
- if (!(ex instanceof SAXParseException) || !"XML document structures must start and end within the same entity.".equals(ex.getMessage())) {
- throw new IOException(ex);
- }
- }
- if (monitor != null) {
- monitor.setState("Finished parsing");
- }
- return graphDocument;
- }
-
- // Whether the parser is allowed to defer connecting the parsed elements.
- // Setting to false is useful for synchronization in unit tests.
- public void setInvokeLater(boolean invokeLater) {
- this.invokeLater = invokeLater;
- }
-
- private XMLReader createReader() throws SAXException {
- try {
- SAXParserFactory pfactory = SAXParserFactory.newInstance();
- pfactory.setValidating(false);
- pfactory.setNamespaceAware(true);
- return pfactory.newSAXParser().getXMLReader();
- } catch (ParserConfigurationException ex) {
- throw new SAXException(ex);
- }
- }
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java
index eb3f1451703..f930e478776 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,13 @@ package com.sun.hotspot.igv.data.serialization;
import com.sun.hotspot.igv.data.*;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Writer;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
/**
*
@@ -36,76 +39,47 @@ import java.util.Set;
*/
public class Printer {
- private final InputStream in;
-
- public Printer() {
- this(null);
- }
-
- public Printer(InputStream inputStream) {
- this.in = inputStream;
- }
-
- public void export(Writer writer, GraphDocument document) {
-
+ public static void exportGraphDocument(Writer writer, Folder folder, List contexts) {
XMLWriter xmlWriter = new XMLWriter(writer);
-
try {
- export(xmlWriter, document);
+ xmlWriter.startTag(Parser.ROOT_ELEMENT);
+ xmlWriter.writeProperties(folder.getProperties());
+ for (FolderElement e : folder.getElements()) {
+ if (e instanceof Group group) {
+ exportGroup(xmlWriter, group, contexts);
+ } else if (e instanceof InputGraph graph) {
+ exportInputGraph(xmlWriter, graph, null, false, contexts);
+ }
+ }
+ xmlWriter.endTag();
+ xmlWriter.flush();
} catch (IOException ignored) {}
}
- private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException {
- xmlWriter.startTag(Parser.ROOT_ELEMENT);
- xmlWriter.writeProperties(document.getProperties());
- for (FolderElement e : document.getElements()) {
- if (e instanceof Group) {
- export(xmlWriter, (Group) e);
- } else if (e instanceof InputGraph) {
- export(xmlWriter, (InputGraph)e, null, false);
- }
- }
-
- xmlWriter.endTag();
- xmlWriter.flush();
- }
-
- private void export(XMLWriter writer, Group g) throws IOException {
+ private static void exportGroup(XMLWriter writer, Group g, List contexts) throws IOException {
Properties attributes = new Properties();
attributes.setProperty("difference", Boolean.toString(true));
writer.startTag(Parser.GROUP_ELEMENT, attributes);
writer.writeProperties(g.getProperties());
- boolean shouldExport = true;
- if (in != null) {
- char c = (char) in.read();
- if (c != 'y') {
- shouldExport = false;
- }
+ if (g.getMethod() != null) {
+ exportInputMethod(writer, g.getMethod());
}
- if (shouldExport) {
- if (g.getMethod() != null) {
- export(writer, g.getMethod());
- }
-
- InputGraph previous = null;
- for (FolderElement e : g.getElements()) {
- if (e instanceof InputGraph) {
- InputGraph graph = (InputGraph) e;
- export(writer, graph, previous, true);
- previous = graph;
- } else if (e instanceof Group) {
- export(writer, (Group) e);
- }
+ InputGraph previous = null;
+ for (FolderElement e : g.getElements()) {
+ if (e instanceof InputGraph graph) {
+ exportInputGraph(writer, graph, previous, true, contexts);
+ previous = graph;
+ } else if (e instanceof Group group) {
+ exportGroup(writer, group, contexts);
}
}
writer.endTag();
}
- public void export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference) throws IOException {
-
+ private static void exportInputGraph(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference, List contexts) throws IOException {
writer.startTag(Parser.GRAPH_ELEMENT);
writer.writeProperties(graph.getProperties());
writer.startTag(Parser.NODES_ELEMENT);
@@ -135,11 +109,11 @@ public class Printer {
if (!difference || !equal.contains(n)) {
writer.startTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId())));
writer.writeProperties(n.getProperties());
- writer.endTag();
+ writer.endTag(); // Parser.NODE_ELEMENT
}
}
- writer.endTag();
+ writer.endTag(); // Parser.NODES_ELEMENT
writer.startTag(Parser.EDGES_ELEMENT);
Set removedEdges = new HashSet<>();
@@ -169,45 +143,78 @@ public class Printer {
}
}
- writer.endTag();
+ writer.endTag(); // Parser.EDGES_ELEMENT
writer.startTag(Parser.CONTROL_FLOW_ELEMENT);
for (InputBlock b : graph.getBlocks()) {
writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName()));
- if (b.getSuccessors().size() > 0) {
+ if (!b.getSuccessors().isEmpty()) {
writer.startTag(Parser.SUCCESSORS_ELEMENT);
for (InputBlock s : b.getSuccessors()) {
writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
}
- writer.endTag();
+ writer.endTag(); // Parser.SUCCESSORS_ELEMENT
}
- if (b.getNodes().size() > 0) {
- writer.startTag(Parser.NODES_ELEMENT);
+ if (!b.getNodes().isEmpty()) {
+ writer.startTag(Parser.NODES_ELEMENT);
for (InputNode n : b.getNodes()) {
writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
}
- writer.endTag();
+ writer.endTag(); // Parser.NODES_ELEMENT
}
- writer.endTag();
+ writer.endTag(); // Parser.BLOCK_ELEMENT
}
- writer.endTag();
- writer.endTag();
+ writer.endTag(); // Parser.CONTROL_FLOW_ELEMENT
+
+ exportStates(writer, graph, contexts);
+
+ writer.endTag(); // Parser.GRAPH_ELEMENT
}
- private void export(XMLWriter w, InputMethod method) throws IOException {
+ private static void exportStates(XMLWriter writer, InputGraph exportingGraph, List contexts) throws IOException {
+ List contextsContainingGraph = contexts.stream()
+ .filter(context -> context.inputGraph().equals(exportingGraph))
+ .toList();
+ if (contextsContainingGraph.isEmpty()) {
+ return;
+ }
+
+ writer.startTag(Parser.GRAPH_STATES_ELEMENT);
+
+ for (GraphContext context : contextsContainingGraph) {
+ assert exportingGraph == context.inputGraph();
+
+ writer.startTag(Parser.STATE_ELEMENT);
+
+ writer.simpleTag(Parser.STATE_POSITION_DIFFERENCE,
+ new Properties(Parser.POSITION_DIFFERENCE_PROPERTY, Integer.toString(context.posDiff().get())));
+
+ writer.startTag(Parser.VISIBLE_NODES_ELEMENT, new Properties(Parser.ALL_PROPERTY, Boolean.toString(context.showAll().get())));
+ for (Integer hiddenNodeID : context.visibleNodes()) {
+ writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, hiddenNodeID.toString()));
+ }
+ writer.endTag(); // Parser.VISIBLE_NODES_ELEMENT
+
+ writer.endTag(); // Parser.STATES_ELEMENT
+ }
+
+ writer.endTag(); // Parser.GRAPH_STATE_ELEMENT
+ }
+
+ private static void exportInputMethod(XMLWriter w, InputMethod method) throws IOException {
w.startTag(Parser.METHOD_ELEMENT, new Properties(Parser.METHOD_BCI_PROPERTY, method.getBci() + "", Parser.METHOD_NAME_PROPERTY, method.getName(), Parser.METHOD_SHORT_NAME_PROPERTY, method.getShortName()));
w.writeProperties(method.getProperties());
- if (method.getInlined().size() > 0) {
+ if (!method.getInlined().isEmpty()) {
w.startTag(Parser.INLINE_ELEMENT);
for (InputMethod m : method.getInlined()) {
- export(w, m);
+ exportInputMethod(w, m);
}
w.endTag();
}
@@ -229,7 +236,7 @@ public class Printer {
w.endTag();
}
- private Properties createProperties(InputEdge edge) {
+ private static Properties createProperties(InputEdge edge) {
Properties p = new Properties();
if (edge.getToIndex() != 0) {
p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
@@ -242,4 +249,10 @@ public class Printer {
p.setProperty(Parser.TYPE_PROPERTY, edge.getType());
return p;
}
+
+ public record GraphContext(InputGraph inputGraph, AtomicInteger posDiff, Set visibleNodes, AtomicBoolean showAll) { }
+
+ public interface GraphContextAction {
+ void performAction(GraphContext context);
+ }
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GraphViewer.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GraphViewer.java
index ebaa03df282..3cef9c4fc95 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GraphViewer.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GraphViewer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@ import com.sun.hotspot.igv.data.InputGraph;
*/
public interface GraphViewer {
- void view(InputGraph graph, boolean newTab);
+ InputGraph view(InputGraph graph, boolean newTab);
- void viewDifference(InputGraph firstGraph, InputGraph secondGraph);
+ InputGraph viewDifference(InputGraph firstGraph, InputGraph secondGraph);
}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GroupCallback.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GroupCallback.java
deleted file mode 100644
index b35f3eabf89..00000000000
--- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/GroupCallback.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.data.services;
-
-import com.sun.hotspot.igv.data.Group;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface GroupCallback {
-
- public void started(Group g);
-}
diff --git a/src/utils/IdealGraphVisualizer/Data/src/test/java/com/sun/hotspot/igv/data/serialization/ParserTest.java b/src/utils/IdealGraphVisualizer/Data/src/test/java/com/sun/hotspot/igv/data/serialization/ParserTest.java
index 43426046448..9788ee4443c 100644
--- a/src/utils/IdealGraphVisualizer/Data/src/test/java/com/sun/hotspot/igv/data/serialization/ParserTest.java
+++ b/src/utils/IdealGraphVisualizer/Data/src/test/java/com/sun/hotspot/igv/data/serialization/ParserTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import static java.nio.charset.StandardCharsets.UTF_8;
+import java.util.ArrayList;
+import java.util.HashSet;
import org.junit.*;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -62,19 +64,18 @@ public class ParserTest {
}
private void test(GraphDocument document) {
- final Printer printer = new Printer();
final CharArrayWriter writer = new CharArrayWriter();
- printer.export(writer, document);
+ Printer.exportGraphDocument(writer, document, new ArrayList<>());
test(document, writer.toString());
}
private void test(GraphDocument document, String xmlString) {
InputStream in = new ByteArrayInputStream(xmlString.getBytes(UTF_8));
try {
- Parser parser = new Parser(Channels.newChannel(in));
+ Parser parser = new Parser(Channels.newChannel(in), null, null, null);
parser.setInvokeLater(false);
- final GraphDocument parsedDocument = parser.parse();
- Util.assertGraphDocumentEquals(document, parsedDocument);
+ final GraphDocument exportData = parser.parse();
+ Util.assertGraphDocumentEquals(document, exportData);
} catch (IOException ex) {
fail(ex.toString());
}
diff --git a/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Client.java b/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Client.java
deleted file mode 100644
index 2f4b6cff0db..00000000000
--- a/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Client.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.connection;
-
-import com.sun.hotspot.igv.data.serialization.Parser;
-import com.sun.hotspot.igv.data.services.GroupCallback;
-import java.io.IOException;
-import java.nio.channels.SocketChannel;
-import org.openide.util.Exceptions;
-
-public class Client implements Runnable {
- private final SocketChannel socket;
- private final GroupCallback callback;
-
- public Client(SocketChannel socket, GroupCallback callback) {
- this.callback = callback;
- this.socket = socket;
- }
-
- @Override
- public void run() {
-
- try {
- final SocketChannel channel = socket;
- channel.configureBlocking(true);
- channel.socket().getOutputStream().write('y');
- new Parser(channel, null, callback).parse();
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- } finally {
- try {
- socket.close();
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- }
-}
diff --git a/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Server.java b/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Server.java
index 523f4d2017d..a507c568be2 100644
--- a/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Server.java
+++ b/src/utils/IdealGraphVisualizer/NetworkConnection/src/main/java/com/sun/hotspot/igv/connection/Server.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,9 @@
*/
package com.sun.hotspot.igv.connection;
-import com.sun.hotspot.igv.data.services.GroupCallback;
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.Parser;
+import com.sun.hotspot.igv.data.serialization.Printer.GraphContextAction;
import com.sun.hotspot.igv.settings.Settings;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -32,9 +34,6 @@ import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
-import org.openide.util.RequestProcessor;
/**
*
@@ -42,13 +41,16 @@ import org.openide.util.RequestProcessor;
*/
public class Server implements PreferenceChangeListener {
private ServerSocketChannel serverSocket;
- private final GroupCallback callback;
+ private final GraphDocument graphDocument;
+ private final GraphContextAction contextAction;
private int port;
- private Runnable serverRunnable;
- public Server(GroupCallback callback) {
- this.callback = callback;
- initializeNetwork();
+ private volatile boolean isServerRunning;
+
+ public Server(GraphDocument graphDocument, GraphContextAction contextAction) {
+ this.graphDocument = graphDocument;
+ this.contextAction = contextAction;
+ port = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
Settings.get().addPreferenceChangeListener(this);
}
@@ -56,46 +58,65 @@ public class Server implements PreferenceChangeListener {
public void preferenceChange(PreferenceChangeEvent e) {
int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
if (curPort != port) {
- initializeNetwork();
+ port = curPort;
+ shutdownServer();
+ startServer();
}
}
- private void initializeNetwork() {
- int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
- this.port = curPort;
+ public void startServer() {
+ isServerRunning = true;
+
try {
serverSocket = ServerSocketChannel.open();
- serverSocket.bind(new InetSocketAddress(curPort));
- } catch (Throwable ex) {
- NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
- DialogDisplayer.getDefault().notifyLater(message);
+ serverSocket.bind(new InetSocketAddress(port));
+ } catch (IOException ex) {
+ ex.printStackTrace();
return;
}
- Runnable runnable = new Runnable() {
-
- @Override
- public void run() {
- while (true) {
- try {
- SocketChannel clientSocket = serverSocket.accept();
- if (serverRunnable != this) {
- clientSocket.close();
- return;
- }
- RequestProcessor.getDefault().post(new Client(clientSocket, callback), 0, Thread.MAX_PRIORITY);
- } catch (IOException ex) {
- serverSocket = null;
- NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
- DialogDisplayer.getDefault().notifyLater(message);
+ Runnable client = () -> {
+ while (isServerRunning) {
+ try {
+ SocketChannel clientSocket = serverSocket.accept();
+ if (!isServerRunning) {
+ clientSocket.close();
return;
}
+ new Thread(() -> {
+ try (clientSocket) {
+ clientSocket.configureBlocking(true);
+ clientSocket.socket().getOutputStream().write('y');
+ new Parser(clientSocket, null, graphDocument, contextAction).parse();
+ } catch (IOException ignored) {}
+ }).start();
+ } catch (IOException ex) {
+ if (isServerRunning) {
+ ex.printStackTrace();
+ }
+ return;
}
}
+ try {
+ if (serverSocket != null) {
+ serverSocket.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
};
- serverRunnable = runnable;
+ new Thread(client).start();
+ }
- RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
+ public void shutdownServer() {
+ isServerRunning = false;
+ try {
+ if (serverSocket != null) {
+ serverSocket.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
}
}
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java
index 23cd4a4360f..e47518de4a7 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java
@@ -652,7 +652,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
Rectangle bounds = rootWidget.getBounds();
if (bounds != null) {
Point location = rootWidget.getLocation();
- centerRectangle(new Rectangle(location.x, location.y, bounds.width, bounds.height));
+ centerRectangle(new Rectangle(location.x, location.y, bounds.width, bounds.height), false);
}
}
}
@@ -872,7 +872,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
private void gotoBlock(final Block block) {
BlockWidget bw = getWidget(block.getInputBlock());
if (bw != null) {
- centerRectangle(bw.getBounds());
+ centerRectangle(bw.getBounds(), true);
}
}
@@ -919,26 +919,28 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl
}
}
if (overallRect != null) {
- centerRectangle(overallRect);
+ centerRectangle(overallRect, true);
}
}
- private void centerRectangle(Rectangle r) {
+ private void centerRectangle(Rectangle r, boolean zoomToFit) {
Rectangle rect = convertSceneToView(r);
Rectangle viewRect = scrollPane.getViewport().getViewRect();
-
- double factor = Math.min(viewRect.getWidth() / rect.getWidth(), viewRect.getHeight() / rect.getHeight());
- double zoomFactor = getZoomFactor();
- double newZoomFactor = zoomFactor * factor;
- if (factor < 1.0 || zoomFactor < 1.0) {
- newZoomFactor = Math.min(1.0, newZoomFactor);
- centredZoom(newZoomFactor, null);
- factor = newZoomFactor / zoomFactor;
- rect.x *= factor;
- rect.y *= factor;
- rect.width *= factor;
- rect.height *= factor;
+ if (zoomToFit) {
+ double factor = Math.min(viewRect.getWidth() / rect.getWidth(), viewRect.getHeight() / rect.getHeight());
+ double zoomFactor = getZoomFactor();
+ double newZoomFactor = zoomFactor * factor;
+ if (factor < 1.0 || zoomFactor < 1.0) {
+ newZoomFactor = Math.min(1.0, newZoomFactor);
+ centredZoom(newZoomFactor, null);
+ factor = newZoomFactor / zoomFactor;
+ rect.x *= factor;
+ rect.y *= factor;
+ rect.width *= factor;
+ rect.height *= factor;
+ }
}
+
viewRect.x = rect.x + rect.width / 2 - viewRect.width / 2;
viewRect.y = rect.y + rect.height / 2 - viewRect.height / 2;
// Ensure to be within area
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
index f48e05ec6b9..6d7599e6d34 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
@@ -332,6 +332,14 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
final HashSet allNodes = new HashSet<>(getGroup().getAllNodes());
allNodes.removeAll(nodes);
setHiddenNodes(allNodes);
+
+
+ }
+
+ public Set getVisibleNodes() {
+ final Set visibleNodes = new HashSet<>(getGraph().getNodesAsSet());
+ visibleNodes.removeAll(hiddenNodes);
+ return visibleNodes;
}
public void setHiddenNodes(Set nodes) {
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
index 57d2b006ac0..617f59a591d 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,8 +125,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
Group group = diagramViewModel.getGroup();
group.getChangedEvent().addListener(g -> closeOnRemovedOrEmptyGroup());
- if (group.getParent() instanceof GraphDocument) {
- final GraphDocument doc = (GraphDocument) group.getParent();
+ if (group.getParent() instanceof GraphDocument doc) {
doc.getChangedEvent().addListener(d -> closeOnRemovedOrEmptyGroup());
}
@@ -309,8 +308,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
l.add(m.getSelectedTopComponent());
l.addAll(Arrays.asList(manager.getOpenedTopComponents(m)));
for (TopComponent t : l) {
- if (t instanceof EditorTopComponent) {
- EditorTopComponent etc = (EditorTopComponent) t;
+ if (t instanceof EditorTopComponent etc) {
if (etc.getModel().getGroup().getGraphs().contains(graph)) {
return etc;
}
@@ -320,17 +318,31 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
return null;
}
+ public static void closeAllInstances() {
+ WindowManager manager = WindowManager.getDefault();
+ for (Mode mode : manager.getModes()) {
+ TopComponent[] openedTopComponents = manager.getOpenedTopComponents(mode);
+ for (TopComponent tc : openedTopComponents) {
+ if (tc instanceof EditorTopComponent etc) {
+ etc.close();
+ }
+ }
+ }
+ }
+
@Override
public int getPersistenceType() {
return TopComponent.PERSISTENCE_NEVER;
}
private void closeOnRemovedOrEmptyGroup() {
- Group group = getModel().getGroup();
- if (!group.getParent().getElements().contains(group) ||
- group.getGraphs().isEmpty()) {
- close();
- }
+ SwingUtilities.invokeLater(() -> {
+ Group group = getModel().getGroup();
+ if (!group.getParent().getElements().contains(group) ||
+ group.getGraphs().isEmpty()) {
+ close();
+ }
+ });
}
public void addSelectedNodes(Collection nodes, boolean showIfHidden) {
@@ -405,8 +417,7 @@ public final class EditorTopComponent extends TopComponent implements TopCompone
WindowManager manager = WindowManager.getDefault();
for (Mode m : manager.getModes()) {
for (TopComponent topComponent : manager.getOpenedTopComponents(m)) {
- if (topComponent instanceof EditorTopComponent) {
- EditorTopComponent editor = (EditorTopComponent) topComponent;
+ if (topComponent instanceof EditorTopComponent editor) {
editor.setBoldDisplayName(false);
}
}
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java
index d4b88135408..04e63ebbc5f 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/GraphViewerImplementation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@ package com.sun.hotspot.igv.view;
import com.sun.hotspot.igv.data.InputGraph;
import com.sun.hotspot.igv.data.services.GraphViewer;
import com.sun.hotspot.igv.difference.Difference;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.settings.Settings;
import org.openide.util.lookup.ServiceProvider;
/**
@@ -38,33 +36,37 @@ import org.openide.util.lookup.ServiceProvider;
public class GraphViewerImplementation implements GraphViewer {
@Override
- public void viewDifference(InputGraph firstGraph, InputGraph secondGraph) {
+ public InputGraph viewDifference(InputGraph firstGraph, InputGraph secondGraph) {
if (firstGraph.getGroup() != secondGraph.getGroup()) {
InputGraph diffGraph = Difference.createDiffGraph(firstGraph, secondGraph);
- view(diffGraph, true);
+ return view(diffGraph, true);
} else {
- view(firstGraph, true);
- EditorTopComponent etc = EditorTopComponent.findEditorForGraph(firstGraph);
- if (etc != null) {
- etc.getModel().selectDiffGraph(secondGraph);
- etc.requestActive();
+ if (view(firstGraph, true) != null) {
+ EditorTopComponent etc = EditorTopComponent.findEditorForGraph(firstGraph);
+ if (etc != null) {
+ etc.getModel().selectDiffGraph(secondGraph);
+ etc.requestActive();
+ return etc.getModel().getGraph();
+ }
}
+ return null;
}
}
@Override
- public void view(InputGraph graph, boolean newTab) {
+ public InputGraph view(InputGraph graph, boolean newTab) {
if (!newTab) {
EditorTopComponent etc = EditorTopComponent.findEditorForGraph(graph);
if (etc != null) {
etc.getModel().selectGraph(graph);
etc.requestActive();
- return;
+ return etc.getModel().getGraph();
}
}
DiagramViewModel model = new DiagramViewModel(graph);
EditorTopComponent etc = new EditorTopComponent(model);
etc.open();
etc.requestActive();
+ return etc.getModel().getGraph();
}
}