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 e37e856fca Proxy autodetection + autoconfiguration for Maven. (#5038)
e37e856fca is described below
commit e37e856fca13c1c0b174a5fb872c5c8f4f74332f
Author: Svatopluk Dedic <[email protected]>
AuthorDate: Wed Dec 7 20:41:42 2022 +0100
Proxy autodetection + autoconfiguration for Maven. (#5038)
Proxy autodetection + autoconfiguration for Maven. Reset gaps/panels to
default size.
---
.../modules/gradle/api/execute/Bundle.properties | 2 +
.../modules/maven/api/execute/Bundle.properties | 1 +
java/maven/licenseinfo.xml | 3 +
.../modules/maven/api/execute/Bundle.properties | 4 +-
.../maven/execute/MavenCommandLineExecutor.java | 60 +-
.../modules/maven/execute/MavenProxySupport.java | 1000 ++++++++++++++++++++
.../modules/maven/execute/proxies.template.xml | 9 +
.../modules/maven/execute/proxy.template.xml | 7 +
.../maven/src/org/netbeans/modules/maven/layer.xml | 5 +
.../modules/maven/options/Bundle.properties | 1 +
.../modules/maven/options/MavenSettings.java | 13 +
.../maven/options/NetworkProxySettings.java | 76 ++
.../modules/maven/options/SettingsPanel.form | 78 +-
.../modules/maven/options/SettingsPanel.java | 63 +-
.../modules/maven/problems/SanityBuildAction.java | 30 +
.../netbeans/modules/maven/settings.template.xml | 17 +
16 files changed, 1328 insertions(+), 41 deletions(-)
diff --git
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-gradle.jar/org/netbeans/modules/gradle/api/execute/Bundle.properties
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-gradle.jar/org/netbeans/modules/gradle/api/execute/Bundle.properties
index c19939052e..fb601ea76a 100644
---
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-gradle.jar/org/netbeans/modules/gradle/api/execute/Bundle.properties
+++
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-gradle.jar/org/netbeans/modules/gradle/api/execute/Bundle.properties
@@ -18,3 +18,5 @@
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=3
+
+org.netbeans.modules.gradle.api.execute.NetworkProxySettings.allowOverride=false
\ No newline at end of file
diff --git
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
index aec63c34af..32382db89c 100644
---
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
+++
b/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
@@ -16,3 +16,4 @@
# under the License.
DEFAULT_COMPILE_ON_SAVE=none
+org.netbeans.modules.maven.api.execute.NetworkProxySettings.allowOverride=false
diff --git a/java/maven/licenseinfo.xml b/java/maven/licenseinfo.xml
index 86205c1d28..467836a522 100644
--- a/java/maven/licenseinfo.xml
+++ b/java/maven/licenseinfo.xml
@@ -82,6 +82,9 @@
<fileset>
<file>src/org/netbeans/modules/maven/resources/AppTest.java.template</file>
<file>src/org/netbeans/modules/maven/resources/App.java.template</file>
+
<file>src/org/netbeans/modules/maven/execute/proxies.template.xml</file>
+ <file>src/org/netbeans/modules/maven/execute/proxy.template.xml</file>
+ <file>src/org/netbeans/modules/maven/settings.template.xml</file>
<license ref="Apache-2.0-ASF" />
<comment type="TEMPLATE_MINIMAL_IP"/>
</fileset>
diff --git
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
b/java/maven/src/org/netbeans/modules/maven/api/execute/Bundle.properties
similarity index 81%
copy from
java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
copy to java/maven/src/org/netbeans/modules/maven/api/execute/Bundle.properties
index aec63c34af..d17e291333 100644
---
a/java/java.lsp.server/nbcode/branding/modules/org-netbeans-modules-maven.jar/org/netbeans/modules/maven/api/execute/Bundle.properties
+++ b/java/maven/src/org/netbeans/modules/maven/api/execute/Bundle.properties
@@ -15,4 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-DEFAULT_COMPILE_ON_SAVE=none
+# Branding API
+# Enables on-the-fly override of proxy in maven sttings. Permitted values:
true, false.
+org.netbeans.modules.maven.api.execute.NetworkProxySettings.allowOverride=true
diff --git
a/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
b/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
index b1805f66a9..da5362821c 100644
---
a/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
+++
b/java/maven/src/org/netbeans/modules/maven/execute/MavenCommandLineExecutor.java
@@ -38,6 +38,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -84,6 +85,7 @@ import org.netbeans.modules.maven.runjar.MavenExecuteUtils;
import org.netbeans.spi.project.ui.support.BuildExecutionSupport;
import org.openide.LifecycleManager;
import org.openide.awt.HtmlBrowser;
+import org.openide.awt.NotificationDisplayer;
import org.openide.execution.ExecutionEngine;
import org.openide.execution.ExecutorTask;
import org.openide.filesystems.FileObject;
@@ -92,7 +94,9 @@ import org.openide.modules.InstalledFileLocator;
import org.openide.modules.Places;
import org.openide.modules.SpecificationVersion;
import org.openide.util.Exceptions;
+import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.Task;
import org.openide.util.TaskListener;
@@ -143,6 +147,8 @@ public class MavenCommandLineExecutor extends
AbstractMavenExecutor {
private static final RequestProcessor RP = new
RequestProcessor(MavenCommandLineExecutor.class.getName(),1);
private static final RequestProcessor UPDATE_INDEX_RP = new
RequestProcessor(RunUtils.class.getName(), 5);
+
+ private static final String ICON_MAVEN_PROJECT =
"org/netbeans/modules/maven/resources/Maven2Icon.gif"; // NOI18N
/**
* Execute maven build in NetBeans execution engine.
* Most callers should rather use {@link #run} as this variant does no
(non-late-bound) prerequisite checks.
@@ -200,6 +206,11 @@ public class MavenCommandLineExecutor extends
AbstractMavenExecutor {
this.io = io;
}
+ @NbBundle.Messages({
+ "# {0} - original message",
+ "ERR_CannotOverrideProxy=Could not override the proxy: {0}",
+ "ERR_BuildCancelled=Build cancelled by the user"
+ })
/**
* not to be called directly.. use execute();
*/
@@ -225,6 +236,49 @@ public class MavenCommandLineExecutor extends
AbstractMavenExecutor {
int executionresult = -10;
final InputOutput ioput = getInputOutput();
+ // TODO: maybe global instance for project-less operation ?
+ MavenProxySupport mps = (clonedConfig.getProject() == null) ? null :
clonedConfig.getProject().getLookup().lookup(MavenProxySupport.class);
+ if (mps != null) {
+ boolean ok = false;
+ try {
+ MavenProxySupport.ProxyResult res =
mps.checkProxySettings().get();
+
+ if (res != null) {
+ res.configure(clonedConfig);
+ }
+ if (res.getStatus() == MavenProxySupport.Status.ABORT) {
+ IOException ex = res.getException();
+
+ if (ex == null) {
+ ioput.getErr().append(Bundle.ERR_BuildCancelled());
+ } else {
+ throw ex;
+ }
+
+ } else {
+ ok = true;
+ }
+ } catch (IOException ex) {
+
NotificationDisplayer.getDefault().notify(Bundle.TITLE_ProxyUpdateFailed(),
+ ImageUtilities.loadImageIcon(ICON_MAVEN_PROJECT,
false),
+ ex.getLocalizedMessage(), null,
NotificationDisplayer.Priority.NORMAL, NotificationDisplayer.Category.ERROR);
+
ioput.getErr().append(Bundle.ERR_CannotOverrideProxy(ex.getLocalizedMessage()));
+ // FIXME: log exception
+ } catch (ExecutionException ex) {
+ // FIXME: log exception
+ } catch (InterruptedException ex) {
+ // FIXME: log exception
+ } finally {
+ if (!ok) {
+ ioput.getOut().close();
+ ioput.getErr().close();
+ actionStatesAtFinish(null, null);
+ markFreeTab();
+ return;
+ }
+ }
+ }
+
final ProgressHandle handle =
ProgressHandle.createHandle(clonedConfig.getTaskDisplayName(), this, new
AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -469,7 +523,11 @@ public class MavenCommandLineExecutor extends
AbstractMavenExecutor {
toRet.add(rel != null ? rel : mp.getGroupId() + ':' +
mp.getArtifactId());
}
}
-
+ Object o = config.getInternalProperties().get("NbIde.configOverride");
// NOI18N
+ if (o instanceof String) {
+ toRet.add("--settings");
+ toRet.add(o.toString());
+ }
String opts = MavenSettings.getDefault().getDefaultOptions();
if (opts != null) {
try {
diff --git
a/java/maven/src/org/netbeans/modules/maven/execute/MavenProxySupport.java
b/java/maven/src/org/netbeans/modules/maven/execute/MavenProxySupport.java
new file mode 100644
index 0000000000..adcd4489da
--- /dev/null
+++ b/java/maven/src/org/netbeans/modules/maven/execute/MavenProxySupport.java
@@ -0,0 +1,1000 @@
+/*
+ * 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.maven.execute;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+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.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.StyledDocument;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
+import org.codehaus.plexus.util.xml.pull.MXParser;
+import org.codehaus.plexus.util.xml.pull.XmlPullParser;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.netbeans.api.editor.document.AtomicLockDocument;
+import org.netbeans.api.editor.document.LineDocument;
+import org.netbeans.api.editor.document.LineDocumentUtils;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.templates.FileBuilder;
+import org.netbeans.modules.maven.api.NbMavenProject;
+import org.netbeans.modules.maven.embedder.EmbedderFactory;
+import org.netbeans.modules.maven.options.MavenSettings;
+import org.netbeans.modules.maven.options.NetworkProxySettings;
+import org.netbeans.spi.project.ProjectServiceProvider;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.NotificationDisplayer;
+import org.openide.cookies.EditorCookie;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.loaders.SaveAsCapable;
+import org.openide.modules.Places;
+import org.openide.util.Exceptions;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.MapFormat;
+import org.openide.util.NbBundle;
+
+/**
+ * Checks the proxy settings and possibly reconfigures Maven settings. The
class checks the effective proxy settings using {@link ProxySelector} API, then
reads the current Maven
+ * settings using {@link EmbedderFactory#getProjectEmbedder()}. If the maven
settings do not contain proper proxy setup, maven options ({@link
MavenSettings#getNetworkProxy()} is consulted:
+ * <ul>
+ * <li>IGNORE - no special handling
+ * <li>NOTICE - a notice is printed into the notifications area informing
about possible bad proxy setup, no other action taken
+ * <li>UPDATE - maven configuration will be automatically updated (see below)
+ * <li>OVERRIDE - persistent global configuration is not changed, but a new
settings file will be generated in $nbuser/var/cache/maven and maven {@link
BeanRunConfig} will be instructed to use it
+ * <li>ASK - asks the user
+ * </ul>
+ * If maven settings are updated, the original contents is preserved as
<code>settings.xml.old</code> or a numbered <code>settings.xml.old.N</code>,
first unused N is selected. If the settings file contins
+ * the proxy in effect, but not active, the <code>active</code> property of
that proxy will be set to true, and the others to false. Otherwise a new proxy
entry with the desired proxy host/port is created.
+ * To disable proxies, all <code>active</code> entries are set to false.
+ * <p>
+ * The {@link
ProxyResult#configure(org.netbeans.modules.maven.execute.BeanRunConfig)} should
be run before each maven online invocation to potentially replace the global
settings file with a customized one,
+ * that specifies the correct proxy.
+ * <p>
+ * When creating customized settings.xml files, the files are named like
<code>settings-[hashcode of the oroginal]-[sanitized proxy host].xml. If the
settings.xml file does not exist at all, "new" is used
+ * instead of the hashcode. Proxy host sanitization just replaces weird
characters by "_".
+ *
+ * @author sdedic
+ */
+@ProjectServiceProvider(service = MavenProxySupport.class, projectType =
NbMavenProject.TYPE)
+public class MavenProxySupport {
+ private static final Logger LOG =
Logger.getLogger(MavenProxySupport.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 ICON_MAVEN_PROJECT =
"org/netbeans/modules/maven/resources/Maven2Icon.gif"; // NOi18N
+
+
+ /**
+ * Tag name in settings file.
+ */
+ private static final String TAG_SETTINGS = "settings"; // NOI18N
+
+ /**
+ * Tag name in settings file.
+ */
+ private static final String TAG_PROXIES = "proxies"; // NOI18N
+
+ /**
+ * Tag name in settings file.
+ */
+ private static final String TAG_NAME_ACTIVE = "active"; // NOI18N
+
+ /**
+ * Complete tag start/end. End tag should contain a newline.
+ */
+ private static final String TAG_ACTIVE_START = "<active>"; // NOI18N
+ private static final String TAG_ACTIVE_END = "</active>\n"; // NOI18N
+
+ /**
+ * Tag name in settings file.
+ */
+ private static final String TAG_PROXY = "proxy"; // NOI18N
+
+ /**
+ * Suffix to add to customized settings filename when no proxy is
configured (all disabled)
+ */
+ private static final String SUFFIX_NONE_PROXY = "-none"; // NOI18N
+
+ /**
+ * Suffix for custom settings filename if global settings is missing.
+ */
+ private static final String SUFFIX_NEW_PROXY = "-new";
+
+ /**
+ * Extension for the settings file
+ */
+ private static final String FILENAME_SETTINGS_EXT = ".xml"; // NOI18N
+
+ /**
+ * Global settings file name
+ */
+ private static final String FILENAME_BASE_SETTINGS = "settings"; // NOI18N
+ private static final String FILENAME_SETTINGS = FILENAME_BASE_SETTINGS +
FILENAME_SETTINGS_EXT;
+
+
+ private static final int PORT_DEFAULT_HTTPS = 1080;
+ private static final int PORT_DEFAULT_HTTP = 80;
+
+ /**
+ * 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 MavenProxySupport(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 Proxy proxy;
+ private final String toolProxy;
+ private final String proxyHost;
+ private final String proxySpec;
+ private final int proxyPort;
+ private final Settings mavenSettings;
+ private final boolean nonDefaultPort;
+ private volatile Status status;
+ TextInfo textInfo;
+ FileObject settingsDir;
+ String settingsFileName = FILENAME_SETTINGS;
+ IOException exception;
+
+ public ProxyResult(Status status, Proxy proxy) {
+ this.status = status;
+ this.proxy = proxy;
+ this.toolProxy = null;
+ this.proxySpec = null;
+ this.proxyHost = null;
+ this.proxyPort = -1;
+ this.mavenSettings = null;
+ this.nonDefaultPort = false;
+ }
+
+ public ProxyResult(Status status, Proxy proxy, String toolProxy,
String proxySpec, String proxyHost, int proxyPort, boolean nonDefault, Settings
mavenSettings) {
+ this.status = status;
+ this.proxy = proxy;
+ this.toolProxy = toolProxy;
+ this.proxySpec = proxySpec;
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ this.mavenSettings = mavenSettings;
+ this.nonDefaultPort = nonDefault;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public Proxy getProxy() {
+ return proxy;
+ }
+
+ public String getToolProxy() {
+ return toolProxy;
+ }
+
+ public String getProxySpec() {
+ return proxySpec;
+ }
+
+ public IOException getException() {
+ return exception;
+ }
+
+ @NbBundle.Messages({
+ "# {0} - settings directory name",
+ "ERR_CannotCreateSettingsDir=Could not create settings directory:
{0}",
+ "# {0} - settings file name",
+ "ERR_CannoLocateSettings=Could not locate and open settings file:
{0}",
+ "# {0} - proxy id",
+ "# {1} - proxy host",
+ "ERR_CannotDisableProxy=Could not disable proxy id {0}, host {1}",
+ "# {0} - proxy id",
+ "# {1} - proxy host",
+ "ERR_CannotEnableProxy=Could not enable proxy id {0}, host {1}",
+ "# {0} - proxy host",
+ "ERR_CannotInsertProxy=Could not add proxy host {0}"
+ })
+ private FileObject generateNewSettingsFile(Path settingsPath) throws
IOException {
+ FileObject settingsDir = this.settingsDir != null ?
this.settingsDir : FileUtil.toFileObject(settingsPath.getParent().toFile());
+ if (settingsDir == null) {
+ Path dir = Files.createDirectory(settingsPath.getParent());
+ settingsDir = FileUtil.toFileObject(dir.toFile());
+ if (settingsDir == null) {
+ throw new
IOException(Bundle.ERROR_ConfigUpdateFailed(settingsPath.getParent()));
+ }
+ }
+ Map<String, Object> params = new HashMap<>();
+ params.put("proxyHost", proxyHost);
+ params.put("proxyPort", proxyPort);
+ return FileBuilder.createFromTemplate(
+
FileUtil.getConfigFile("Templates/Project/Maven2/settings.xml"), settingsDir,
settingsFileName,
+ params, FileBuilder.Mode.FAIL);
+ }
+
+ private File getMavenSettings() {
+ return new File(new File(System.getProperty("user.home"), ".m2"),
FILENAME_SETTINGS); // NOI18N
+ }
+
+ public BeanRunConfig configure(BeanRunConfig config) throws
IOException {
+ if (status != Status.OVERRIDE) {
+ return config;
+ }
+ // compute digest
+ String uniqueString = "";
+ try {
+ Path p = getMavenSettings().toPath();
+ if (!Files.exists(p)) {
+ uniqueString = SUFFIX_NEW_PROXY; // NOI18N
+ } else {
+ MessageDigest dg = MessageDigest.getInstance("SHA1");
+ byte[] bytes = dg.digest(Files.readAllBytes(p));
+ StringBuilder sb = new StringBuilder("-");
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append(Integer.toHexString(bytes[i] & 0xff));
+ }
+ uniqueString = sb.toString();
+ }
+ } catch (NoSuchAlgorithmException | IOException ex) {
+ return config;
+ }
+ settingsDir =
FileUtil.toFileObject(Places.getCacheSubdirectory("maven"));
+ if (settingsDir == null) {
+ return config;
+ }
+ if (proxyHost == null) {
+ uniqueString += SUFFIX_NONE_PROXY;
+ } else {
+ uniqueString += "-" + proxySpec.replace(":", "_");
+ }
+ settingsFileName = FILENAME_BASE_SETTINGS + uniqueString +
FILENAME_SETTINGS_EXT;
+ FileObject alreadyDone =
settingsDir.getFileObject(settingsFileName);
+ if (alreadyDone != null) {
+ config.setInternalProperty("NbIde.configOverride",
alreadyDone.getPath());
+ return config;
+ }
+
+ updateMavenProxy();
+ alreadyDone = settingsDir.getFileObject(settingsFileName);
+ config.setInternalProperty("NbIde.configOverride",
alreadyDone.getPath());
+ return config;
+ }
+
+ private void loadMavenTextInfo() throws IOException,
IllegalArgumentException {
+ Path settingsPath = getMavenSettings().toPath();
+ if (!Files.isReadable(settingsPath) &&
Files.isRegularFile(settingsPath)) {
+ generateNewSettingsFile(settingsPath);
+ return;
+ }
+ XppDelegate del = new
XppDelegate(EntityReplacementMap.defaultEntityReplacementMap);
+
+ try (FileInputStream in = new
FileInputStream(settingsPath.toFile())) {
+ del.setInput( ReaderFactory.newXmlReader( in ));
+ while (del.next() != XmlPullParser.END_DOCUMENT) {
+ // empty, just read
+ }
+ textInfo = del.textInfo;
+ } catch (XmlPullParserException ex) {
+ throw new IOException(ex);
+ }
+ }
+
+ private AtomicLockDocument adoc;
+ private LineDocument settingsLineDoc;
+ private EditorCookie settingsEditor;
+ private Lookup fileLookup;
+
+ private void loadSettingsContents() throws IOException {
+ if (settingsEditor != null) {
+ return;
+ }
+ Path settingsPath = getMavenSettings().toPath();
+ FileObject fo = FileUtil.toFileObject(settingsPath.toFile());
+ if (fo == null) {
+ return;
+ }
+ fileLookup = fo.getLookup();
+ EditorCookie cake = fileLookup.lookup(EditorCookie.class);
+ if (cake == null) {
+ throw new
IOException(Bundle.ERR_CannoLocateSettings(settingsPath));
+ }
+ StyledDocument doc = cake.openDocument();
+ settingsLineDoc = LineDocumentUtils.as(doc, LineDocument.class);
+ adoc = LineDocumentUtils.asRequired(doc, AtomicLockDocument.class);
+ if (settingsLineDoc == null) {
+ throw new
IOException(Bundle.ERR_CannoLocateSettings(settingsPath));
+ }
+ settingsEditor = cake;
+
+ loadMavenTextInfo();
+ }
+
+ private String padding(int num) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < num; i++) {
+ sb.append(' ');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Insert a new proxy:
+ * - if at least one 'proxy' block exists, insert the new definition
before all the other ones
+ * - if "proxies" element exists, but no proxy definition, insert
right after "proxies"
+ * - if no proxies element exists insert at the position of the first
element including the 'proxies' clause.
+ */
+ private void insertNewProxy() throws IOException {
+ int startColumn = 0;
+ LineAndColumn insertAt;
+
+ StringBuilder textBuilder = new StringBuilder();
+ if (textInfo.proxyTags.isEmpty()) {
+ if (textInfo.proxiesEndTag != null) {
+ // TODO: obey IDE formatting for xml files ?
+ insertAt = textInfo.proxiesEndTag;
+ startColumn = insertAt.column - 1 + 4;
+ // add 4 spaces, indent between <proxies> and nested
<proxy>, we're using padding of the </proxies> here.
+ textBuilder.append(" "); // NOI18N
+ } else {
+ insertAt = textInfo.firstTag;
+ startColumn = insertAt.column - 1;
+ }
+ } else {
+ insertAt =
textInfo.proxyTags.get(0).tags.get(TAG_PROXY).startTag;
+ startColumn = insertAt.column - 1;
+ }
+
+ // inserting at the position of first "proxy" element: no padding
in front, add padding at the end.
+ // inserting at the position of </proxies> closing tag: 4-space
padding at the start,
+ try (
+ InputStream inputStream =
getClass().getResourceAsStream(textInfo.proxiesEndTag != null ?
"proxy.template.xml" : "proxies.template.xml");
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(inputStream,
Charset.forName(StandardCharsets.UTF_8.name())))) {
+ String s;
+ boolean first = true;
+
+ while ((s = reader.readLine()) != null) {
+ if (!first) {
+ textBuilder.append(padding(startColumn));
+ }
+ first = false;
+ textBuilder.append(s).append("\n");
+ }
+ }
+ // add necessary padding
+ if (!textInfo.proxyTags.isEmpty()) {
+ textBuilder.append(padding(startColumn));
+ } else if (textInfo.proxiesEndTag != null) {
+ textBuilder.append(padding(textInfo.proxiesEndTag.column - 1));
+ } else {
+ textBuilder.append(padding(startColumn));
+ }
+ Map<String, String> args = new HashMap<>();
+ args.put(FMT_PROXY_HOST, proxyHost);
+ args.put(FMT_PROXY_PORT, Integer.toString(proxyPort));
+
+ MapFormat fmt = new MapFormat(args);
+ fmt.setLeftBrace("${");
+ String contents = fmt.format(textBuilder.toString());
+
+ IOException[] err = new IOException[1];
+ adoc.runAtomic(() -> {
+ try {
+ int lineOffset =
LineDocumentUtils.getLineStartFromIndex(settingsLineDoc, insertAt.line - 1);
+ int startOffset = lineOffset + insertAt.column - 1;
+
+ settingsLineDoc.insertString(startOffset, contents, null);
+ } catch (BadLocationException ex) {
+ err[0] = new
IOException(Bundle.ERR_CannotInsertProxy(proxyHost));
+ }
+ });
+
+ if (err[0] != null) {
+ throw err[0];
+ }
+ }
+ private static final String FMT_PROXY_PORT = "proxyPort"; // NOI18N
+ private static final String FMT_PROXY_HOST = "proxyHost"; // NOI18N
+
+ private void enableProxy(org.apache.maven.settings.Proxy p, int
proxyIndex, boolean enable) throws IOException {
+ String failureMsg = enable ?
Bundle.ERR_CannotEnableProxy(p.getId(), p.getHost()) :
Bundle.ERR_CannotDisableProxy(p.getId(), p.getHost());
+ if (textInfo.proxyTags.size() < proxyIndex) {
+ throw new IOException(failureMsg);
+ }
+ ProxyInfo pi = textInfo.proxyTags.get(proxyIndex);
+ TagInfo activeTag = pi.tags.get(TAG_NAME_ACTIVE);
+ IOException[] err = new IOException[1];
+
+ if (activeTag != null) {
+ adoc.runAtomic(() -> {
+ try {
+ int lineOffset =
LineDocumentUtils.getLineStartFromIndex(settingsLineDoc,
activeTag.startTag.line - 1);
+ int startOffset = lineOffset +
activeTag.startTag.column - 1;
+
+ int endLineOffset =
LineDocumentUtils.getLineStartFromIndex(settingsLineDoc, activeTag.endTag.line
- 1);
+ int endOffset = endLineOffset +
activeTag.endTag.column - 1;
+
+ String content = settingsLineDoc.getText(startOffset,
endOffset - startOffset);
+ int endStartTagPos = content.indexOf(">");
+ if (endStartTagPos == -1 || endStartTagPos >=
(endOffset - startOffset)) {
+ // cannot find end of start tag
+ err[0] = new
IOException(Bundle.ERR_CannotDisableProxy(p.getId(), p.getHost()));
+ return;
+ }
+ int from = startOffset + endStartTagPos + 1;
+ settingsLineDoc.remove(from, endOffset - from);
+ settingsLineDoc.insertString(from, enable ? "true" :
"false", null); // NOI18N
+ } catch (BadLocationException ex) {
+ err[0] = new IOException(failureMsg);
+ }
+ });
+ } else {
+ if (pi.firstTag == null) {
+ throw new
IOException(Bundle.ERR_CannotDisableProxy(p.getId(), p.getHost()));
+ }
+ String toInsert = padding(pi.firstTag.column) +
TAG_ACTIVE_START + enable + TAG_ACTIVE_END; // NOI18N
+ adoc.runAtomic(() -> {
+ try {
+ int lineOffset =
LineDocumentUtils.getLineStartFromIndex(settingsLineDoc, pi.firstTag.line - 1);
+ settingsLineDoc.insertString(lineOffset, toInsert,
null);
+ } catch (BadLocationException ex) {
+ err[0] = new IOException(failureMsg);
+ }
+ });
+ }
+
+ if (err[0] != null) {
+ throw err[0];
+ }
+ }
+
+ private void updateMavenProxy() throws IOException {
+ loadSettingsContents();
+
+ if (textInfo == null) {
+ if (settingsDir != null) {
+
generateNewSettingsFile(FileUtil.toFile(settingsDir).toPath().resolve(settingsFileName));
+ } else {
+ generateNewSettingsFile(getMavenSettings().toPath());
+ }
+ return;
+ }
+
+ // case 1: proxy should not be set, let's deactivate all the
proxies
+ int pos = 0;
+ if (proxyHost == null) {
+ for (org.apache.maven.settings.Proxy p :
mavenSettings.getProxies()) {
+ if (p.isActive()) {
+ enableProxy(p, pos, false);
+ }
+ pos++;
+ }
+ } else {
+
+ // case 2: there MAY be a matching proxy already defined, but
not active.
+ org.apache.maven.settings.Proxy existingProxy = null;
+
+ for (org.apache.maven.settings.Proxy p :
mavenSettings.getProxies()) {
+ if (proxyHost.equals(p.getHost())) {
+ if (!nonDefaultPort || proxyPort == p.getPort()) {
+ existingProxy = p;
+ break;
+ }
+ }
+ }
+
+ for (org.apache.maven.settings.Proxy p :
mavenSettings.getProxies()) {
+ if (p != existingProxy) {
+ enableProxy(p, pos, false);
+ }
+ pos++;
+ }
+ if (existingProxy != null) {
+ if (!existingProxy.isActive()) {
+ int proxyIndex =
mavenSettings.getProxies().indexOf(existingProxy);
+ if (proxyIndex == -1) {
+ throw new
IOException(Bundle.ERR_CannotEnableProxy(existingProxy.getId(),
existingProxy.getHost()));
+ }
+ enableProxy(existingProxy, proxyIndex, true);
+ }
+ } else {
+ insertNewProxy();
+ }
+ }
+
+ if (settingsEditor.isModified()) {
+ if (settingsDir != null) {
+ SaveAsCapable saa = fileLookup.lookup(SaveAsCapable.class);
+ if (saa != null) {
+ saa.saveAs(settingsDir, settingsFileName);
+ } else {
+ // FIXME: log a warning
+ }
+ } else {
+ File settings = getMavenSettings();
+ String base = settings + FILENAME_SUFFIX_OLD;
+ File f = new File(settings.getParentFile(), base);
+ int n = 1;
+ while (f.exists()) {
+ f = new File(settings.getParentFile(), base + "." +
n); // NOI18N
+ n++;
+ }
+ settings.renameTo(f);
+ settingsEditor.saveDocument();
+ }
+ }
+ }
+ }
+
+ @NbBundle.Messages({
+ "TITLE_MavenProxyMismatch=Possible Network Proxy Issue",
+ "# {0} - gradle proxy",
+ "MSG_ProxyMisconfiguredDirect=Maven 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=Maven 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=Maven 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 Maven configuration ? Choose
\"Override\" to apply detected proxy only to IDE operations.",
+ "MSG_AppendAskUpdate2=\nUpdate Maven 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 Maven user properties: {0}",
+ "# {0} - proxy specification",
+ "MSG_ProxySetTo=Maven Network proxy set to: {0}",
+ "MSG_ProxyCleared=Maven Network proxy removed",
+ })
+ /**
+ * 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;
+
+ Settings mavenSettings;
+
+ public CompletableFuture<ProxyResult> checkProxy() {
+ boolean supportOverride =
NetworkProxySettings.allowProxyOverride();
+ NetworkProxySettings action =
MavenSettings.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) {
+ 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;
+ }
+ }
+
+ switch (action) {
+ case IGNORE:
+ return
CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+
+ case NOTICE:
+
NotificationDisplayer.getDefault().notify(Bundle.TITLE_MavenProxyMismatch(),
+ ImageUtilities.loadImageIcon(ICON_MAVEN_PROJECT,
false),
+ userMessage, null,
NotificationDisplayer.Priority.NORMAL, NotificationDisplayer.Category.WARNING);
+ return
CompletableFuture.completedFuture(createResult(Status.CONTINUE));
+
+ case OVERRIDE:
+ return
CompletableFuture.completedFuture(createResult(Status.OVERRIDE));
+
+ case UPDATE:
+ try {
+ result = createResult(Status.RECONFIGURED);
+ result.updateMavenProxy();
+ } catch (IOException ex) {
+ result = createResult(ex);
+ }
+ return CompletableFuture.completedFuture(result);
+
+ 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_MavenProxyMismatch(),
+ 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(IOException ex) {
+ ProxyResult r = createResult(Status.ABORT);
+ r.exception = ex;
+ LOG.log(Level.WARNING, "Failed to configure proxy", ex);
+ return r;
+ }
+
+ 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, publicProxyNonDefaultPort >
0, mavenSettings);
+ if (keep) {
+ synchronized (this) {
+ acknowledgedResults.put(publicProxySpec, r);
+ }
+ }
+ return r;
+ }
+
+ @NbBundle.Messages({
+ "TITLE_ProxyUpdateFailed=Update of proxy configuration failed"
+ })
+ 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) {
+ try {
+ ProxyResult result = createResult(Status.RECONFIGURED);
+ result.updateMavenProxy();
+ } catch (IOException ex) {
+ return createResult(ex);
+ }
+ }
+ 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 void loadProjectProxy() {
+ mavenSettings = EmbedderFactory.getProjectEmbedder().getSettings();
+ org.apache.maven.settings.Proxy activeProxy =
mavenSettings.getActiveProxy();
+ if (activeProxy != null) {
+ proxyHost = activeProxy.getHost();
+ proxyPort = activeProxy.getPort();
+
+ if (proxyPort > 0) {
+ proxyAuthority = proxyHost + ":" + proxyPort;
+ }
+ } else {
+ proxyAuthority = null;
+ proxyHost = null;
+ proxyPort = -1;
+ }
+ }
+
+ }
+
+ static class LineAndColumn {
+ int offset = -1;
+ int line;
+ int column;
+
+ public LineAndColumn(int line, int column) {
+ this.line = line;
+ this.column = column;
+ }
+ }
+
+ static class TagInfo {
+ String tagName;
+ LineAndColumn startTag;
+ LineAndColumn content;
+ LineAndColumn endTag;
+
+ public TagInfo(String tagName, LineAndColumn start) {
+ this.tagName = tagName;
+ this.startTag = start;
+ }
+ }
+
+ static class ProxyInfo {
+ LineAndColumn firstTag;
+ Map<String, TagInfo> tags = new HashMap<>();
+ }
+
+ static class TextInfo {
+ LineAndColumn firstTag;
+ LineAndColumn firstProxyTag;
+ LineAndColumn proxiesEndTag;
+ List<ProxyInfo> proxyTags = new ArrayList<>();
+ }
+
+ static class XppDelegate extends MXParser {
+ private static final int UNKNOWN = 0;
+ private static final int PROXIES = 1;
+ private static final int PROXY = 2;
+ private static final int INSIDE_PROXY = 3;
+
+ private TextInfo textInfo = new TextInfo();
+ private LinkedList<TagInfo> tagStack = new LinkedList<>();
+ private ProxyInfo current;
+ private int state = UNKNOWN;
+
+ public XppDelegate(EntityReplacementMap entityReplacementMap) {
+ super(entityReplacementMap);
+ }
+
+ @Override
+ public int nextTag() throws XmlPullParserException, IOException {
+ int t = super.nextTag();
+ return processToken(t);
+ }
+
+ @Override
+ public int next() throws XmlPullParserException, IOException {
+ int t = super.next();
+ return processToken(t);
+ }
+
+ private LineAndColumn startPos() {
+ int ln = getLineNumber();
+ int col = getColumnNumber();
+ col -= (posEnd - posStart);
+ return new LineAndColumn(ln, col);
+ }
+
+ private LineAndColumn pos() {
+ return new LineAndColumn(getLineNumber(), getColumnNumber());
+ }
+
+ private int processToken(int token) {
+
+ switch (token) {
+ case XmlPullParser.END_TAG:
+ String en = getName();
+ if (state >= PROXY) {
+ if (TAG_PROXY.equals(en)) {
+ state = PROXIES;
+ current = null;
+ tagStack.clear();
+ break;
+ }
+ if (!tagStack.isEmpty()) {
+ tagStack.getLast().endTag = startPos();
+ tagStack.removeLast();
+ }
+ } else if (state == PROXIES && TAG_PROXIES.equals(en)) {
+ state = UNKNOWN;
+ textInfo.proxiesEndTag = startPos();
+ break;
+ }
+ break;
+ case XmlPullParser.START_TAG:
+ String n = getName();
+ if (state == UNKNOWN) {
+ if (TAG_PROXIES.equals(n)) {
+ state = 1;
+ } else if (!TAG_SETTINGS.equals(n) &&
textInfo.firstTag == null) {
+ textInfo.firstTag = startPos();
+ }
+ break;
+ }
+ if (state == PROXIES && TAG_PROXY.equals(n)) {
+ textInfo.firstProxyTag = pos();
+ state = INSIDE_PROXY;
+ current = new ProxyInfo();
+ textInfo.proxyTags.add(current);
+ // fall through, so proxy is recorded
+ }
+ if (state >= PROXY) {
+ TagInfo ti = new TagInfo(n, startPos());
+ if (current != null) {
+ if (current.firstTag == null) {
+ current.firstTag = ti.startTag;
+ }
+ current.tags.putIfAbsent(ti.tagName, ti);
+ }
+ tagStack.add(ti);
+ break;
+ }
+ }
+ return token;
+ }
+ }
+}
diff --git
a/java/maven/src/org/netbeans/modules/maven/execute/proxies.template.xml
b/java/maven/src/org/netbeans/modules/maven/execute/proxies.template.xml
new file mode 100644
index 0000000000..f1b2f3fcbe
--- /dev/null
+++ b/java/maven/src/org/netbeans/modules/maven/execute/proxies.template.xml
@@ -0,0 +1,9 @@
+<proxies>
+ <proxy>
+ <id>netbeans-default-proxy</id>
+ <active>true</active>
+ <protocol>http</protocol>
+ <host>${proxyHost}</host>
+ <port>${proxyPort}</port>
+ </proxy>
+</proxies>
diff --git
a/java/maven/src/org/netbeans/modules/maven/execute/proxy.template.xml
b/java/maven/src/org/netbeans/modules/maven/execute/proxy.template.xml
new file mode 100644
index 0000000000..486e867909
--- /dev/null
+++ b/java/maven/src/org/netbeans/modules/maven/execute/proxy.template.xml
@@ -0,0 +1,7 @@
+<proxy>
+ <id>netbeans-default-proxy</id>
+ <active>true</active>
+ <protocol>http</protocol>
+ <host>${proxyHost}</host>
+ <port>${proxyPort}</port>
+</proxy>
diff --git a/java/maven/src/org/netbeans/modules/maven/layer.xml
b/java/maven/src/org/netbeans/modules/maven/layer.xml
index b23427b7eb..a80ef96dd0 100644
--- a/java/maven/src/org/netbeans/modules/maven/layer.xml
+++ b/java/maven/src/org/netbeans/modules/maven/layer.xml
@@ -49,6 +49,11 @@
</folder>
</folder>
</folder>
+
+ <file name="settings.xml" url="settings.template.xml">
+ <attr name="javax.script.ScriptEngine"
stringvalue="freemarker"/>
+ <attr name="template.openFile" boolvalue="false"/>
+ </file>
</folder>
</folder>
</folder>
diff --git
a/java/maven/src/org/netbeans/modules/maven/options/Bundle.properties
b/java/maven/src/org/netbeans/modules/maven/options/Bundle.properties
index 5a430ebe69..9e300b945b 100644
--- a/java/maven/src/org/netbeans/modules/maven/options/Bundle.properties
+++ b/java/maven/src/org/netbeans/modules/maven/options/Bundle.properties
@@ -91,3 +91,4 @@ SettingsPanel.jLabel5.text=(NOT recommended, many features
will be limited as a
SettingsPanel.lblJdkHome.text=Default &JDK
SettingsPanel.comManageJdks.text=Mana&ge Java Platforms
SettingsPanel.cbPreferWrapper.text=Prefer Maven Wrapper that comes with project
+SettingsPanel.lbNetworkSettings.text=Network pro&xy:
diff --git
a/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
b/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
index 6fe2a7f1f7..bda5cbabf2 100644
--- a/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
+++ b/java/maven/src/org/netbeans/modules/maven/options/MavenSettings.java
@@ -85,6 +85,7 @@ public final class MavenSettings {
private static final String PROP_PLUGIN_POLICY = "pluginUpdatePolicy";
//NOI18N
private static final String PROP_FAILURE_BEHAVIOUR = "failureBehaviour";
//NOI18N
private static final String PROP_USE_REGISTRY = "usePluginRegistry";
//NOI18N
+ public static final String PROP_NETWORK_PROXY = "networkProxy";
private static final MavenSettings INSTANCE = new MavenSettings();
@@ -591,4 +592,16 @@ public final class MavenSettings {
}
}
+ 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/java/maven/src/org/netbeans/modules/maven/options/NetworkProxySettings.java
b/java/maven/src/org/netbeans/modules/maven/options/NetworkProxySettings.java
new file mode 100644
index 0000000000..5f19dbf7d9
--- /dev/null
+++
b/java/maven/src/org/netbeans/modules/maven/options/NetworkProxySettings.java
@@ -0,0 +1,76 @@
+/*
+ * 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.maven.options;
+
+import org.netbeans.modules.maven.api.execute.RunUtils;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author sdedic
+ */
[email protected]({
+ "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(Bundle.PROXY_IGNORE()),
+ /**
+ * Display a notice that proxy settings mismatch.
+ */
+ NOTICE(Bundle.PROXY_NOTICE()),
+ /**
+ * Update user's gradle.properties file.
+ */
+ UPDATE(Bundle.PROXY_UPDATE()),
+ /**
+ * Ask the user for confirmation.
+ */
+ ASK(Bundle.PROXY_ASK()),
+ /**
+ * Automatically override on execution, but do not change
gradle.properties.
+ */
+ OVERRIDE(Bundle.PROXY_OVERRIDE());
+
+ private String displayName;
+
+ public String toString() {
+ return displayName;
+ }
+
+ private static final String BRANDING_API_OVERRIDE_ENABLED =
"org.netbeans.modules.maven.api.execute.NetworkProxySettings.allowOverride"; //
NOI18N
+
+ private NetworkProxySettings(String dispName) {
+ this.displayName = dispName;
+ }
+
+ /**
+ * 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/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.form
b/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.form
index 49c6cfbcc3..151e2a9a6e 100644
--- a/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.form
+++ b/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.form
@@ -216,7 +216,7 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" pref="44" max="-2"
attributes="0"/>
- <EmptySpace pref="218" max="32767" attributes="0"/>
+ <EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -322,7 +322,7 @@
<Component id="cbDisableIndex" min="-2" max="-2"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel5" min="-2" max="-2"
attributes="0"/>
- <EmptySpace pref="290" max="32767" attributes="0"/>
+ <EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -422,7 +422,7 @@
<Component id="txtDirectory" alignment="3" min="-2"
max="-2" attributes="0"/>
<Component id="btnDirectory" alignment="3" min="-2"
max="-2" attributes="0"/>
</Group>
- <EmptySpace pref="180" max="32767" attributes="0"/>
+ <EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -481,12 +481,16 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
+ <Group type="102" alignment="0" attributes="0">
+ <EmptySpace min="-2" pref="119" max="-2" attributes="0"/>
+ <Component id="lblExternalVersion" max="32767"
attributes="0"/>
+ </Group>
<Group type="102" attributes="0">
- <EmptySpace min="-2" max="-2" attributes="0"/>
+ <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
- <Group type="102" attributes="0">
+ <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1"
attributes="0">
- <Group type="102" attributes="0">
+ <Group type="102" alignment="1"
attributes="0">
<Group type="103" groupAlignment="0"
attributes="0">
<Component id="cbAlwaysShow"
min="-2" max="-2" attributes="0"/>
<Component id="cbReuse"
alignment="0" min="-2" max="-2" attributes="0"/>
@@ -496,7 +500,7 @@
<EmptySpace max="-2"
attributes="0"/>
<Group type="103"
groupAlignment="0" attributes="0">
<Component
id="cbOutputTabShowConfig" min="-2" max="-2" attributes="0"/>
- <Group type="102"
attributes="0">
+ <Group type="102"
alignment="0" attributes="0">
<Component
id="rbOutputTabName" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2"
attributes="0"/>
<Component
id="rbOutputTabId" min="-2" max="-2" attributes="0"/>
@@ -510,17 +514,10 @@
</Group>
<Component id="cbSkipTests" alignment="0"
min="-2" max="-2" attributes="0"/>
</Group>
- <EmptySpace min="0" pref="55" max="32767"
attributes="0"/>
+ <EmptySpace min="-2" pref="58" max="-2"
attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0"
attributes="0">
- <Group type="102" alignment="0"
attributes="0">
- <Component id="lblOptions" min="-2"
max="-2" attributes="0"/>
- <EmptySpace max="-2" attributes="0"/>
- <Component id="txtOptions" max="32767"
attributes="0"/>
- <EmptySpace max="-2" attributes="0"/>
- <Component id="btnOptions" min="-2"
max="-2" attributes="0"/>
- </Group>
<Group type="102" alignment="0"
attributes="0">
<Group type="103" groupAlignment="0"
attributes="0">
<Component id="lblCommandLine"
min="-2" max="-2" attributes="0"/>
@@ -540,15 +537,24 @@
</Group>
</Group>
</Group>
+ <Group type="102" alignment="1"
attributes="0">
+ <Group type="103" groupAlignment="0"
max="-2" attributes="0">
+ <Component id="lblOptions"
max="32767" attributes="0"/>
+ <Component id="lbNetworkSettings"
max="32767" attributes="0"/>
+ </Group>
+ <EmptySpace max="-2" attributes="0"/>
+ <Group type="103" groupAlignment="0"
attributes="0">
+ <Component id="cbNetworkProxy"
max="32767" attributes="0"/>
+ <Component id="txtOptions"
max="32767" attributes="0"/>
+ </Group>
+ <EmptySpace max="-2" attributes="0"/>
+ <Component id="btnOptions" min="-2"
max="-2" attributes="0"/>
+ </Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
- <Group type="102" alignment="0" attributes="0">
- <EmptySpace min="-2" pref="119" max="-2" attributes="0"/>
- <Component id="lblExternalVersion" max="32767"
attributes="0"/>
- </Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
@@ -575,7 +581,15 @@
<Component id="txtOptions" alignment="3" min="-2"
max="-2" attributes="0"/>
<Component id="btnOptions" alignment="3" min="-2"
max="-2" attributes="0"/>
</Group>
- <EmptySpace type="unrelated" max="-2" attributes="0"/>
+ <EmptySpace max="-2" attributes="0"/>
+ <Group type="103" groupAlignment="1" attributes="0">
+ <Component id="cbNetworkProxy" alignment="1"
min="-2" max="-2" attributes="0"/>
+ <Group type="102" alignment="1" attributes="0">
+ <Component id="lbNetworkSettings" min="-2"
pref="16" max="-2" attributes="0"/>
+ <EmptySpace min="3" pref="3" max="-2"
attributes="0"/>
+ </Group>
+ </Group>
+ <EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="cbSkipTests" min="-2" max="-2"
attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="btnGoals" min="-2" max="-2"
attributes="0"/>
@@ -591,11 +605,11 @@
<Component id="rbOutputTabName" alignment="3"
min="-2" max="-2" attributes="0"/>
<Component id="rbOutputTabId" alignment="3" min="-2"
max="-2" attributes="0"/>
</Group>
- <EmptySpace max="-2" attributes="0"/>
+ <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="cbOutputTabShowConfig" min="-2" max="-2"
attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cbCollapseSuccessFolds" min="-2" max="-2"
attributes="0"/>
- <EmptySpace max="32767" attributes="0"/>
+ <EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -759,6 +773,26 @@
</Property>
</Properties>
</Component>
+ <Component class="javax.swing.JComboBox" name="cbNetworkProxy">
+ <Properties>
+ <Property name="model" type="javax.swing.ComboBoxModel"
editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+ <StringArray count="0"/>
+ </Property>
+ </Properties>
+ <AuxValues>
+ <AuxValue name="JavaCodeGenerator_TypeParameters"
type="java.lang.String" value="<NetworkProxySettings>"/>
+ </AuxValues>
+ </Component>
+ <Component class="javax.swing.JLabel" name="lbNetworkSettings">
+ <Properties>
+ <Property name="labelFor" type="java.awt.Component"
editor="org.netbeans.modules.form.ComponentChooserEditor">
+ <ComponentRef name="cbNetworkProxy"/>
+ </Property>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/maven/options/Bundle.properties"
key="SettingsPanel.lbNetworkSettings.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ </Properties>
+ </Component>
</SubComponents>
</Container>
</SubComponents>
diff --git
a/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.java
b/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.java
index fe3a3ecad7..b960bfcf38 100644
--- a/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.java
+++ b/java/maven/src/org/netbeans/modules/maven/options/SettingsPanel.java
@@ -229,6 +229,13 @@ public class SettingsPanel extends javax.swing.JPanel {
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
}
});
+
+ DefaultComboBoxModel mdl = new
DefaultComboBoxModel<>(NetworkProxySettings.values());
+ if (!NetworkProxySettings.allowProxyOverride()) {
+ mdl.removeElement(NetworkProxySettings.OVERRIDE);
+ }
+ cbNetworkProxy.setModel(mdl);
+ cbNetworkProxy.addActionListener(listener);
}
/** XXX update for M3 from {@link
org.apache.maven.cli.CLIManager#CLIManager} */
@@ -397,6 +404,8 @@ public class SettingsPanel extends javax.swing.JPanel {
comJdkHome = new javax.swing.JComboBox();
comManageJdks = new javax.swing.JButton();
cbPreferWrapper = new javax.swing.JCheckBox();
+ cbNetworkProxy = new javax.swing.JComboBox<>();
+ lbNetworkSettings = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
lstCategory = new javax.swing.JList();
lblCategory = new javax.swing.JLabel();
@@ -516,7 +525,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(comSource,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE,
44, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(218, Short.MAX_VALUE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
pnlCards.add(pnlDependencies, "dependencies");
@@ -576,7 +585,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(cbDisableIndex)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel5)
- .addContainerGap(290, Short.MAX_VALUE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
pnlCards.add(pnlIndex, "index");
@@ -632,7 +641,7 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(lblDirectory)
.addComponent(txtDirectory,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnDirectory))
- .addContainerGap(180, Short.MAX_VALUE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
pnlCards.add(plnExperimental, "experimental");
@@ -690,10 +699,16 @@ public class SettingsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(cbPreferWrapper,
org.openide.util.NbBundle.getMessage(SettingsPanel.class,
"SettingsPanel.cbPreferWrapper.text")); // NOI18N
+ lbNetworkSettings.setLabelFor(cbNetworkProxy);
+ org.openide.awt.Mnemonics.setLocalizedText(lbNetworkSettings,
org.openide.util.NbBundle.getMessage(SettingsPanel.class,
"SettingsPanel.lbNetworkSettings.text")); // NOI18N
+
javax.swing.GroupLayout pnlExecutionLayout = new
javax.swing.GroupLayout(pnlExecution);
pnlExecution.setLayout(pnlExecutionLayout);
pnlExecutionLayout.setHorizontalGroup(
pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnlExecutionLayout.createSequentialGroup()
+ .addGap(119, 119, 119)
+ .addComponent(lblExternalVersion,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
.addGroup(pnlExecutionLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -717,15 +732,9 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(btnGoals))
.addGap(18, 18, 18))
.addComponent(cbSkipTests,
javax.swing.GroupLayout.Alignment.LEADING))
- .addGap(0, 55, Short.MAX_VALUE))
+ .addGap(58, 58, 58))
.addGroup(pnlExecutionLayout.createSequentialGroup()
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-
.addGroup(pnlExecutionLayout.createSequentialGroup()
- .addComponent(lblOptions)
-
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(txtOptions)
-
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnOptions))
.addGroup(pnlExecutionLayout.createSequentialGroup()
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblCommandLine)
@@ -739,11 +748,18 @@ public class SettingsPanel extends javax.swing.JPanel {
.addGroup(pnlExecutionLayout.createSequentialGroup()
.addComponent(comJdkHome, 0,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(comManageJdks)))))
+ .addComponent(comManageJdks))))
+
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
pnlExecutionLayout.createSequentialGroup()
+
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
+ .addComponent(lblOptions,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)
+ .addComponent(lbNetworkSettings,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
+
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(cbNetworkProxy, 0,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(txtOptions))
+
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnOptions)))
.addContainerGap())))
- .addGroup(pnlExecutionLayout.createSequentialGroup()
- .addGap(119, 119, 119)
- .addComponent(lblExternalVersion,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
pnlExecutionLayout.setVerticalGroup(
pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -766,7 +782,13 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(lblOptions)
.addComponent(txtOptions,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnOptions))
-
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+
.addGroup(pnlExecutionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(cbNetworkProxy,
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(pnlExecutionLayout.createSequentialGroup()
+ .addComponent(lbNetworkSettings,
javax.swing.GroupLayout.PREFERRED_SIZE, 16,
javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(3, 3, 3)))
+ .addGap(18, 18, 18)
.addComponent(cbSkipTests)
.addGap(18, 18, 18)
.addComponent(btnGoals)
@@ -781,11 +803,11 @@ public class SettingsPanel extends javax.swing.JPanel {
.addComponent(lblOutputTab)
.addComponent(rbOutputTabName)
.addComponent(rbOutputTabId))
-
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGap(6, 6, 6)
.addComponent(cbOutputTabShowConfig)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(cbCollapseSuccessFolds)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
+ .addContainerGap())
);
pnlCards.add(pnlExecution, "execution");
@@ -935,6 +957,7 @@ public class SettingsPanel extends javax.swing.JPanel {
private javax.swing.JCheckBox cbAlwaysShow;
private javax.swing.JCheckBox cbCollapseSuccessFolds;
private javax.swing.JCheckBox cbDisableIndex;
+ private javax.swing.JComboBox<NetworkProxySettings> cbNetworkProxy;
private javax.swing.JCheckBox cbOutputTabShowConfig;
private javax.swing.JCheckBox cbPreferWrapper;
private javax.swing.JComboBox cbProjectNodeNameMode;
@@ -955,6 +978,7 @@ public class SettingsPanel extends javax.swing.JPanel {
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JLabel lbNetworkSettings;
private javax.swing.JLabel lblBinaries;
private javax.swing.JLabel lblCategory;
private javax.swing.JLabel lblCommandLine;
@@ -1157,6 +1181,8 @@ public class SettingsPanel extends javax.swing.JPanel {
}
}
+
cbNetworkProxy.setSelectedItem(MavenSettings.getDefault().getNetworkProxy());
+
changed = false; //#163955 - do not fire change events on load
}
@@ -1215,6 +1241,8 @@ public class SettingsPanel extends javax.swing.JPanel {
//a predefined pattern entry was selected
MavenSettings.getDefault().setProjectNodeNamePattern(cbProjectNodeNameMode.getSelectedItem().toString());
}
+
+
MavenSettings.getDefault().setNetworkProxy((NetworkProxySettings)cbNetworkProxy.getSelectedItem());
changed = false;
}
@@ -1283,6 +1311,7 @@ public class SettingsPanel extends javax.swing.JPanel {
isChanged |= (projectNodeNamePattern == null ?
!cbProjectNodeNameMode.getSelectedItem().toString().isEmpty() :
!projectNodeNamePattern.equals(cbProjectNodeNameMode.getSelectedItem().toString()));
}
}
+ isChanged |= MavenSettings.getDefault().getNetworkProxy() !=
cbNetworkProxy.getSelectedItem();
changed = isChanged;
}
diff --git
a/java/maven/src/org/netbeans/modules/maven/problems/SanityBuildAction.java
b/java/maven/src/org/netbeans/modules/maven/problems/SanityBuildAction.java
index dea2d9340f..c0f88d3347 100644
--- a/java/maven/src/org/netbeans/modules/maven/problems/SanityBuildAction.java
+++ b/java/maven/src/org/netbeans/modules/maven/problems/SanityBuildAction.java
@@ -21,6 +21,7 @@ package org.netbeans.modules.maven.problems;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -30,11 +31,14 @@ import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.api.execute.RunConfig.ReactorStyle;
import org.netbeans.modules.maven.api.execute.RunUtils;
import org.netbeans.modules.maven.execute.BeanRunConfig;
+import org.netbeans.modules.maven.execute.MavenProxySupport;
+import org.netbeans.modules.maven.execute.MavenProxySupport.ProxyResult;
import static org.netbeans.modules.maven.problems.Bundle.*;
import org.netbeans.spi.project.ui.ProjectProblemResolver;
import org.netbeans.spi.project.ui.ProjectProblemsProvider;
import org.openide.execution.ExecutorTask;
import org.openide.filesystems.FileUtil;
+import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
/**
@@ -67,6 +71,11 @@ public class SanityBuildAction implements
ProjectProblemResolver {
return this.pendingResult;
}
+ @NbBundle.Messages({
+ "ERR_SanityBuildCancalled=Sanity build cancelled",
+ "# {0} - message",
+ "ERR_ProxyUpdateFailed=Proxy setup failed: {0}"
+ })
@Override
public CompletableFuture<ProjectProblemsProvider.Result> resolve() {
CompletableFuture<ProjectProblemsProvider.Result> pr = pendingResult;
@@ -97,6 +106,27 @@ public class SanityBuildAction implements
ProjectProblemResolver {
String label =
build_label(nbproject.getProjectDirectory().getNameExt());
config.setExecutionName(label);
config.setTaskDisplayName(label);
+
+ MavenProxySupport mps =
nbproject.getLookup().lookup(MavenProxySupport.class);
+ if (mps != null) {
+ ProxyResult res;
+ try {
+ res = mps.checkProxySettings().get();
+ if (res.getStatus() ==
MavenProxySupport.Status.ABORT) {
+ ProjectProblemsProvider.Result r =
ProjectProblemsProvider.Result.create(ProjectProblemsProvider.Status.UNRESOLVED,
ERR_SanityBuildCancalled());
+ publicResult.complete(r);
+ return;
+ }
+ } catch (ExecutionException ex) {
+ ProjectProblemsProvider.Result r =
ProjectProblemsProvider.Result.create(ProjectProblemsProvider.Status.UNRESOLVED,
ERR_ProxyUpdateFailed(ex.getLocalizedMessage()));
+ publicResult.complete(r);
+ return;
+ } catch (InterruptedException ex) {
+ ProjectProblemsProvider.Result r =
ProjectProblemsProvider.Result.create(ProjectProblemsProvider.Status.UNRESOLVED,
ERR_SanityBuildCancalled());
+ publicResult.complete(r);
+ return;
+ }
+ }
LOG.log(Level.FINE, "Executing sanity build: goals = {0},
properties = {1}", new Object[] { config.getGoals(), config.getProperties() });
ExecutorTask et = RunUtils.run(config);
et.addTaskListener(t -> {
diff --git a/java/maven/src/org/netbeans/modules/maven/settings.template.xml
b/java/maven/src/org/netbeans/modules/maven/settings.template.xml
new file mode 100644
index 0000000000..84150288c3
--- /dev/null
+++ b/java/maven/src/org/netbeans/modules/maven/settings.template.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<settings>
+<#if proxyHost?? && proxyHost != "">
+ <proxies>
+ <!-- Proxy defined by NetBeans IDE -->
+ <proxy>
+ <id>netbeans-default-proxy</id>
+ <active>true</active>
+ <protocol>http</protocol>
+ <host>${proxyHost}</host>
+ <port>${proxyPort}</port>
+ <!-- Proxy exclusion list: separate by pipe-symbol, e.g.
127.0.0.8|localhost -->
+
<nonProxyHosts>localhost|127.0.0.0/8|localhost.localdomain|127.0.0.1|[::1]</nonProxyHosts>
+ </proxy>
+ </proxies>
+</#if>
+</settings>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists