You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ge...@apache.org on 2019/04/30 11:49:24 UTC
[netbeans] branch master updated: Integration of JEP-330 (#1171)
This is an automated email from the ASF dual-hosted git repository.
geertjan 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 8836aad Integration of JEP-330 (#1171)
8836aad is described below
commit 8836aad99151ac1e57ff440c15de90c67251fce7
Author: Sarvesh Kesharwani <32...@users.noreply.github.com>
AuthorDate: Tue Apr 30 17:19:17 2019 +0530
Integration of JEP-330 (#1171)
* adding support to run single java files outside projects (JEP-330)
* adding SingleJavaSourceRunActionProvider.java to global lookup
* adding content to SingleJavaSourceRunActionProvider.java
* removing unused methods and variables
* restricting JEP-330 to jdk-11 and above
* fixing check for jdk-11 and execution in linux
* removing unnecessary dependencies in projectui
* fixing the public packages in java.source
* removing extecxecution dependency in java.source; using dataObjects' attributes to add arguments and vm options
* adding test case for JEP-330 run
* using tests to check functionality of SingleJavaSourceRunActionProvider
* removing unused code
* removing unused imports
* testing java.api.common with jdk11
* adding check for jdk11 in test file
* adding quiet option to travis build
* changing RunProcess to package protected; changing TestJavaFile to JavaFileTest
* restoring .travis.yml
* adding test for isActionEnabled; fixing bug in isActionEnabled
---
.../modules/java/api/common/RunProcess.java | 86 +++++++++++++++++
.../common/SingleJavaSourceRunActionProvider.java | 107 +++++++++++++++++++++
.../test/unit/data/files/TestSingleJavaFile.java | 7 ++
.../modules/java/api/common/JavaFileTest.java | 73 ++++++++++++++
.../org/netbeans/modules/java/Bundle.properties | 1 +
.../src/org/netbeans/modules/java/JavaNode.java | 63 ++++++++++++
6 files changed, 337 insertions(+)
diff --git a/java/java.api.common/src/org/netbeans/modules/java/api/common/RunProcess.java b/java/java.api.common/src/org/netbeans/modules/java/api/common/RunProcess.java
new file mode 100644
index 0000000..cc7d44d
--- /dev/null
+++ b/java/java.api.common/src/org/netbeans/modules/java/api/common/RunProcess.java
@@ -0,0 +1,86 @@
+/*
+ * 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.api.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Sarvesh Kesharwani
+ */
+class RunProcess implements Callable<Process> {
+
+ private static final Logger LOG = Logger.getLogger(RunProcess.class.getName());
+
+ private final String dirPath;
+ private final List<String> commandsList;
+ private InputStream is;
+ private Process p;
+
+ public RunProcess(String command, String dirPath) {
+ this.dirPath = dirPath;
+ commandsList = new ArrayList<>();
+ commandsList.add(command);
+ setupProcess();
+ }
+
+ public RunProcess(String command) {
+ commandsList = new ArrayList<>();
+ commandsList.add(command);
+ this.dirPath = System.getProperty("user.home");
+ setupProcess();
+ }
+
+ public RunProcess(List<String> commandsList) {
+ this.commandsList = commandsList;
+ this.dirPath = System.getProperty("user.home");
+ setupProcess();
+ }
+
+ public void setupProcess() {
+ try {
+ ProcessBuilder runFileProcessBuilder = new ProcessBuilder(commandsList);
+ runFileProcessBuilder.directory(new File(dirPath));
+ runFileProcessBuilder.redirectErrorStream(true);
+ p = runFileProcessBuilder.start();
+ is = p.getInputStream();
+ } catch (IOException ex) {
+ LOG.log(
+ Level.WARNING,
+ "Could not get InputStream of Run Process"); //NOI18N
+ }
+ }
+
+ public InputStream getInputStream() {
+ return is;
+ }
+
+ @Override
+ public Process call() throws Exception {
+ return p;
+ }
+
+}
diff --git a/java/java.api.common/src/org/netbeans/modules/java/api/common/SingleJavaSourceRunActionProvider.java b/java/java.api.common/src/org/netbeans/modules/java/api/common/SingleJavaSourceRunActionProvider.java
new file mode 100644
index 0000000..662d454
--- /dev/null
+++ b/java/java.api.common/src/org/netbeans/modules/java/api/common/SingleJavaSourceRunActionProvider.java
@@ -0,0 +1,107 @@
+/*
+ * 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.api.common;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import org.netbeans.api.extexecution.ExecutionDescriptor;
+import org.netbeans.api.extexecution.ExecutionService;
+import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.api.project.Project;
+import org.netbeans.spi.project.ActionProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataObject;
+import org.openide.util.Lookup;
+import org.openide.util.Utilities;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ * This class provides support to run a single Java file without a parent
+ * project (JEP-330).
+ *
+ * @author Sarvesh Kesharwani
+ */
+@ServiceProvider(service = ActionProvider.class)
+public class SingleJavaSourceRunActionProvider implements ActionProvider {
+
+ private static final String FILE_ARGUMENTS = "single_file_run_arguments"; //NOI18N
+ private static final String FILE_VM_OPTIONS = "single_file_vm_options"; //NOI18N
+
+ @Override
+ public String[] getSupportedActions() {
+ return new String[]{ActionProvider.COMMAND_RUN_SINGLE};
+ }
+
+ @Override
+ public void invokeAction(String command, Lookup context) throws IllegalArgumentException {
+ FileObject fileObject = getJavaFileWithoutProjectFromLookup(context);
+ if (fileObject == null)
+ return;
+ ExecutionDescriptor descriptor = new ExecutionDescriptor().controllable(true).frontWindow(true).
+ preExecution(null).postExecution(null);
+ RunProcess process = invokeActionHelper(command, fileObject);
+ ExecutionService exeService = ExecutionService.newService(
+ process,
+ descriptor, "Running Single Java File");
+ Future<Integer> exitCode = exeService.run();
+ }
+
+ @Override
+ public boolean isActionEnabled(String command, Lookup context) throws IllegalArgumentException {
+ // JEP-330 is supported only on JDK-11 and above.
+ String javaVersion = System.getProperty("java.specification.version");
+ if (javaVersion.startsWith("1.")) {
+ javaVersion = javaVersion.substring(2);
+ }
+ int version = Integer.parseInt(javaVersion);
+ FileObject fileObject = getJavaFileWithoutProjectFromLookup(context);
+ return version >= 11 && fileObject != null;
+ }
+
+ public RunProcess invokeActionHelper (String command, FileObject fileObject) {
+ String filePath = fileObject.getPath();
+ Object argumentsObject = fileObject.getAttribute(FILE_ARGUMENTS);
+ String arguments = argumentsObject != null ? (String) argumentsObject : "";
+ Object vmOptionsObject = fileObject.getAttribute(FILE_VM_OPTIONS);
+ String vmOptions = vmOptionsObject != null ? (String) vmOptionsObject : "";
+ List<String> commandsList = new ArrayList<>();
+ if (Utilities.isUnix()) {
+ commandsList.add("bash");
+ commandsList.add("-c");
+ }
+ File javaPathFile = new File(new File(new File(System.getProperty("java.home")), "bin"), "java");
+ String javaPath = "\"" + javaPathFile.getAbsolutePath() + "\"";
+ commandsList.add(javaPath + " " + vmOptions + " " + filePath + " " + arguments);
+ return new RunProcess(commandsList);
+ }
+
+ private FileObject getJavaFileWithoutProjectFromLookup(Lookup lookup) {
+ for (DataObject dObj : lookup.lookupAll(DataObject.class)) {
+ FileObject fObj = dObj.getPrimaryFile();
+ Project p = FileOwnerQuery.getOwner(fObj);
+ if (p == null && fObj.getExt().equalsIgnoreCase("java")) {
+ return fObj;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/java/java.api.common/test/unit/data/files/TestSingleJavaFile.java b/java/java.api.common/test/unit/data/files/TestSingleJavaFile.java
new file mode 100644
index 0000000..b6390a6
--- /dev/null
+++ b/java/java.api.common/test/unit/data/files/TestSingleJavaFile.java
@@ -0,0 +1,7 @@
+public class TestSingleJavaFile {
+
+ public static void main (String args[]) {
+ System.out.print("hello world");
+ }
+
+}
diff --git a/java/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/JavaFileTest.java b/java/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/JavaFileTest.java
new file mode 100644
index 0000000..13c76d1
--- /dev/null
+++ b/java/java.api.common/test/unit/src/org/netbeans/modules/java/api/common/JavaFileTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.api.common;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.logging.Logger;
+import static junit.framework.TestCase.assertEquals;
+import org.netbeans.junit.NbTestCase;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Sarvesh Kesharwani
+ */
+public class JavaFileTest extends NbTestCase {
+
+ private static final Logger LOG = Logger.getLogger(JavaFileTest.class.getName());
+
+ public JavaFileTest(String name) {
+ super(name);
+ }
+
+ public void testSingleJavaSourceRun() throws IOException {
+ File f1 = new File(new File(new File(getDataDir().getAbsolutePath()), "files"), "TestSingleJavaFile.java");
+ FileObject javaFO = FileUtil.toFileObject(f1);
+ SingleJavaSourceRunActionProvider runActionProvider = new SingleJavaSourceRunActionProvider();
+ if (!isJDK11OrNewer()) {
+ assertFalse("The action is only enabled on JDK11 and newer", runActionProvider.isActionEnabled("run.single", Lookup.EMPTY));
+ return;
+ }
+ RunProcess process = runActionProvider.invokeActionHelper("run.single", javaFO);
+ BufferedReader reader
+ = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ StringBuilder builder = new StringBuilder();
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ builder.append(line);
+ }
+ String result = builder.toString();
+ assertEquals("hello world", result);
+ }
+
+ private boolean isJDK11OrNewer() {
+ String javaVersion = System.getProperty("java.specification.version");
+ if (javaVersion.startsWith("1.")) {
+ javaVersion = javaVersion.substring(2);
+ }
+ int version = Integer.parseInt(javaVersion);
+ return version >= 11;
+ }
+
+}
diff --git a/java/java.source/src/org/netbeans/modules/java/Bundle.properties b/java/java.source/src/org/netbeans/modules/java/Bundle.properties
index f640478..c87723c 100644
--- a/java/java.source/src/org/netbeans/modules/java/Bundle.properties
+++ b/java/java.source/src/org/netbeans/modules/java/Bundle.properties
@@ -36,6 +36,7 @@ HINT_JavaNode_execute_classpath=What classes are expected to be available to thi
PROP_JavaNode_boot_classpath=Boot Classpath
HINT_JavaNode_boot_classpath=What Java platform (JRE) classes this class is expected to be compiled and run against.
LBL_JavaNode_classpath_unknown=<unknown>
+LBL_JavaNode_without_project_run=Run Single File
#JavaNode badges:
TP_NeedsCompileBadge=Needs to be compiled.
diff --git a/java/java.source/src/org/netbeans/modules/java/JavaNode.java b/java/java.source/src/org/netbeans/modules/java/JavaNode.java
index 4cb93f9..3abe857 100644
--- a/java/java.source/src/org/netbeans/modules/java/JavaNode.java
+++ b/java/java.source/src/org/netbeans/modules/java/JavaNode.java
@@ -52,6 +52,8 @@ import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.Task;
+import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.api.project.Project;
import org.netbeans.api.queries.FileBuiltQuery;
import org.netbeans.api.queries.FileBuiltQuery.Status;
import org.netbeans.modules.classfile.Access;
@@ -75,6 +77,7 @@ import static org.openide.util.ImageUtilities.loadImage;
import org.openide.util.Lookup;
import static org.openide.util.NbBundle.getMessage;
+import org.openide.util.NbPreferences;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;
@@ -97,6 +100,8 @@ public final class JavaNode extends DataNode implements ChangeListener {
private static final String ANNOTATION_ICON_BASE = "org/netbeans/modules/java/resources/annotation_file.png"; //NOI18N
private static final String EXECUTABLE_BADGE_URL = "org/netbeans/modules/java/resources/executable-badge.png"; //NOI18N
private static final String NEEDS_COMPILE_BADGE_URL = "org/netbeans/modules/java/resources/needs-compile.png"; //NOI18N
+ private static final String FILE_ARGUMENTS = "single_file_run_arguments"; //NOI18N
+ private static final String FILE_VM_OPTIONS = "single_file_vm_options"; //NOI18N
private static final Map<String,Image> IMAGE_CACHE = new ConcurrentHashMap<>();
private static final boolean ALWAYS_PREFFER_COMPUTED_ICON = Boolean.getBoolean("JavaNode.prefferComputedIcon"); //NOI18N
@@ -213,6 +218,64 @@ public final class JavaNode extends DataNode implements ChangeListener {
});
sheet.put(ps);
+ Project parentProject = FileOwnerQuery.getOwner(super.getDataObject().getPrimaryFile());
+ DataObject dObj = super.getDataObject();
+ // If any of the parent folders is a project, user won't have the option to specify these attributes to the java files.
+ if (parentProject == null) {
+ Node.Property arguments = new org.openide.nodes.PropertySupport.ReadWrite<String> (
+ "runFileArguments", // NOI18N
+ String.class,
+ "Arguments",
+ "Arguments passed to the main method while running the file."
+ ) {
+ public String getValue () {
+ Object arguments = dObj.getPrimaryFile().getAttribute(FILE_ARGUMENTS);
+ return arguments != null ? (String) arguments : "";
+ }
+
+ public void setValue (String o) {
+ try {
+ dObj.getPrimaryFile().setAttribute(FILE_ARGUMENTS, o);
+ } catch (IOException ex) {
+ LOG.log(
+ Level.WARNING,
+ "Java File does not exist : {0}", //NOI18N
+ dObj.getPrimaryFile().getName());
+ }
+ }
+ };
+ Node.Property vmOptions = new org.openide.nodes.PropertySupport.ReadWrite<String> (
+ "runFileVMOptions", // NOI18N
+ String.class,
+ "VM Options",
+ "VM Options to be considered while running the file."
+ ) {
+ public String getValue () {
+ Object vmOptions = dObj.getPrimaryFile().getAttribute(FILE_VM_OPTIONS);
+ return vmOptions != null ? (String) vmOptions : "";
+ }
+
+ public void setValue (String o) {
+ try {
+ dObj.getPrimaryFile().setAttribute(FILE_VM_OPTIONS, o);
+ } catch (IOException ex) {
+ LOG.log(
+ Level.WARNING,
+ "Java File does not exist : {0}", //NOI18N
+ dObj.getPrimaryFile().getName());
+ }
+ }
+ };
+ Sheet.Set ss = new Sheet.Set();
+ ss.setName("runFileArguments"); // NOI18N
+ ss.setDisplayName(getMessage(JavaNode.class, "LBL_JavaNode_without_project_run"));
+ ss.setShortDescription("Run the file's source code.");
+ ss.put (arguments);
+ ss.put (vmOptions);
+ sheet.put(ss);
+ }
+
+
@SuppressWarnings("LocalVariableHidesMemberVariable")
PropertySet[] propertySets = sheet.toArray();
---------------------------------------------------------------------
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