You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jh...@apache.org on 2022/03/25 15:51:26 UTC

[netbeans] branch master updated: Invoke arbitrary action from vscode

This is an automated email from the ASF dual-hosted git repository.

jhorvath pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new dd19ef1  Invoke arbitrary action from vscode
     new a9dfd9e  Merge pull request #3843 from jhorvath/invoke-action
dd19ef1 is described below

commit dd19ef1b6311bf60136349b568264176a9261883
Author: Jan Horvath <ja...@horvath.cz>
AuthorDate: Fri Mar 25 10:38:26 2022 +0100

    Invoke arbitrary action from vscode
---
 .../modules/cloud/oracle/items/DatabaseItem.java   |   6 +
 .../modules/cloud/oracle/items/OCIItem.java        |   4 +
 .../lsp/server/explorer/NodeActionsProvider.java   |  69 ++++++++---
 .../test/unit/src/META-INF/generated-layer.xml     |  17 +++
 .../server/explorer/NodeActionsProviderTest.java   | 137 +++++++++++++++++++++
 .../modules/java/lsp/server/explorer/TestInfo.java |  39 +++---
 6 files changed, 241 insertions(+), 31 deletions(-)

diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java
index 410a3fd..1fb5aa5 100644
--- a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java
@@ -32,6 +32,12 @@ public class DatabaseItem extends OCIItem {
         this.connectionName = connectionName;
     }
 
+    public DatabaseItem() {
+        super();
+        serviceUrl = null;
+        connectionName = null;
+    }
+    
     public String getServiceUrl() {
         return serviceUrl;
     }
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/OCIItem.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/OCIItem.java
index 94e64aa..b1fea18 100644
--- a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/OCIItem.java
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/OCIItem.java
@@ -44,6 +44,10 @@ public class OCIItem {
         changeSupport = new ChangeSupport(this);
     }
 
+    public OCIItem() {
+        this(null, null);
+    }
+    
     /**
      * OCID of the item.
      * 
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProvider.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProvider.java
index dc0d34a..5d59d04 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProvider.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProvider.java
@@ -38,9 +38,12 @@ import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient;
 import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.awt.Actions;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.nodes.Node;
 import org.openide.util.ContextAwareAction;
+import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
 import org.openide.util.lookup.ProxyLookup;
 
 /**
@@ -61,7 +64,7 @@ public class NodeActionsProvider extends CodeActionsProvider {
     private final Set<String>  commands;
     private final Gson gson = new Gson();
 
-    private NodeActionsProvider(Set<String> commands) {
+    NodeActionsProvider(Set<String> commands) {
         this.commands = commands;
     }
 
@@ -108,8 +111,22 @@ public class NodeActionsProvider extends CodeActionsProvider {
                 
             }
         }
+        
+        String categoryAndId = command.substring(NBLS_ACTION_PREFIX.length());
+        String category;
+        String aid;
+        
+        int col = categoryAndId.indexOf(CATEGORY_SEPARATOR);
+        if (col != -1) {
+            aid = categoryAndId.substring(col + 1);
+            category = categoryAndId.substring(0, col);
+        } else {
+            category = null;
+            aid = categoryAndId;
+        }
+        
         if (id == -1) {
-            return CompletableFuture.completedFuture(false);
+            return invokeAction(client, category, aid, arguments);
         }
 
         //gson.fromJson(arguments.get(0), JSONObject.class);
@@ -129,18 +146,6 @@ public class NodeActionsProvider extends CodeActionsProvider {
             return f;
         }
         
-        String categoryAndId = command.substring(NBLS_ACTION_PREFIX.length());
-        String category;
-        String aid;
-        
-        int col = categoryAndId.indexOf(CATEGORY_SEPARATOR);
-        if (col != -1) {
-            aid = categoryAndId.substring(col + 1);
-            category = categoryAndId.substring(0, col);
-        } else {
-            category = null;
-            aid = categoryAndId;
-        }
         
         final Lookup targetLookup = new ProxyLookup(target.getLookup(), provider.getLookup());
         
@@ -161,4 +166,40 @@ public class NodeActionsProvider extends CodeActionsProvider {
         return CompletableFuture.completedFuture(true);
     }
     
+    CompletableFuture<Object> invokeAction(NbCodeLanguageClient client, String category, String aid, List<Object> arguments) {
+        String path = "Actions/" + category + "/" + aid.replace('.', '-') + ".instance"; //NOI18N
+        FileObject config = FileUtil.getConfigFile(path);
+        String contextType = (String) config.getAttribute("type"); //NOI18N
+        try {
+            Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(contextType);
+            Object context = gson.fromJson(gson.toJson(arguments.get(0)), clazz);
+            if (context != null) {
+                Lookup targetLookup = Lookups.singleton(context);
+                AbstractGlobalActionContext.withActionContext(targetLookup, () -> {
+                    Action a = Actions.forID(category, aid);
+                    if (a == null) {
+                        return CompletableFuture.completedFuture(false);
+                    }
+                    if (a instanceof ContextAwareAction) {
+                        a = ((ContextAwareAction)a).createContextAwareInstance(targetLookup);
+                    }
+                    final Action a2 = a;
+
+                    a2.actionPerformed(new ActionEvent(client, 0, aid));
+                    return null;
+                });
+            } else {
+                return CompletableFuture.completedFuture(false);
+            }
+        } catch (ClassNotFoundException ex) {
+            return completeExceptionally(ex);
+        }
+        return CompletableFuture.completedFuture(true);
+    }
+    
+    private CompletableFuture completeExceptionally(Throwable t) {
+        CompletableFuture f = new CompletableFuture();
+        f.completeExceptionally(t);
+        return f;
+    }
 }
diff --git a/java/java.lsp.server/test/unit/src/META-INF/generated-layer.xml b/java/java.lsp.server/test/unit/src/META-INF/generated-layer.xml
new file mode 100644
index 0000000..2f64f85
--- /dev/null
+++ b/java/java.lsp.server/test/unit/src/META-INF/generated-layer.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Tools">
+            <file name="testAction1.instance">
+                <attr stringvalue="Test Action" name="displayName"/>
+                <attr methodvalue="org.openide.awt.Actions.context" name="instanceCreate"/>
+                <attr name="type" stringvalue="org.netbeans.modules.java.lsp.server.explorer.TestInfo"/>
+                <attr name="injectable" stringvalue="org.netbeans.modules.java.lsp.server.explorer.NodeActionsProviderTest$TestAction"/>
+                <attr name="delegate" methodvalue="org.openide.awt.Actions.inject"/>
+                <attr name="selectionType" stringvalue="EXACTLY_ONE"/>
+                <attr boolvalue="false" name="noIconInMenu"/>
+                <attr boolvalue="false" name="asynchronous"/>
+            </file>
+        </folder>
+    </folder>
+</filesystem>
diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProviderTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProviderTest.java
new file mode 100644
index 0000000..53ebe46
--- /dev/null
+++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/NodeActionsProviderTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.explorer;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.SwingUtilities;
+import static junit.framework.TestCase.assertEquals;
+import org.eclipse.lsp4j.LogTraceParams;
+import org.eclipse.lsp4j.RegistrationParams;
+import org.eclipse.lsp4j.SetTraceParams;
+import org.eclipse.lsp4j.ShowDocumentParams;
+import org.eclipse.lsp4j.ShowDocumentResult;
+import org.eclipse.lsp4j.UnregistrationParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+import org.junit.Test;
+import org.netbeans.modules.java.lsp.server.TestCodeLanguageClient;
+import org.netbeans.modules.java.lsp.server.ui.AbstractGlobalActionContext;
+import org.openide.util.test.MockLookup;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+public class NodeActionsProviderTest {
+
+    static CountDownLatch latch;
+
+    /**
+     * Test of processCommand method, of class NodeActionsProvider.
+     */
+    @Test
+    public void testProcessCommand() throws InterruptedException, InvocationTargetException {
+        latch = new CountDownLatch(1);
+        MockLookup.setLayersAndInstances(
+                new AbstractGlobalActionContext());
+        try {
+            NodeActionsProvider p = new NodeActionsProvider(Collections.EMPTY_SET);
+            Map<String, String> m = new HashMap<String, String>();
+            m.put("name", "test");
+            m.put("id", "test1");
+
+            SwingUtilities.invokeAndWait(() -> {
+                p.invokeAction(new TestCodeLanguageClient() {
+                    @Override
+                    public boolean isRequestDispatcherThread() {
+                        return super.isRequestDispatcherThread();
+                    }
+
+                    @Override
+                    public CompletableFuture<Void> registerCapability(RegistrationParams params) {
+                        return super.registerCapability(params);
+                    }
+
+                    @Override
+                    public CompletableFuture<Void> unregisterCapability(UnregistrationParams params) {
+                        return super.unregisterCapability(params);
+                    }
+
+                    @Override
+                    public CompletableFuture<ShowDocumentResult> showDocument(ShowDocumentParams params) {
+                        return super.showDocument(params);
+                    }
+
+                    @Override
+                    public CompletableFuture<List<WorkspaceFolder>> workspaceFolders() {
+                        return super.workspaceFolders();
+                    }
+
+                    @Override
+                    public void logTrace(LogTraceParams params) {
+                        super.logTrace(params);
+                    }
+
+                    @Override
+                    public void setTrace(SetTraceParams params) {
+                        super.setTrace(params);
+                    }
+
+                    @Override
+                    public CompletableFuture<Void> refreshSemanticTokens() {
+                        return super.refreshSemanticTokens();
+                    }
+
+                    @Override
+                    public CompletableFuture<Void> refreshCodeLenses() {
+                        return super.refreshCodeLenses();
+                    }
+                }, "Tools", "testAction1", Collections.singletonList(m));
+            });
+        } finally {
+            MockLookup.setInstances();
+        }
+        latch.await(2, TimeUnit.SECONDS);
+        assertEquals(0, latch.getCount());
+    }
+
+    public static class TestAction implements ActionListener {
+
+        private final TestInfo context;
+
+        public TestAction(TestInfo context) {
+            this.context = context;
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            assertEquals("test1", context.id);
+            latch.countDown();
+        }
+    }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/TestInfo.java
similarity index 59%
copy from enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java
copy to java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/TestInfo.java
index 410a3fd..92bd6ec 100644
--- a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/items/DatabaseItem.java
+++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/explorer/TestInfo.java
@@ -16,28 +16,33 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.netbeans.modules.cloud.oracle.items;
+package org.netbeans.modules.java.lsp.server.explorer;
 
 /**
  *
- * @author Jan Horvath
  */
-public class DatabaseItem extends OCIItem {
-    private final String serviceUrl;
-    private final String connectionName;
+public class TestInfo {
+    String name;
+        String id;
 
-    public DatabaseItem(String id, String name, String serviceUrl, String connectionName) {
-        super(id, name);
-        this.serviceUrl = serviceUrl;
-        this.connectionName = connectionName;
-    }
+        public TestInfo() {
+            name = "1";
+            id = "2";
+        }
+        
+        public String getName() {
+            return name;
+        }
 
-    public String getServiceUrl() {
-        return serviceUrl;
-    }
+        public void setName(String name) {
+            this.name = name;
+        }
 
-    public String getConnectionName() {
-        return connectionName;
-    }
-    
+        public String getId() {
+            return id;
+        }
+
+        public void setId(String id) {
+            this.id = id;
+        }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists