You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sd...@apache.org on 2022/12/07 08:27:42 UTC
[netbeans] branch master updated: Support for proxy detection / autoconfiguration.
This is an automated email from the ASF dual-hosted git repository.
sdedic 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 a65047e41e Support for proxy detection / autoconfiguration.
new bd3877440a Merge pull request #5006 from sdedic/gradle/proxydetect
a65047e41e is described below
commit a65047e41ea4ea5e7ed884c1af5de4675fce58fa
Author: Svata Dedic <sv...@oracle.com>
AuthorDate: Thu Nov 24 14:07:19 2022 +0100
Support for proxy detection / autoconfiguration.
---
extide/gradle/apichanges.xml | 2 +-
extide/gradle/arch.xml | 7 +
extide/gradle/manifest.mf | 2 +-
.../modules/gradle/api/execute/Bundle.properties | 5 +
.../gradle/execute/GradleDaemonExecutor.java | 14 +
.../gradle/execute/GradleNetworkProxySupport.java | 596 +++++++++++++++++++++
.../gradle/loaders/LegacyProjectLoader.java | 29 +-
.../modules/gradle/options/Bundle.properties | 1 +
.../gradle/options/GradleExperimentalSettings.java | 14 +
.../gradle/options/NetworkProxySettings.java | 79 +++
.../modules/gradle/options/SettingsPanel.form | 42 +-
.../modules/gradle/options/SettingsPanel.java | 43 +-
12 files changed, 814 insertions(+), 20 deletions(-)
diff --git a/extide/gradle/apichanges.xml b/extide/gradle/apichanges.xml
index 47013fa0c6..2c6e7e1fb9 100644
--- a/extide/gradle/apichanges.xml
+++ b/extide/gradle/apichanges.xml
@@ -91,7 +91,7 @@ is the proper place.
<author login="sdedic"/>
<compatibility semantic="compatible" addition="yes"/>
<description>
- Tasks declared by other projects are marked as 'external'. Tasjs can report their declaring project's path.
+ Tasks declared by other projects are marked as 'external'. Tasks can report their declaring project's path.
</description>
<class package="org.netbeans.modules.gradle.api" name="GradleTask"/>
</change>
diff --git a/extide/gradle/arch.xml b/extide/gradle/arch.xml
index 78d3e8f8d3..c303d76d91 100644
--- a/extide/gradle/arch.xml
+++ b/extide/gradle/arch.xml
@@ -130,6 +130,13 @@
<answer id="exec-property">
+ <api category="devel" group="branding" name="org.netbeans.modules.gradle.api.execute.NetworkProxySettings.allowOverride" type="export">
+ Brand the <code>org.netbeans.modules.gradle.api.execute.NetworkProxySettings.allowOverride</code> key in a
+ <code>org.netbeans.modules.gradle.api.execute.Bundle</code> file
+ with one of the values <code>true</code> or <code>false</code> to specify whether to offer override of proxies
+ when running Gradle daemon. With <code>false</code>, the user is only given an option to upgrade gradle's configuration files.
+ Since
+ </api>
<api category="devel" group="branding" name="org.netbeans.modules.gradle.spi.DEFAULT_REUSE_OUTPUT" type="export">
Brand the <code>DEFAULT_REUSE_OUTPUT</code> key in a
<code>org.netbeans.modules.gradle.spi.Bundle</code> file
diff --git a/extide/gradle/manifest.mf b/extide/gradle/manifest.mf
index 197c9fd82d..03eafb6fbd 100644
--- a/extide/gradle/manifest.mf
+++ b/extide/gradle/manifest.mf
@@ -3,4 +3,4 @@ AutoUpdate-Show-In-Client: false
OpenIDE-Module: org.netbeans.modules.gradle/2
OpenIDE-Module-Layer: org/netbeans/modules/gradle/layer.xml
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/gradle/Bundle.properties
-OpenIDE-Module-Specification-Version: 2.30
+OpenIDE-Module-Specification-Version: 2.31
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/api/execute/Bundle.properties b/extide/gradle/src/org/netbeans/modules/gradle/api/execute/Bundle.properties
index ca3bcc51eb..51a98c0356 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/api/execute/Bundle.properties
+++ b/extide/gradle/src/org/netbeans/modules/gradle/api/execute/Bundle.properties
@@ -82,3 +82,8 @@ WRITE_VERIFICATION_METADATA_DSC=<p>Generates checksums for dependencies used in
org.netbeans.modules.gradle.api.execute.TrustProjectOption.TrustOnce=-1
org.netbeans.modules.gradle.api.execute.TrustProjectOption.PermanentTrust=2
org.netbeans.modules.gradle.api.execute.TrustProjectOption.RunAlways=0
+
+# A distribution can choose if 'override' proxy option is available: NetBeans will
+# override proxy in the gradle daemon's JVM using explicit system properties.
+org.netbeans.modules.gradle.api.execute.NetworkProxySettings.allowOverride=true
+
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java
index cd10f28c59..e9a4ae8f7a 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java
@@ -56,6 +56,7 @@ import org.netbeans.api.project.ProjectInformation;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.modules.gradle.api.execute.GradleDistributionManager.GradleDistribution;
import org.netbeans.modules.gradle.api.execute.GradleExecConfiguration;
+import org.netbeans.modules.gradle.execute.GradleNetworkProxySupport.ProxyResult;
import org.netbeans.modules.gradle.spi.GradleFiles;
import org.netbeans.modules.gradle.spi.execute.GradleDistributionProvider;
import org.netbeans.modules.gradle.spi.execute.GradleJavaPlatformProvider;
@@ -239,6 +240,19 @@ public final class GradleDaemonExecutor extends AbstractGradleExecutor {
}
}
GradleExecAccessor.instance().configureGradleHome(buildLauncher);
+ GradleNetworkProxySupport proxySupport = config.getProject().getLookup().lookup(GradleNetworkProxySupport.class);
+ if (proxySupport != null) {
+ try {
+ ProxyResult result = proxySupport.checkProxySettings().get();
+ if (result.getStatus() == GradleNetworkProxySupport.Status.ABORT) {
+ showAbort();
+ return;
+ }
+ buildLauncher = result.configure(buildLauncher);
+ } catch (InterruptedException | ExecutionException ex) {
+ throw new BuildCancelledException("Interrupted", ex);
+ }
+ }
buildLauncher.run();
StatusDisplayer.getDefault().setStatusText(Bundle.BUILD_SUCCESS(getProjectName()));
gradleTask.finish(0);
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleNetworkProxySupport.java b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleNetworkProxySupport.java
new file mode 100644
index 0000000000..10a4181852
--- /dev/null
+++ b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleNetworkProxySupport.java
@@ -0,0 +1,596 @@
+/*
+ * 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.gradle.execute;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.gradle.tooling.BuildActionExecuter;
+import org.gradle.tooling.ConfigurableLauncher;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.gradle.api.NbGradleProject;
+import org.netbeans.modules.gradle.options.GradleExperimentalSettings;
+import org.netbeans.modules.gradle.options.NetworkProxySettings;
+import org.netbeans.modules.gradle.spi.GradleFiles;
+import org.netbeans.spi.project.ProjectServiceProvider;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.NotificationDisplayer;
+import org.openide.awt.StatusDisplayer;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.EditableProperties;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
+
+/**
+ * Support for proxy autodetection or autoconfiguration. The class works with {@link GradleExperimentalSettings} and {@link NetworkProxySettings} to determine
+ * the behaviour:
+ * <ul>
+ * <li>{@link NetworkProxySettings#IGNORE} - skip autodetection at all
+ * <li>{@link NetworkProxySettings#NOTICE} - just note mismatch, do not update configuration and continue building
+ * <li>{@link NetworkProxySettings#OVERRIDE} - override gradle.properties by explicit system properties
+ * <li>{@link NetworkProxySettings#UPDATE} - automatically update settings
+ * {@link NetworkProxySettings#ASK} - ask the user
+ * </ul>
+ * The user choice is remembered so for the same project and detected proxy, the question is not asked again. Also notice is displayed just once for project+detected proxy,
+ * so the log is not full of reminders.
+ *
+ * @author sdedic
+ */
+@ProjectServiceProvider(service = GradleNetworkProxySupport.class, projectType = NbGradleProject.GRADLE_PROJECT_TYPE)
+public class GradleNetworkProxySupport {
+ private static final Logger LOG = Logger.getLogger(GradleNetworkProxySupport.class.getName());
+ /**
+ * Sample probe URI - google's public DNS server
+ */
+ private static final String PROBE_URI_STRING = "http://search.maven.org"; // NOI18N
+
+ private static final String FILENAME_SUFFIX_OLD = ".old"; // NOI18N
+ private static final String SYSTEMPROP_HTTPS_PROXYPORT = "systemProp.https.proxyPort"; // NOI18N
+ private static final String SYSTEMPROP_HTTP_PROXYPORT = "systemProp.http.proxyPort"; // NOI18N
+ private static final String SYSTEMPROP_HTTPS_PROXYHOST = "systemProp.https.proxyHost"; // NOI18N
+ private static final String SYSTEMPROP_HTTP_PROXYHOST = "systemProp.http.proxyHost"; // NOI18N
+
+ private static final String JVM_HTTPS_PROXYPORT = "https.proxyPort"; // NOI18N
+ private static final String JVM_HTTP_PROXYPORT = "http.proxyPort"; // NOI18N
+ private static final String JVM_HTTPS_PROXYHOST = "https.proxyHost"; // NOI18N
+ private static final String JVM_HTTP_PROXYHOST = "http.proxyHost"; // NOI18N
+
+ private static final int PORT_DEFAULT_HTTPS = 1080;
+ private static final int PORT_DEFAULT_HTTP = 80;
+
+ private final Project project;
+
+ /**
+ * Past decisions made by the user during this session. The Map is used so the user si not bothered that often with questions.
+ * If the user chooses 'override' or 'continue' (no action), the Map receives the public proxy spec and the result. If the same
+ * effective proxy is detected, the user is not asked again.
+ */
+ // @GuardedBy(this)
+ private Map<String, ProxyResult> acknowledgedResults = new HashMap<>();
+
+ public GradleNetworkProxySupport(Project project) {
+ this.project = project;
+ }
+
+ public CompletableFuture<ProxyResult> checkProxySettings() {
+ return new Processor().checkProxy();
+ }
+
+ public enum Status {
+ UNKNOWN,
+ CONTINUE,
+ RECONFIGURED,
+ OVERRIDE,
+ ABORT
+ }
+
+ public static final class ProxyResult {
+ private final Status status;
+ private final Proxy proxy;
+ private final String toolProxy;
+ private final String proxyHost;
+ private final String proxySpec;
+ private final int proxyPort;
+
+ public ProxyResult(Status status, Proxy proxy) {
+ this.status = status;
+ this.proxy = proxy;
+ this.toolProxy = null;
+ this.proxySpec = null;
+ this.proxyHost = null;
+ this.proxyPort = -1;
+ }
+
+ public ProxyResult(Status status, Proxy proxy, String toolProxy, String proxySpec, String proxyHost, int proxyPort) {
+ this.status = status;
+ this.proxy = proxy;
+ this.toolProxy = toolProxy;
+ this.proxySpec = proxySpec;
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public Proxy getProxy() {
+ return proxy;
+ }
+
+ public String getToolProxy() {
+ return toolProxy;
+ }
+
+ public String getProxySpec() {
+ return proxySpec;
+ }
+
+ public <T > BuildActionExecuter<T> configure(BuildActionExecuter<T> executor) {
+ configure((ConfigurableLauncher)executor);
+ return executor;
+ }
+
+ public <T extends ConfigurableLauncher> T configure(T executor) {
+ if (status != Status.OVERRIDE) {
+ return executor;
+ }
+ addSystemProperty(executor, JVM_HTTP_PROXYHOST, proxyHost);
+ addSystemProperty(executor, JVM_HTTP_PROXYPORT, Integer.toString(proxyPort));
+ addSystemProperty(executor, JVM_HTTPS_PROXYHOST, proxyHost);
+ addSystemProperty(executor, JVM_HTTPS_PROXYPORT, Integer.toString(proxyPort));
+
+ return executor;
+ }
+
+ private void addSystemProperty(ConfigurableLauncher<?> executer, String propName, String value) {
+ executer.addJvmArguments("-D" + propName + "=" + (value == null ? "" : value));
+ }
+ }
+
+ @NbBundle.Messages({
+ "TITLE_GradleProxyMismatch=Possible Network Proxy Issue",
+ "# {0} - gradle proxy",
+ "MSG_ProxyMisconfiguredDirect=Gradle is configured for a proxy {0}, but the system does not require a proxy for network connections. Proxy settings should be removed from user gradle.properties.",
+ "# {0} - system proxy",
+ "MSG_ProxyMisconfiguredMissing=Gradle is not configured to use a network proxy, but the proxy {0} seems to be required for network communication. User gradle.properties should be updated to specify a proxy.",
+ "# {0} - system proxy",
+ "# {1} - gradle proxy",
+ "MSG_ProxyMisconfiguredOther=Gradle is configured to use a network proxy {1}, but the proxy {0} seems to be required for network communication. Proxy settings should be updated in user gradle.properties.",
+ "MSG_AppendAskUpdate=\nUpdate Gradle configuration ? Choose \"Override\" to apply detected proxy only to IDE operations.",
+ "MSG_AppendAskUpdate2=\nUpdate Gradle configuration ?",
+ "ACTION_Override=Override",
+ "ACTION_Continue=Keep settings",
+ "# {0} - date/time of the update",
+ "COMMENT_CreatedByNetBeans=# This proxy configuration has been updated by Apache NetBeans on {0}",
+ "TITLE_ConfigUpdateFailed=Configuration update failed",
+ "# {0} - error message",
+ "ERROR_ConfigUpdateFailed=Failed to modify Gradle user properties: {0}",
+ "# {0} - proxy specification",
+ "MSG_ProxySetTo=Gradle Network proxy set to: {0}",
+ "MSG_ProxyCleared=Gradle Network proxy removed",
+
+ "# Branding API: change to false to disable suggestion to override proxies in Gradle invocation",
+ "CTRL_SuggestProxyOverride=true"
+ })
+ /**
+ * Encapsulates a single check to avoid an enormous method or a ton of parameters passed through
+ * a method chain. Should be constructed for each new check separately.
+ */
+ private class Processor {
+ Proxy publicProxy;
+ String publicProxyHost;
+ int publicProxyPort;
+ int publicProxyNonDefaultPort;
+
+ String proxyAuthority;
+ String proxyHost;
+ String publicProxySpec;
+
+ int proxyPort;
+ GradleFiles gradleFiles;
+
+ public CompletableFuture<ProxyResult> checkProxy() {
+ boolean supportOverride = NetworkProxySettings.allowProxyOverride();
+ NetworkProxySettings action = GradleExperimentalSettings.getDefault().getNetworkProxy();
+ if (action == NetworkProxySettings.IGNORE) {
+ return CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+ }
+
+ obtainPublicProxy();
+ loadProjectProxy();
+
+ boolean direct = publicProxy == null || publicProxy.type() == Proxy.Type.DIRECT;
+
+ if (direct && proxyAuthority == null || gradleFiles == null) {
+ LOG.log(Level.FINE, "Project does not specify a proxy and none is needed");
+ return CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+ }
+
+ if (publicProxy != null) {
+ if (publicProxyHost == null) {
+ // unable to decipher proxy address
+ LOG.log(Level.WARNING, "Unable to decipher proxy: {0}", publicProxy);
+ return CompletableFuture.completedFuture(new ProxyResult(Status.UNKNOWN, null));
+ }
+ if (publicProxyHost.equals(proxyHost) && proxyPort == publicProxyPort) {
+ LOG.log(Level.FINE, "Project specifies detected proxy: {0}", publicProxySpec);
+ return CompletableFuture.completedFuture(new ProxyResult(Status.CONTINUE, publicProxy));
+ }
+ }
+
+ // at this point, it's obvious that
+
+ String userMessage;
+
+ if (direct) {
+ userMessage = Bundle.MSG_ProxyMisconfiguredDirect(proxyAuthority);
+ } else if (proxyAuthority == null) {
+ userMessage = Bundle.MSG_ProxyMisconfiguredMissing(publicProxySpec);
+ } else {
+ userMessage = Bundle.MSG_ProxyMisconfiguredOther(publicProxySpec, proxyAuthority);
+ }
+
+ ProxyResult result;
+ synchronized (this) {
+ result = acknowledgedResults.get(publicProxySpec);
+ }
+ if (result != null) {
+ LOG.log(Level.FINE, "Reusing previous decision: {0} with proxy {1}", new Object[] { result.getStatus(), result.proxySpec });
+ switch (result.getStatus()) {
+ case CONTINUE:
+ // includes noth NOTICE and IGNORE settings !
+ action = NetworkProxySettings.IGNORE;
+ break;
+ case OVERRIDE:
+ action = NetworkProxySettings.OVERRIDE;
+ break;
+ case RECONFIGURED:
+ action = NetworkProxySettings.UPDATE;
+ break;
+ }
+ }
+ // TODO: because of some strange gradle tooling API behaviour, it is not possible to
+ // override ~/.gradle/gradle.properties system properties with values passed on the commandline or -D ...
+ // ... but ./gradlew works for some strange reason.
+ // See https://github.com/gradle/gradle/issues/22856
+ if (proxyHost != null) {
+ supportOverride = false;
+ if (action == NetworkProxySettings.OVERRIDE) {
+ action = NetworkProxySettings.NOTICE;
+ }
+ }
+ switch (action) {
+ case IGNORE:
+ return CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+
+ case NOTICE:
+ NotificationDisplayer.getDefault().notify(
+ Bundle.TITLE_GradleProxyMismatch(),
+ NbGradleProject.getIcon(),
+ userMessage, null, NotificationDisplayer.Priority.NORMAL, NotificationDisplayer.Category.WARNING);
+ return CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+
+ case OVERRIDE:
+ return CompletableFuture.completedFuture(createResult(Status.OVERRIDE));
+
+ case UPDATE:
+ return CompletableFuture.completedFuture(updateGradleConfiguration(false));
+
+ case ASK:
+ if (result != null) {
+ return CompletableFuture.completedFuture(result);
+ }
+ String promptMsg;
+
+ if (supportOverride) {
+ promptMsg = userMessage + Bundle.MSG_AppendAskUpdate();
+ } else {
+ promptMsg = userMessage + Bundle.MSG_AppendAskUpdate2();
+ }
+ NotifyDescriptor desc = new NotifyDescriptor.Confirmation(
+ promptMsg, Bundle.TITLE_GradleProxyMismatch(),
+ NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+ if (supportOverride) {
+ desc.setAdditionalOptions(new Object[] { Bundle.ACTION_Continue(), Bundle.ACTION_Override() });
+ } else {
+ desc.setAdditionalOptions(new Object[] { Bundle.ACTION_Continue() });
+ }
+ desc.setValue(NotifyDescriptor.OK_OPTION);
+
+ return DialogDisplayer.getDefault().notifyFuture(desc).thenApply(this::processUserConfirmation).exceptionally(t -> {
+ if ((t instanceof CompletionException) && (t.getCause() instanceof CancellationException)) {
+ return createResult(Status.ABORT);
+ } else {
+ return createResult(Status.UNKNOWN);
+ }
+ });
+ }
+
+ return null;
+ }
+
+ ProxyResult createResult(Status s) {
+ boolean keep = false;
+ switch (s) {
+ case OVERRIDE:
+ keep = true;
+ LOG.log(Level.FINE, "Will override proxy to {0}", publicProxy);
+ break;
+ case ABORT:
+ LOG.log(Level.FINE, "Will abort operation");
+ break;
+ case CONTINUE:
+ keep = true;
+ LOG.log(Level.FINE, "No action will be taken");
+ break;
+ case RECONFIGURED:
+ LOG.log(Level.FINE, "User properties were reconfigured to {0}", publicProxy);
+ break;
+ }
+ ProxyResult r = new ProxyResult(s, publicProxy, proxyAuthority, publicProxySpec, publicProxyHost, publicProxyPort);
+ if (keep) {
+ synchronized (this) {
+ acknowledgedResults.put(publicProxySpec, r);
+ }
+ }
+ return r;
+ }
+
+ ProxyResult updateGradleConfiguration(boolean interactive) {
+ EditableProperties eprops = new EditableProperties(true);
+
+ File userProps = gradleFiles.getFile(GradleFiles.Kind.USER_PROPERTIES);
+
+ // TODO: would be better if, when removing the proxy, the support would only comment out the keys. But EditableProperties is not suitable for that
+ // now.
+ if (userProps.exists()) {
+ try (FileInputStream is = new FileInputStream(userProps)) {
+ eprops.load(is);
+ } catch (IOException ex) {
+ NotificationDisplayer.getDefault().notify(
+ Bundle.TITLE_ConfigUpdateFailed(),
+ NbGradleProject.getWarningIcon(),
+ Bundle.ERROR_ConfigUpdateFailed(ex.getLocalizedMessage()), null,
+ NotificationDisplayer.Priority.HIGH, NotificationDisplayer.Category.ERROR);
+ return createResult(Status.UNKNOWN);
+ }
+ } else {
+ if (publicProxyHost == null) {
+ return createResult(Status.CONTINUE);
+ }
+ }
+
+ if (publicProxy != null) {
+ eprops.put(SYSTEMPROP_HTTP_PROXYHOST, publicProxyHost);
+ eprops.put(SYSTEMPROP_HTTPS_PROXYHOST, publicProxyHost);
+ if (publicProxyNonDefaultPort > 0) {
+ eprops.put(SYSTEMPROP_HTTP_PROXYPORT, Integer.toString(publicProxyNonDefaultPort));
+ eprops.put(SYSTEMPROP_HTTPS_PROXYPORT, Integer.toString(publicProxyNonDefaultPort));
+ } else {
+ eprops.remove(SYSTEMPROP_HTTP_PROXYPORT);
+ eprops.remove(SYSTEMPROP_HTTPS_PROXYPORT);
+ }
+ eprops.setComment(SYSTEMPROP_HTTP_PROXYHOST, new String[] {
+ Bundle.COMMENT_CreatedByNetBeans(DateFormat.getDateTimeInstance().format(new Date()))
+ }, true );
+ } else {
+ eprops.remove(SYSTEMPROP_HTTP_PROXYHOST);
+ eprops.remove(SYSTEMPROP_HTTP_PROXYPORT);
+ eprops.remove(SYSTEMPROP_HTTPS_PROXYHOST);
+ eprops.remove(SYSTEMPROP_HTTPS_PROXYPORT);
+ }
+
+ if (userProps.exists()) {
+ String base = userProps.getName() + FILENAME_SUFFIX_OLD;
+ File f = new File(userProps.getParentFile(), base);
+ int n = 1;
+ while (f.exists()) {
+ f = new File(userProps.getParentFile(), base + "." + n); // NOI18N
+ n++;
+ }
+ userProps.renameTo(f);
+ }
+ try (FileOutputStream os = new FileOutputStream(userProps)) {
+ eprops.store(os);
+ StatusDisplayer.getDefault().setStatusText(
+ proxyHost == null ?
+ Bundle.MSG_ProxyCleared() :
+ Bundle.MSG_ProxySetTo(proxyAuthority)
+ );
+ } catch (IOException ex) {
+ NotificationDisplayer.getDefault().notify(
+ Bundle.TITLE_ConfigUpdateFailed(),
+ NbGradleProject.getWarningIcon(),
+ Bundle.ERROR_ConfigUpdateFailed(ex.getLocalizedMessage()), null,
+ NotificationDisplayer.Priority.HIGH, NotificationDisplayer.Category.ERROR);
+ return createResult(Status.ABORT);
+ }
+ return createResult(Status.RECONFIGURED);
+ }
+
+ ProxyResult processUserConfirmation(NotifyDescriptor desc) {
+ Object val = desc.getValue();
+ if (val == NotifyDescriptor.CANCEL_OPTION) {
+ return createResult(Status.ABORT);
+ } else if (val == Bundle.ACTION_Continue()) {
+ return createResult(Status.CONTINUE);
+ } else if (val == Bundle.ACTION_Override()) {
+ return createResult(Status.OVERRIDE);
+ } else if (val == NotifyDescriptor.OK_OPTION) {
+ return updateGradleConfiguration(true);
+ }
+ return createResult(Status.UNKNOWN);
+ }
+
+ private void obtainPublicProxy() {
+ URI probeUri;
+ try {
+ probeUri = new URI(PROBE_URI_STRING);
+ } catch (URISyntaxException ex) {
+ // this is competely unexpected
+ Exceptions.printStackTrace(ex);
+ return;
+ }
+ List<Proxy> proxies = ProxySelector.getDefault().select(probeUri);
+ LOG.log(Level.FINER, "Detected proxies for URI {0}: {1}", new Object[] { probeUri, proxies });
+ for (Proxy p : proxies) {
+ if (p.type() == Proxy.Type.HTTP) {
+ publicProxy = p;
+ LOG.log(Level.FINE, "Selected HTTP proxy: {0}", p);
+ break;
+ } else if (p.type() == Proxy.Type.SOCKS) {
+ if (publicProxy == null) {
+ LOG.log(Level.FINE, "Found SOCKS proxy: {0}", p);
+ publicProxy = p;
+ }
+ }
+ }
+ if (publicProxy != null) {
+ SocketAddress proxyAddress = publicProxy.address();
+ if (proxyAddress instanceof InetSocketAddress) {
+ InetSocketAddress iaddr = (InetSocketAddress)proxyAddress;
+ int port = iaddr.getPort();
+ int defPort = -1;
+
+ switch(publicProxy.type()) {
+ case HTTP:
+ defPort = PORT_DEFAULT_HTTP;
+ break;
+ case SOCKS:
+ defPort = PORT_DEFAULT_HTTPS;
+ break;
+ }
+
+ if (port > 1) {
+ publicProxyPort = port;
+ if (publicProxyPort != defPort) {
+ publicProxyNonDefaultPort = port;
+ }
+ }
+ publicProxyHost = ((InetSocketAddress) proxyAddress).getHostString();
+ publicProxySpec = publicProxyHost + ((publicProxyNonDefaultPort == 0) ? "" : ":" + publicProxyNonDefaultPort);
+ LOG.log(Level.FINE, "Detected proxy: {0}", publicProxySpec);
+ }
+ }
+ }
+
+ private boolean extractNetworkProxy(Properties props) {
+ proxyHost = props.getProperty(SYSTEMPROP_HTTP_PROXYHOST);
+ String portKey;
+ int defPort;
+
+ if (proxyHost == null || proxyHost.isEmpty()) {
+ proxyHost = props.getProperty(SYSTEMPROP_HTTPS_PROXYHOST);
+ if (proxyHost == null || proxyHost.isEmpty()) {
+ proxyHost = null;
+ proxyPort = -1;
+ return false;
+ } else {
+ LOG.log(Level.FINER, "Found https proxy: ", proxyHost);
+ }
+ portKey = SYSTEMPROP_HTTPS_PROXYPORT;
+ defPort = 443;
+ } else {
+ LOG.log(Level.FINER, "Found http proxy: ", proxyHost);
+ defPort = 80;
+ portKey = SYSTEMPROP_HTTP_PROXYPORT;
+ }
+
+ String port = props.getProperty(portKey);
+ if (port != null && !port.trim().isEmpty()) {
+ proxyAuthority = proxyHost + ":" + port;
+ try {
+ proxyPort = Integer.parseInt(port);
+ } catch (NumberFormatException ex) {
+ // expected ?
+ proxyPort = defPort;
+ proxyAuthority = proxyHost;
+ }
+ } else {
+ proxyPort = defPort;
+ proxyAuthority = proxyHost;
+ }
+ return true;
+ }
+
+
+ private void loadProjectProxy() {
+ File f = FileUtil.toFile(project.getProjectDirectory());
+ if (f == null || !f.exists()) {
+ LOG.log(Level.WARNING, "Project has no directory: {0}", project);
+ return;
+ }
+ GradleFiles gf = new GradleFiles(f);
+ gradleFiles = gf;
+ // system properties are only read from the root project's directory, not from subprojects.
+ File rootDir = gf.getRootDir();
+ LOG.log(Level.FINE, "Project directory: {0}, root directory: {1}", new Object[] { f, rootDir });
+ if (!rootDir.equals(f)) {
+ gf = new GradleFiles(rootDir);
+ }
+
+ Properties props = new Properties();
+
+ File userProperties = gf.getFile(GradleFiles.Kind.USER_PROPERTIES);
+ File projectProperties = gf.getFile(GradleFiles.Kind.PROJECT_PROPERTIES);
+
+ if (projectProperties != null && projectProperties.exists()) {
+ try (FileInputStream fis = new FileInputStream(projectProperties)) {
+ LOG.log(Level.FINER, "Loading project properties from {0}", projectProperties);
+ props.load(fis);
+ } catch (IOException ex) {
+ // TBD: log
+ }
+ }
+ // override project properties with user properties; see Gradle manual for precedence.
+ if (userProperties != null && userProperties.exists()) {
+ try (FileInputStream fis = new FileInputStream(userProperties)) {
+ LOG.log(Level.FINER, "Loading user properties from {0}", userProperties);
+ props.load(fis);
+ } catch (IOException ex) {
+ // TBD: log
+ }
+ }
+
+ extractNetworkProxy(props);
+ }
+
+ }
+
+}
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/loaders/LegacyProjectLoader.java b/extide/gradle/src/org/netbeans/modules/gradle/loaders/LegacyProjectLoader.java
index b05f751916..9406a19764 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/loaders/LegacyProjectLoader.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/loaders/LegacyProjectLoader.java
@@ -75,6 +75,7 @@ import org.netbeans.modules.gradle.tooling.internal.NbProjectInfo.Report;
import org.netbeans.modules.gradle.api.execute.GradleCommandLine;
import org.netbeans.modules.gradle.api.execute.RunUtils;
import org.netbeans.modules.gradle.cache.ProjectInfoDiskCache;
+import org.netbeans.modules.gradle.execute.GradleNetworkProxySupport;
import org.netbeans.modules.gradle.spi.GradleSettings;
import org.openide.util.Cancellable;
import org.openide.util.NbBundle;
@@ -326,6 +327,11 @@ public class LegacyProjectLoader extends AbstractProjectLoader {
Throwable th = ex;
while (th != null) {
problems.add(GradleProject.createGradleReport(null, th.getMessage()));
+ ex = th;
+ th = th.getCause();
+ if (ex == th) {
+ break;
+ }
}
return problems;
}
@@ -454,6 +460,9 @@ public class LegacyProjectLoader extends AbstractProjectLoader {
return ret;
}
+ @NbBundle.Messages({
+ "ERR_UserAbort=Project analysis aborted by the user."
+ })
private static NbProjectInfo retrieveProjectInfo(NbGradleProjectImpl projectImpl, GoOnline goOnline, ProjectConnection pconn, GradleCommandLine cmd, CancellationToken token, ProgressListener pl, AtomicBoolean wasOnline) throws GradleConnectionException, IllegalStateException {
NbProjectInfo ret;
@@ -489,8 +498,26 @@ public class LegacyProjectLoader extends AbstractProjectLoader {
}
}
}
+
+ BuildActionExecuter<NbProjectInfo> action = createInfoAction(pconn, online, token, pl);
+ // since we're going online, check the network settings:
+ GradleNetworkProxySupport support = projectImpl.getLookup().lookup(GradleNetworkProxySupport.class);
+ if (support != null) {
+ try {
+ GradleNetworkProxySupport.ProxyResult result = support.checkProxySettings().get();
+ switch (result.getStatus()) {
+ case ABORT:
+ LOG.log(Level.FINE, "User cancelled the project load");
+ throw new IllegalStateException(Bundle.ERR_UserAbort());
+ }
+ action = result.configure(action);
+ } catch (InterruptedException ex) {
+ throw new IllegalStateException(ex);
+ } catch (ExecutionException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
- BuildActionExecuter<NbProjectInfo> action = createInfoAction(pconn, online, token, pl);
wasOnline.set(true);
return runInfoAction(action);
}
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/options/Bundle.properties b/extide/gradle/src/org/netbeans/modules/gradle/options/Bundle.properties
index a192be03cb..76285a5c74 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/options/Bundle.properties
+++ b/extide/gradle/src/org/netbeans/modules/gradle/options/Bundle.properties
@@ -59,3 +59,4 @@ SettingsPanel.cbUseConfigCache.toolTipText=<html>This is an <b>incubating</b> fe
SettingsPanel.cbUseConfigCache.text=Use Configuration Cache
SettingsPanel.cbNoRebuild.text=Do not Rebuild Project Dependencies
SettingsPanel.cbNoRebuild.toolTipText=<html>Useful for debugging and fine-tuning buildSrc, but <b>can lead to wrong results</b>.<br/>Use with caution!
+SettingsPanel.jLabel2.text=Network Proxy:
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/options/GradleExperimentalSettings.java b/extide/gradle/src/org/netbeans/modules/gradle/options/GradleExperimentalSettings.java
index 35432d52e5..3fc9a8185b 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/options/GradleExperimentalSettings.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/options/GradleExperimentalSettings.java
@@ -29,6 +29,7 @@ public final class GradleExperimentalSettings {
public static final String PROP_DISABLE_CACHE = "disableCache";
public static final String PROP_LAZY_OPEN_GROUPS = "lazyOpen";
public static final String PROP_BUNDLED_LOADING = "bundledLoading";
+ public static final String PROP_NETWORK_PROXY = "networkProxy";
private static final GradleExperimentalSettings INSTANCE = new GradleExperimentalSettings(NbPreferences.forModule(GradleExperimentalSettings.class));
private final Preferences preferences;
@@ -68,4 +69,17 @@ public final class GradleExperimentalSettings {
public boolean isBundledLoading() {
return getPreferences().getBoolean(PROP_BUNDLED_LOADING, false);
}
+
+ public NetworkProxySettings getNetworkProxy() {
+ String s = getPreferences().get(PROP_NETWORK_PROXY, NetworkProxySettings.ASK.name());
+ try {
+ return NetworkProxySettings.valueOf(s);
+ } catch (IllegalArgumentException ex) {
+ return NetworkProxySettings.ASK;
+ }
+ }
+
+ public void setNetworkProxy(NetworkProxySettings s) {
+ getPreferences().put(PROP_NETWORK_PROXY, s.name());
+ }
}
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/options/NetworkProxySettings.java b/extide/gradle/src/org/netbeans/modules/gradle/options/NetworkProxySettings.java
new file mode 100644
index 0000000000..fdb03195ec
--- /dev/null
+++ b/extide/gradle/src/org/netbeans/modules/gradle/options/NetworkProxySettings.java
@@ -0,0 +1,79 @@
+/*
+ * 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.gradle.options;
+
+import org.netbeans.modules.gradle.api.execute.RunUtils;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author sdedic
+ */
+@NbBundle.Messages({
+ "PROXY_IGNORE=Do not check",
+ "PROXY_NOTICE=Display Mismatch Notice",
+ "PROXY_UPDATE=Update User Properties",
+ "PROXY_ASK=Ask Before Execution",
+ "PROXY_OVERRIDE=Override on execution",
+})
+public enum NetworkProxySettings {
+ /**
+ * Do not verify proxy settings.
+ */
+ IGNORE,
+ /**
+ * Display a notice that proxy settings mismatch.
+ */
+ NOTICE,
+ /**
+ * Update user's gradle.properties file.
+ */
+ UPDATE,
+ /**
+ * Ask the user for confirmation.
+ */
+ ASK,
+ /**
+ * Automatically override on execution, but do not change gradle.properties.
+ */
+ OVERRIDE;
+
+ public String toString() {
+ switch (this) {
+ case IGNORE: return Bundle.PROXY_IGNORE();
+ case NOTICE: return Bundle.PROXY_NOTICE();
+ case UPDATE: return Bundle.PROXY_UPDATE();
+ case ASK: return Bundle.PROXY_ASK();
+ case OVERRIDE: return Bundle.PROXY_OVERRIDE();
+
+ default:
+ return name();
+ }
+ }
+
+ private static final String BRANDING_API_OVERRIDE_ENABLED = "org.netbeans.modules.gradle.api.execute.NetworkProxySettings.allowOverride";
+
+ /**
+ * Determines if override is a valid option.
+ * @return true, if override should be offered as an option
+ */
+ public static boolean allowProxyOverride() {
+ return Boolean.parseBoolean(NbBundle.getMessage(RunUtils.class, BRANDING_API_OVERRIDE_ENABLED));
+ }
+}
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.form b/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.form
index 47224f56b6..e261be3182 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.form
+++ b/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.form
@@ -41,7 +41,7 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
- <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-70,0,0,3,82"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-35,0,0,3,82"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
@@ -72,7 +72,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="lblCategories" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="lstCategories" max="32767" attributes="0"/>
+ <Component id="lstCategories" pref="440" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@@ -146,9 +146,16 @@
</Group>
<Component id="jPanel2" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
- <Component id="lbAllowExecution" max="32767" attributes="0"/>
+ <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+ <Group type="103" groupAlignment="0" max="-2" attributes="0">
+ <Component id="lbAllowExecution" max="32767" attributes="0"/>
+ <Component id="jLabel2" max="32767" attributes="0"/>
+ </Group>
<EmptySpace max="-2" attributes="0"/>
- <Component id="cbAllowExecution" min="-2" pref="280" max="-2" attributes="0"/>
+ <Group type="103" groupAlignment="0" max="-2" attributes="0">
+ <Component id="cbNetworkProxy" max="32767" attributes="0"/>
+ <Component id="cbAllowExecution" pref="280" max="32767" attributes="0"/>
+ </Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@@ -166,7 +173,12 @@
<Component id="cbAllowExecution" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbAllowExecution" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
- <EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
+ <EmptySpace max="-2" attributes="0"/>
+ <Group type="103" groupAlignment="3" attributes="0">
+ <Component id="cbNetworkProxy" alignment="3" min="-2" max="-2" attributes="0"/>
+ <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+ </Group>
+ <EmptySpace max="32767" attributes="0"/>
<Component id="cbPreferMaven" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
@@ -442,7 +454,7 @@
<Component id="cbConfigureOnDemand" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="cbNoRebuild" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
- <EmptySpace max="32767" attributes="0"/>
+ <EmptySpace pref="162" max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="cbUseConfigCache" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
@@ -548,6 +560,18 @@
</Property>
</Properties>
</Component>
+ <Component class="javax.swing.JComboBox" name="cbNetworkProxy">
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<NetworkProxySettings>"/>
+ </AuxValues>
+ </Component>
+ <Component class="javax.swing.JLabel" name="jLabel2">
+ <Properties>
+ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString bundle="org/netbeans/modules/gradle/options/Bundle.properties" key="SettingsPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
+ </Property>
+ </Properties>
+ </Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnlAppearance">
@@ -582,7 +606,7 @@
<Component id="jPanel4" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jPanel5" min="-2" max="-2" attributes="0"/>
- <EmptySpace pref="204" max="32767" attributes="0"/>
+ <EmptySpace pref="232" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -762,7 +786,7 @@
<Component id="lbDownloadJavadoc" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cbDownloadJavadoc" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
- <EmptySpace pref="352" max="32767" attributes="0"/>
+ <EmptySpace pref="384" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -865,7 +889,7 @@
<Component id="cbOpenLazy" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbBundledLoading" min="-2" max="-2" attributes="0"/>
- <EmptySpace pref="334" max="32767" attributes="0"/>
+ <EmptySpace pref="365" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.java b/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.java
index 546024e5d4..e8d10f7312 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/options/SettingsPanel.java
@@ -76,6 +76,12 @@ public class SettingsPanel extends javax.swing.JPanel {
cbDownloadSources.setModel(new DefaultComboBoxModel<>(GradleSettings.DownloadMiscRule.values()));
cbDownloadJavadoc.setModel(new DefaultComboBoxModel<>(GradleSettings.DownloadMiscRule.values()));
cbAllowExecution.setModel(new DefaultComboBoxModel<>(GradleSettings.GradleExecutionRule.values()));
+
+ DefaultComboBoxModel mdl = new DefaultComboBoxModel<>(NetworkProxySettings.values());
+ if (!NetworkProxySettings.allowProxyOverride()) {
+ mdl.removeElement(NetworkProxySettings.OVERRIDE);
+ }
+ cbNetworkProxy.setModel(mdl);
}
/**
@@ -119,6 +125,8 @@ public class SettingsPanel extends javax.swing.JPanel {
lbAllowExecution = new javax.swing.JLabel();
cbAllowExecution = new javax.swing.JComboBox<>();
cbPreferMaven = new javax.swing.JCheckBox();
+ cbNetworkProxy = new javax.swing.JComboBox<>();
+ jLabel2 = new javax.swing.JLabel();
pnlAppearance = new javax.swing.JPanel();
jPanel4 = new javax.swing.JPanel();
cbDisplayDescription = new javax.swing.JCheckBox();
@@ -174,7 +182,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addContainerGap()
.addComponent(lblCategories)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(lstCategories, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lstCategories, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
.addContainerGap())
);
@@ -364,7 +372,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(cbOffline)
.addComponent(cbConfigureOnDemand)
.addComponent(cbNoRebuild))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 162, Short.MAX_VALUE)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(cbUseConfigCache)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
@@ -395,6 +403,8 @@ public class SettingsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(cbPreferMaven, org.openide.util.NbBundle.getMessage(SettingsPanel.class, "SettingsPanel.cbPreferMaven.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SettingsPanel.class, "SettingsPanel.jLabel2.text")); // NOI18N
+
javax.swing.GroupLayout pnlExecutionLayout = new javax.swing.GroupLayout(pnlExecution);
pnlExecution.setLayout(pnlExecutionLayout);
pnlExecutionLayout.setHorizontalGroup(
@@ -408,9 +418,14 @@ public class SettingsPanel extends javax.swing.JPanel {
.addGap(0, 346, Short.MAX_VALUE))
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlExecutionLayout.createSequentialGroup()
- .addComponent(lbAllowExecution, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(0, 0, Short.MAX_VALUE)
+ .addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbAllowExecution, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(cbAllowExecution, javax.swing.GroupLayout.PREFERRED_SIZE, 280, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(cbNetworkProxy, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(cbAllowExecution, 0, 280, Short.MAX_VALUE))))
.addContainerGap())
);
pnlExecutionLayout.setVerticalGroup(
@@ -423,7 +438,11 @@ public class SettingsPanel extends javax.swing.JPanel {
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cbAllowExecution, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbAllowExecution))
- .addGap(11, 11, 11)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cbNetworkProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel2))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(cbPreferMaven)
.addContainerGap())
);
@@ -509,7 +528,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(204, Short.MAX_VALUE))
+ .addContainerGap(232, Short.MAX_VALUE))
);
pnlCards.add(pnlAppearance, "Appearance");
@@ -570,7 +589,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addGroup(pnlDependenciesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDownloadJavadoc)
.addComponent(cbDownloadJavadoc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addContainerGap(352, Short.MAX_VALUE))
+ .addContainerGap(384, Short.MAX_VALUE))
);
pnlCards.add(pnlDependencies, "Dependencies");
@@ -613,7 +632,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(cbOpenLazy)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbBundledLoading)
- .addContainerGap(334, Short.MAX_VALUE))
+ .addContainerGap(365, Short.MAX_VALUE))
);
pnlCards.add(pnlExperimental, "Experimental");
@@ -746,6 +765,8 @@ public class SettingsPanel extends javax.swing.JPanel {
cbDownloadJavadoc.setSelectedItem(settings.getDownloadJavadoc());
cbAllowExecution.setSelectedItem(settings.getGradleExecutionRule());
+
+ cbNetworkProxy.setSelectedItem(experimental.getNetworkProxy());
new SwingWorker<List<GradleDistribution>, Void>() {
@@ -830,6 +851,8 @@ public class SettingsPanel extends javax.swing.JPanel {
LifecycleManager.getDefault().exit();
});
}
+
+ experimental.setNetworkProxy((NetworkProxySettings)cbNetworkProxy.getSelectedItem());
}
public boolean hasChanges() {
@@ -869,6 +892,8 @@ public class SettingsPanel extends javax.swing.JPanel {
isChanged |= settings.getDownloadJavadoc() != cbDownloadJavadoc.getSelectedItem();
isChanged |= settings.getGradleExecutionRule() != cbAllowExecution.getSelectedItem();
+
+ isChanged |= experimental.getNetworkProxy() != cbNetworkProxy.getSelectedItem();
return isChanged;
}
@@ -933,6 +958,7 @@ public class SettingsPanel extends javax.swing.JPanel {
private javax.swing.JCheckBox cbEnableCache;
private javax.swing.JComboBox<GradleDistribution> cbGradleVersion;
private javax.swing.JCheckBox cbHideEmptyConfig;
+ private javax.swing.JComboBox<NetworkProxySettings> cbNetworkProxy;
private javax.swing.JCheckBox cbNoRebuild;
private javax.swing.JCheckBox cbOffline;
private javax.swing.JCheckBox cbOpenLazy;
@@ -946,6 +972,7 @@ public class SettingsPanel extends javax.swing.JPanel {
private javax.swing.JCheckBox cbStartDaemonOnStart;
private javax.swing.JCheckBox cbUseConfigCache;
private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
---------------------------------------------------------------------
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