Skip to content

Commit b4d9f11

Browse files
VoragoFylmTM
authored andcommitted
Provide query example for metadata using context menu (#19)
* Added context menu for labels, relationship, property keys * Added context menu for data sources * Added interface for TreeNode userObject
1 parent cbfbb6c commit b4d9f11

26 files changed

+764
-38
lines changed

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/actions/execute/ExecuteQueryPayload.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import com.intellij.openapi.editor.Editor;
44
import org.jetbrains.annotations.NotNull;
55

6+
import java.util.Optional;
7+
68
public class ExecuteQueryPayload {
79

810
private final String content;
9-
1011
private final Editor editor;
1112

13+
public ExecuteQueryPayload(String content) {
14+
this.content = content;
15+
this.editor = null;
16+
}
17+
1218
public ExecuteQueryPayload(String content, Editor editor) {
1319
this.content = content;
1420
this.editor = editor;
@@ -20,8 +26,8 @@ public String getContent() {
2026
}
2127

2228
@NotNull
23-
public Editor getEditor() {
24-
return editor;
29+
public Optional<Editor> getEditor() {
30+
return Optional.ofNullable(editor);
2531
}
2632

2733
}

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/component/datasource/metadata/Neo4jBoltCypherDataSourceMetadata.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@ public boolean isMetadataExists(final String metadataKey) {
3030
}
3131

3232
public void addLabels(GraphQueryResult labelsQueryResult) {
33-
addDataSourceMetadata(labelsQueryResult, LABELS);
33+
addDataSourceMetadata(LABELS, labelsQueryResult);
3434
}
3535

3636
public void addRelationshipTypes(GraphQueryResult relationshipQueryResult) {
37-
addDataSourceMetadata(relationshipQueryResult, RELATIONSHIP_TYPES);
37+
addDataSourceMetadata(RELATIONSHIP_TYPES, relationshipQueryResult);
3838
}
3939

4040
public void addPropertyKeys(GraphQueryResult propertyKeysResult) {
41-
addDataSourceMetadata(propertyKeysResult, PROPERTY_KEYS);
41+
addDataSourceMetadata(PROPERTY_KEYS, propertyKeysResult);
4242
}
4343

4444
public void addStoredProcedures(GraphQueryResult storedProceduresResult) {
45-
addDataSourceMetadata(storedProceduresResult, STORED_PROCEDURES);
45+
addDataSourceMetadata(STORED_PROCEDURES, storedProceduresResult);
4646
}
4747

4848
public void addUserFunctions(GraphQueryResult userFunctionsResult) {
49-
addDataSourceMetadata(userFunctionsResult, USER_FUNCTIONS);
49+
addDataSourceMetadata(USER_FUNCTIONS, userFunctionsResult);
5050
}
5151

52-
private void addDataSourceMetadata(GraphQueryResult graphQueryResult, String key) {
52+
private void addDataSourceMetadata(String key, GraphQueryResult graphQueryResult) {
5353
List<Map<String, String>> dataSourceMetadata = new ArrayList<>();
5454

5555
List<GraphQueryResultColumn> columns = graphQueryResult.getColumns();
@@ -65,4 +65,8 @@ private void addDataSourceMetadata(GraphQueryResult graphQueryResult, String key
6565

6666
dataReceiver.put(key, dataSourceMetadata);
6767
}
68+
69+
public void addDataSourceMetadata(String key, List<Map<String, String>> data) {
70+
dataReceiver.put(key, data);
71+
}
6872
}

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/graph/GraphPanel.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@
2929
import java.awt.event.MouseEvent;
3030
import java.util.Enumeration;
3131

32-
import static com.neueda.jetbrains.plugin.graphdb.visualization.util.DisplayUtil.*;
32+
import static com.neueda.jetbrains.plugin.graphdb.visualization.util.DisplayUtil.getTooltipText;
33+
import static com.neueda.jetbrains.plugin.graphdb.visualization.util.DisplayUtil.getTooltipTitle;
3334

3435
public class GraphPanel {
3536

36-
private static final int TYPES_DEPTH = 2;
37-
private static final int PROPERTY_DEPTH = 3;
38-
3937
private PrefuseVisualization visualization;
4038
private LookAndFeelService lookAndFeelService;
4139
private BalloonBuilder balloonPopupBuilder;

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/console/graph/GraphPanelInteractions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void postResultReceived(ExecuteQueryPayload payload) {
6161
@Override
6262
public void handleError(ExecuteQueryPayload payload, Exception exception) {
6363
String errorMessage = exception.getMessage() == null ? "Error occurred" : "Error occurred: " + exception.getMessage();
64-
HintManager.getInstance().showErrorHint(payload.getEditor(), errorMessage);
64+
payload.getEditor().ifPresent(editor -> HintManager.getInstance().showErrorHint(editor, errorMessage));
6565

6666
visualization.stop();
6767
visualization.clear();

ui/jetbrains/src/main/java/com/neueda/jetbrains/plugin/graphdb/jetbrains/ui/datasource/DataSourcesView.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.actions.RefreshDataSourcesAction;
1919
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.interactions.DataSourceInteractions;
2020
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.metadata.DataSourceMetadataUi;
21-
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.GraphColoredTreeCellRenderer;
21+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.RootTreeNodeModel;
22+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.*;
2223
import com.neueda.jetbrains.plugin.graphdb.jetbrains.util.FileUtil;
2324
import com.neueda.jetbrains.plugin.graphdb.language.cypher.completion.metadata.CypherMetadataProviderService;
2425

@@ -30,6 +31,7 @@
3031
import java.io.IOException;
3132
import java.util.Enumeration;
3233
import java.util.List;
34+
import java.util.Objects;
3335

3436
public class DataSourcesView implements Disposable {
3537

@@ -62,7 +64,7 @@ public void initToolWindow(Project project, ToolWindow toolWindow) {
6264
componentMetadata = project.getComponent(DataSourcesComponentMetadata.class);
6365
cypherMetadataProviderService = ServiceManager.getService(project, CypherMetadataProviderService.class);
6466
dataSourceMetadataUi = new DataSourceMetadataUi(componentMetadata);
65-
treeRoot = new PatchedDefaultMutableTreeNode("treeRoot");
67+
treeRoot = new PatchedDefaultMutableTreeNode(new RootTreeNodeModel());
6668
treeModel = new DefaultTreeModel(treeRoot, false);
6769
decorator = ToolbarDecorator.createDecorator(dataSourceTree);
6870
decorator.addExtraAction(new RefreshDataSourcesAction(this));
@@ -110,6 +112,7 @@ private void configureDataSourceTree() {
110112
dataSourceTree.setModel(treeModel);
111113
dataSourceTree.setRootVisible(false);
112114
dataSourceTree.setToggleClickCount(0);
115+
dataSourceTree.addMouseListener(new DataSourcesTreeMouseAdapter());
113116
}
114117

115118
private void decorateDataSourceTree() {
@@ -124,7 +127,7 @@ private void replaceTreeWithDecorated() {
124127

125128
private void showDataSources() {
126129
component.getDataSourceContainer().getDataSources()
127-
.forEach((dataSource) -> treeRoot.add(new PatchedDefaultMutableTreeNode(dataSource)));
130+
.forEach((dataSource) -> treeRoot.add(new PatchedDefaultMutableTreeNode(new DataSourceTreeNodeModel(dataSource))));
128131
treeModel.reload();
129132
}
130133

@@ -143,15 +146,17 @@ public void refreshDataSourcesMetadata() {
143146
}
144147

145148
public boolean refreshDataSourceMetadata(PatchedDefaultMutableTreeNode treeNode) {
146-
DataSourceApi nodeDataSource = (DataSourceApi) treeNode.getUserObject();
149+
TreeNodeModelApi userObject = (TreeNodeModelApi) treeNode.getUserObject();
150+
DataSourceApi nodeDataSource = userObject.getDataSourceApi();
147151
Analytics.event(nodeDataSource, "refreshMetadata");
148152
return dataSourceMetadataUi.updateDataSourceMetadataUi(treeNode, nodeDataSource);
149153
}
150154

151155
public void createDataSource(DataSourceApi dataSource) {
152156
Analytics.event(dataSource, "create");
153157
component.getDataSourceContainer().addDataSource(dataSource);
154-
PatchedDefaultMutableTreeNode treeNode = new PatchedDefaultMutableTreeNode(dataSource);
158+
TreeNodeModelApi model = new DataSourceTreeNodeModel(dataSource);
159+
PatchedDefaultMutableTreeNode treeNode = new PatchedDefaultMutableTreeNode(model);
155160
treeRoot.add(treeNode);
156161
refreshDataSourceMetadata(treeNode);
157162
treeModel.reload();
@@ -160,7 +165,7 @@ public void createDataSource(DataSourceApi dataSource) {
160165
public void updateDataSource(PatchedDefaultMutableTreeNode treeNode, DataSourceApi oldDataSource, DataSourceApi newDataSource) {
161166
Analytics.event(newDataSource, "update");
162167
component.getDataSourceContainer().updateDataSource(oldDataSource, newDataSource);
163-
treeNode.setUserObject(newDataSource);
168+
treeNode.setUserObject(new DataSourceTreeNodeModel(newDataSource));
164169
refreshDataSourceMetadata(treeNode);
165170
treeModel.reload();
166171
}
@@ -184,14 +189,15 @@ public void removeDataSources(Project project, List<DataSourceApi> dataSourcesFo
184189
Enumeration enumeration = treeRoot.children();
185190
while (enumeration.hasMoreElements()) {
186191
DefaultMutableTreeNode element = (DefaultMutableTreeNode) enumeration.nextElement();
187-
DataSourceApi dataSource = (DataSourceApi) element.getUserObject();
192+
TreeNodeModelApi userObject = (TreeNodeModelApi) element.getUserObject();
193+
DataSourceApi dataSource = userObject.getDataSourceApi();
188194
if (dataSource.getName().equals(name)) {
189195
return element;
190196
}
191197
}
192198
return null;
193199
})
194-
.filter(ds -> ds != null)
200+
.filter(Objects::nonNull)
195201
.forEach(treeRoot::remove);
196202

197203
treeModel.reload();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.actions;
2+
3+
import com.intellij.openapi.actionSystem.AnAction;
4+
import com.intellij.openapi.actionSystem.AnActionEvent;
5+
import com.intellij.openapi.project.Project;
6+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.analytics.Analytics;
7+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.state.DataSourceApi;
8+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.util.FileUtil;
9+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.util.Notifier;
10+
11+
import javax.swing.*;
12+
import java.io.IOException;
13+
14+
public class DataSourceAction extends AnAction {
15+
16+
private DataSourceApi dataSource;
17+
18+
DataSourceAction(String title, String description, Icon icon, DataSourceApi dataSource) {
19+
super(title, description, icon);
20+
this.dataSource = dataSource;
21+
}
22+
23+
@Override
24+
public void actionPerformed(AnActionEvent e) {
25+
Analytics.event(dataSource, "openEditor");
26+
Project project = getEventProject(e);
27+
try {
28+
FileUtil.openFile(project, FileUtil.getDataSourceFile(project, dataSource));
29+
} catch (IOException exception) {
30+
Notifier.error("Open editor error", exception.getMessage());
31+
}
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.actions;
2+
3+
import com.intellij.openapi.actionSystem.ActionGroup;
4+
import com.intellij.openapi.actionSystem.AnAction;
5+
import com.intellij.openapi.actionSystem.AnActionEvent;
6+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.state.DataSourceApi;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.jetbrains.annotations.Nullable;
9+
10+
public class DataSourceActionGroup extends ActionGroup {
11+
12+
private final DataSourceApi dataSourceApi;
13+
14+
public DataSourceActionGroup(DataSourceApi dataSourceApi) {
15+
this.dataSourceApi = dataSourceApi;
16+
}
17+
18+
@NotNull
19+
@Override
20+
public AnAction[] getChildren(@Nullable AnActionEvent e) {
21+
return new AnAction[]{new DataSourceAction("Open editor", "", null, dataSourceApi)};
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
package com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.metadata;
22

33
import com.intellij.ui.treeStructure.PatchedDefaultMutableTreeNode;
4-
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.*;
4+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.DataSourceMetadata;
5+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.DataSourcesComponentMetadata;
6+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.metadata.Neo4jBoltCypherDataSourceMetadata;
57
import com.neueda.jetbrains.plugin.graphdb.jetbrains.component.datasource.state.DataSourceApi;
6-
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.dto.ValueWithIcon;
8+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.MetadataTreeNodeModel;
9+
import com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.TreeNodeModelApi;
710
import com.neueda.jetbrains.plugin.graphdb.platform.GraphIcons;
811

12+
import static com.neueda.jetbrains.plugin.graphdb.jetbrains.ui.datasource.tree.Neo4jTreeNodeType.*;
13+
914
public class DataSourceMetadataUi {
1015

16+
private static final String RELATIONSHIP_TYPES_TITLE = "relationship types";
17+
private static final String PROPERTY_KEYS_TITLE = "property keys";
18+
private static final String LABELS_TITLE = "labels";
19+
private static final String STORED_PROCEDURES_TITLE = "stored procedures";
20+
private static final String USER_FUNCTIONS_TITLE = "user functions";
21+
1122
private final DataSourcesComponentMetadata dataSourcesComponent;
1223

1324
public DataSourceMetadataUi(DataSourcesComponentMetadata dataSourcesComponent) {
@@ -26,43 +37,45 @@ public boolean updateDataSourceMetadataUi(PatchedDefaultMutableTreeNode node, Da
2637
}
2738

2839
// ui
29-
private boolean updateNeo4jBoltCypherMetadataUi(PatchedDefaultMutableTreeNode dataSourceRootTreeNode,
40+
boolean updateNeo4jBoltCypherMetadataUi(PatchedDefaultMutableTreeNode dataSourceRootTreeNode,
3041
DataSourceMetadata dataSourceMetadata) {
3142
// Remove existing metadata from ui
3243
dataSourceRootTreeNode.removeAllChildren();
44+
TreeNodeModelApi model = (TreeNodeModelApi) dataSourceRootTreeNode.getUserObject();
45+
DataSourceApi dataSourceApi = model.getDataSourceApi();
3346

3447
// Labels
3548
PatchedDefaultMutableTreeNode labelsTreeNode = new PatchedDefaultMutableTreeNode(
36-
new ValueWithIcon(GraphIcons.Nodes.LABEL, "labels"));
49+
new MetadataTreeNodeModel(LABELS, dataSourceApi, LABELS_TITLE, GraphIcons.Nodes.LABEL));
3750
dataSourceMetadata
3851
.getMetadata(Neo4jBoltCypherDataSourceMetadata.LABELS)
39-
.forEach((row) -> labelsTreeNode.add(new PatchedDefaultMutableTreeNode(row.get("label"))));
52+
.forEach((row) -> labelsTreeNode.add(of(new MetadataTreeNodeModel(LABEL, dataSourceApi, row.get("label")))));
4053
dataSourceRootTreeNode.add(labelsTreeNode);
4154

4255
// RelTypes
4356
PatchedDefaultMutableTreeNode relationshipTypesTreeNode = new PatchedDefaultMutableTreeNode(
44-
new ValueWithIcon(GraphIcons.Nodes.RELATIONSHIP_TYPE, "relationship types"));
57+
new MetadataTreeNodeModel(RELATIONSHIPS, dataSourceApi, RELATIONSHIP_TYPES_TITLE, GraphIcons.Nodes.RELATIONSHIP_TYPE));
4558
dataSourceMetadata
4659
.getMetadata(Neo4jBoltCypherDataSourceMetadata.RELATIONSHIP_TYPES)
47-
.forEach((row) -> relationshipTypesTreeNode.add(new PatchedDefaultMutableTreeNode(row.get("relationshipType"))));
60+
.forEach((row) -> relationshipTypesTreeNode.add(of(new MetadataTreeNodeModel(RELATIONSHIP, dataSourceApi, row.get("relationshipType")))));
4861
dataSourceRootTreeNode.add(relationshipTypesTreeNode);
4962

5063
// Property Keys
5164
PatchedDefaultMutableTreeNode propertyKeysTreeNode = new PatchedDefaultMutableTreeNode(
52-
new ValueWithIcon(GraphIcons.Nodes.PROPERTY_KEY, "property keys"));
65+
new MetadataTreeNodeModel(PROPERTY_KEYS, dataSourceApi, PROPERTY_KEYS_TITLE, GraphIcons.Nodes.PROPERTY_KEY));
5366
dataSourceMetadata
5467
.getMetadata(Neo4jBoltCypherDataSourceMetadata.PROPERTY_KEYS)
55-
.forEach((row) -> propertyKeysTreeNode.add(new PatchedDefaultMutableTreeNode(row.get("propertyKey"))));
68+
.forEach((row) -> propertyKeysTreeNode.add(of(new MetadataTreeNodeModel(PROPERTY_KEY, dataSourceApi, row.get("propertyKey")))));
5669
dataSourceRootTreeNode.add(propertyKeysTreeNode);
5770

5871
// Stored procedures
5972
PatchedDefaultMutableTreeNode storedProceduresTreeNode = new PatchedDefaultMutableTreeNode(
60-
new ValueWithIcon(GraphIcons.Nodes.STORED_PROCEDURE, "stored procedures"));
73+
new MetadataTreeNodeModel(STORED_PROCEDURES, dataSourceApi, STORED_PROCEDURES_TITLE, GraphIcons.Nodes.STORED_PROCEDURE));
6174
dataSourceMetadata
6275
.getMetadata(Neo4jBoltCypherDataSourceMetadata.STORED_PROCEDURES)
6376
.forEach((row) -> {
64-
PatchedDefaultMutableTreeNode nameNode = new PatchedDefaultMutableTreeNode(row.get("name"));
65-
PatchedDefaultMutableTreeNode descriptionNode = new PatchedDefaultMutableTreeNode(row.get("signature"));
77+
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("name")));
78+
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(STORED_PROCEDURE, dataSourceApi, row.get("signature")));
6679
nameNode.add(descriptionNode);
6780
storedProceduresTreeNode.add(nameNode);
6881
});
@@ -71,13 +84,13 @@ private boolean updateNeo4jBoltCypherMetadataUi(PatchedDefaultMutableTreeNode da
7184
// User Functions
7285
if (dataSourceMetadata.isMetadataExists(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS)) {
7386
PatchedDefaultMutableTreeNode userFunctionTreeNode = new PatchedDefaultMutableTreeNode(
74-
new ValueWithIcon(GraphIcons.Nodes.USER_FUNCTION, "user functions"));
87+
new MetadataTreeNodeModel(USER_FUNCTIONS, dataSourceApi, USER_FUNCTIONS_TITLE, GraphIcons.Nodes.USER_FUNCTION));
7588

7689
dataSourceMetadata
7790
.getMetadata(Neo4jBoltCypherDataSourceMetadata.USER_FUNCTIONS)
7891
.forEach((row) -> {
79-
PatchedDefaultMutableTreeNode nameNode = new PatchedDefaultMutableTreeNode(row.get("name"));
80-
PatchedDefaultMutableTreeNode descriptionNode = new PatchedDefaultMutableTreeNode(row.get("signature"));
92+
PatchedDefaultMutableTreeNode nameNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("name")));
93+
PatchedDefaultMutableTreeNode descriptionNode = of(new MetadataTreeNodeModel(USER_FUNCTION, dataSourceApi, row.get("signature")));
8194
nameNode.add(descriptionNode);
8295
userFunctionTreeNode.add(nameNode);
8396
});
@@ -87,4 +100,8 @@ private boolean updateNeo4jBoltCypherMetadataUi(PatchedDefaultMutableTreeNode da
87100

88101
return true;
89102
}
103+
104+
private PatchedDefaultMutableTreeNode of(MetadataTreeNodeModel model) {
105+
return new PatchedDefaultMutableTreeNode(model);
106+
}
90107
}

0 commit comments

Comments
 (0)