blob: b91fc58ef3d6f623dfced5f424a6edb7801a1773 [file] [log] [blame]
/*
* 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 java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import org.apache.maven.execution.MavenExecutionRequest;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.netbeans.api.annotations.common.CheckForNull;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.embedder.EmbedderFactory;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
import org.openide.util.NbPreferences;
import org.openide.util.WeakSet;
/**
* a netbeans settings for global options that cannot be put into the settings file.
* @author mkleint
*/
public final class MavenSettings {
//same prop constant in Embedderfactory.java
private static final String PROP_DEFAULT_OPTIONS = "defaultOptions"; // NOI18N
private static final String PROP_SOURCE_DOWNLOAD = "sourceDownload"; //NOI18N
private static final String PROP_JAVADOC_DOWNLOAD = "javadocDownload"; //NOI18N
private static final String PROP_BINARY_DOWNLOAD = "binaryDownload"; //NOI18N
private static final String PROP_LAST_ARCHETYPE_GROUPID = "lastArchetypeGroupId"; //NOI18N
private static final String PROP_LAST_ARCHETYPE_VERSION = "lastArchetypeVersion"; //NOI18N
private static final String PROP_SKIP_TESTS = "skipTests"; //NOI18N
private static final String PROP_MAVEN_RUNTIMES = "mavenRuntimes"; //NOI18N
public static final String PROP_PROJECTNODE_NAME_PATTERN = "project.displayName"; //NOI18N
private static final String PROP_ALWAYS_OUTPUT = "alwaysShowOutput";
private static final String PROP_SHOW_LOGGING_LEVEL = "showLoggingLevel"; //NOI18N
private static final String PROP_REUSE_OUTPUT = "reuseOutputTabs";
private static final String PROP_COLLAPSE_FOLDS = "collapseSuccessFolds";
private static final String PROP_OUTPUT_TAB_CONFIG = "showConfigInOutputTab";
private static final String PROP_OUTPUT_TAB_NAME = "showOutputTabAs";
private static final String PROP_EXPERIMENTAL_USE_BEST_MAVEN = "useBestMaven";
private static final String PROP_EXPERIMENTAL_USE_ALTERNATE_LOCATION = "useBestMavenAltLocation";
private static final String PROP_EXPERIMENTAL_ALTERNATE_LOCATION = "bestMavenAltLocation";
private static final String PROP_VM_OPTIONS_WRAP = "vmOptionsWrap";
private static final String PROP_DEFAULT_JDK = "defaultJdk";
//these are from former versions (6.5) and are here only for conversion
private static final String PROP_DEBUG = "showDebug"; // NOI18N
private static final String PROP_ERRORS = "showErrors"; //NOI18N
private static final String PROP_CHECKSUM_POLICY = "checksumPolicy"; //NOI18N
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
private static final MavenSettings INSTANCE = new MavenSettings();
private final Set<PropertyChangeListener> listeners = new WeakSet<>();
public static MavenSettings getDefault() {
return INSTANCE;
}
public boolean isInteractive() {
return !hasOption("--batch", "-B"); //NOI18N
}
public Boolean isOffline() {
if (hasOption("--offline", "-o")) { //NOI18N
return Boolean.TRUE;
}
return null;
}
public boolean isShowDebug() {
return hasOption("--debug", "-X"); //NOI18N
}
public boolean isShowErrors() {
return hasOption("--errors", "-e"); //NOI18N
}
public boolean isUpdateSnapshots() {
return hasOption("--update-snapshots", "-U"); //NOI18N
}
private boolean hasOption(String longName, String shortName) {
String defOpts = getDefaultOptions();
if (defOpts != null) {
try {
String[] strs = CommandLineUtils.translateCommandline(defOpts);
for (String s : strs) {
s = s.trim();
if (s.startsWith(shortName) || s.startsWith(longName)) {
return true;
}
}
} catch (Exception ex) {
Logger.getLogger(MavenSettings.class.getName()).log(Level.FINE, "Error parsing global options:{0}", defOpts);
//will check for contains of -X be enough?
return defOpts.contains(longName) || defOpts.contains(shortName);
}
}
return false;
}
private Preferences getPreferences() {
return NbPreferences.forModule(MavenSettings.class);
}
private String putProperty(String key, String value) {
String retval = getProperty(key);
if (value != null) {
getPreferences().put(key, value);
} else {
getPreferences().remove(key);
}
return retval;
}
private String getProperty(String key) {
return getPreferences().get(key, null);
}
private MavenSettings() {
//import from older versions
String defOpts = getPreferences().get(PROP_DEFAULT_OPTIONS, null);
if (defOpts == null) {
defOpts = "";
//only when not already set by user or by previous import
String debug = getPreferences().get(PROP_DEBUG, null);
if (debug != null) {
boolean val = Boolean.parseBoolean(debug);
if (val) {
defOpts = defOpts + " --debug";//NOI18N
}
getPreferences().remove(PROP_DEBUG);
}
String error = getPreferences().get(PROP_ERRORS, null);
if (error != null) {
boolean val = Boolean.parseBoolean(error);
if (val) {
defOpts = defOpts + " --errors"; //NOI18N
}
getPreferences().remove(PROP_ERRORS);
}
String checksum = getPreferences().get(PROP_CHECKSUM_POLICY, null);
if (checksum != null) {
if (MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals(checksum)) {
defOpts = defOpts + " --strict-checksums";//NOI18N
} else if (MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals(checksum)) {
defOpts = defOpts + " --lax-checksums";//NOI18N
}
getPreferences().remove(PROP_CHECKSUM_POLICY);
}
String fail = getPreferences().get(PROP_FAILURE_BEHAVIOUR, null);
if (fail != null) {
if (MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(fail)) {
defOpts = defOpts + " --fail-never";//NOI18N
} else if (MavenExecutionRequest.REACTOR_FAIL_FAST.equals(fail)) {
defOpts = defOpts + " --fail-fast";//NOI18N
} else if (MavenExecutionRequest.REACTOR_FAIL_AT_END.equals(fail)) {
defOpts = defOpts + " --fail-at-end";//NOI18N
}
getPreferences().remove(PROP_FAILURE_BEHAVIOUR);
}
String pluginUpdate = getPreferences().get(PROP_PLUGIN_POLICY, null);
if (pluginUpdate != null) {
if (Boolean.parseBoolean(pluginUpdate)) {
defOpts = defOpts + " --check-plugin-updates";//NOI18N
} else {
defOpts = defOpts + " --no-plugin-updates";//NOI18N
}
getPreferences().remove(PROP_PLUGIN_POLICY);
}
String registry = getPreferences().get(PROP_USE_REGISTRY, null);
if (registry != null) {
if (!Boolean.parseBoolean(registry)) {
defOpts = defOpts + " --no-plugin-registry";//NOI18N
}
getPreferences().remove(PROP_USE_REGISTRY);
}
setDefaultOptions(defOpts);
try {
getPreferences().flush();
} catch (BackingStoreException ex) {
// Exceptions.printStackTrace(ex);
}
}
}
public String getDefaultOptions() {
return getPreferences().get(PROP_DEFAULT_OPTIONS, ""); //NOI18N
}
public void setDefaultOptions(String options) {
String old = getDefaultOptions();
putProperty(PROP_DEFAULT_OPTIONS, options);
if (!old.equals(options)) {
//options could contain -Dkey=value, then the MavenEmbedder instances need to be reloaded
EmbedderFactory.resetCachedEmbedders();
}
}
public boolean isVMOptionsWrap() {
return getPreferences().getBoolean(PROP_VM_OPTIONS_WRAP, true);
}
public void setVMOptionsWrap(boolean b) {
getPreferences().putBoolean(PROP_VM_OPTIONS_WRAP, b);
}
public String getDefaultJdk() {
return getPreferences().get(PROP_DEFAULT_JDK, "");
}
public void setDefaultJdk(String jdk) {
getPreferences().put(PROP_DEFAULT_JDK, jdk);
PropertyChangeListener[] arr;
synchronized (listeners) {
arr = listeners.toArray(new PropertyChangeListener[0]);
}
for (PropertyChangeListener l : arr) {
l.propertyChange(new PropertyChangeEvent(this, PROP_DEFAULT_JDK, null, jdk));
}
}
public String getLastArchetypeGroupId() {
return getPreferences().get(PROP_LAST_ARCHETYPE_GROUPID, Boolean.getBoolean("netbeans.full.hack") ? "test" : "com.mycompany"); //NOI18N
}
public void setLastArchetypeGroupId(String groupId) {
putProperty(PROP_LAST_ARCHETYPE_GROUPID, groupId);
}
public boolean isSkipTests() {
return getPreferences().getBoolean(PROP_SKIP_TESTS, false);
}
public void setSkipTests(boolean skipped) {
getPreferences().putBoolean(PROP_SKIP_TESTS, skipped);
}
public boolean isAlwaysShowOutput() {
return getPreferences().getBoolean(PROP_ALWAYS_OUTPUT, true);
}
public void setAlwaysShowOutput(boolean show) {
getPreferences().putBoolean(PROP_ALWAYS_OUTPUT, show);
}
public boolean isShowLoggingLevel() {
return getPreferences().getBoolean(PROP_SHOW_LOGGING_LEVEL, false);
}
public void setShowLoggingLevel(boolean show) {
getPreferences().putBoolean(PROP_SHOW_LOGGING_LEVEL, show);
}
public boolean isReuseOutputTabs() {
return getPreferences().getBoolean(PROP_REUSE_OUTPUT, true);
}
public void setReuseOutputTabs(boolean reuse) {
getPreferences().putBoolean(PROP_REUSE_OUTPUT, reuse);
}
public String getLastArchetypeVersion() {
return getPreferences().get(PROP_LAST_ARCHETYPE_VERSION, "1.0-SNAPSHOT"); //NOI18N
}
public void setLastArchetypeVersion(String version) {
putProperty(PROP_LAST_ARCHETYPE_VERSION, version); //NOI18N
}
public void setProjectNodeNamePattern(String pattern) {
if (null == pattern) {
getPreferences().remove(PROP_PROJECTNODE_NAME_PATTERN);
} else {
putProperty(PROP_PROJECTNODE_NAME_PATTERN, pattern);
}
}
public String getProjectNodeNamePattern() {
return getPreferences().get(PROP_PROJECTNODE_NAME_PATTERN, null); //NOI18N
}
public boolean isUseBestMaven() {
return getPreferences().getBoolean(PROP_EXPERIMENTAL_USE_BEST_MAVEN, false);
}
public void setUseBestMaven(boolean bestMaven) {
getPreferences().putBoolean(PROP_EXPERIMENTAL_USE_BEST_MAVEN, bestMaven);
}
public boolean isUseBestMavenAltLocation() {
return getPreferences().getBoolean(PROP_EXPERIMENTAL_USE_ALTERNATE_LOCATION, false);
}
public void setUseBestMavenAltLocation(boolean bestMavenAltLocation) {
getPreferences().putBoolean(PROP_EXPERIMENTAL_USE_ALTERNATE_LOCATION, bestMavenAltLocation);
}
public void setBestMavenAltLocation(String location) {
if (null == location) {
getPreferences().remove(PROP_EXPERIMENTAL_ALTERNATE_LOCATION);
} else {
putProperty(PROP_EXPERIMENTAL_ALTERNATE_LOCATION, location);
}
}
public String getBestMavenAltLocation() {
return getPreferences().get(PROP_EXPERIMENTAL_ALTERNATE_LOCATION, null); //NOI18N
}
public boolean isCollapseSuccessFolds() {
return getPreferences().getBoolean(PROP_COLLAPSE_FOLDS, false);
}
public void setCollapseSuccessFolds(boolean collapse) {
getPreferences().putBoolean(PROP_COLLAPSE_FOLDS, collapse);
}
public void setOutputTabShowConfig(boolean selected) {
getPreferences().putBoolean(PROP_OUTPUT_TAB_CONFIG, selected);
}
public boolean isOutputTabShowConfig() {
return getPreferences().getBoolean(PROP_OUTPUT_TAB_CONFIG, false);
}
public OutputTabName getOutputTabName() {
String val = getPreferences().get(PROP_OUTPUT_TAB_NAME, OutputTabName.PROJECT_NAME.name());
try {
return OutputTabName.valueOf(val);
} catch (IllegalArgumentException ex) {
return OutputTabName.PROJECT_NAME;
}
}
public void setOutputTabName(OutputTabName ds) {
if (ds != null) {
getPreferences().put(PROP_OUTPUT_TAB_NAME, ds.name());
} else {
getPreferences().remove(PROP_OUTPUT_TAB_NAME);
}
}
public void addWeakPropertyChangeListener(PropertyChangeListener l) {
synchronized (listeners) {
listeners.add(l);
}
}
public static enum OutputTabName {
PROJECT_NAME,
PROJECT_ID
}
public static enum DownloadStrategy {
NEVER,
FIRST_OPEN,
EVERY_OPEN
}
public DownloadStrategy getSourceDownloadStrategy() {
String val = getPreferences().get(PROP_SOURCE_DOWNLOAD, DownloadStrategy.NEVER.name());
try {
return DownloadStrategy.valueOf(val);
} catch (IllegalArgumentException ex) {
return DownloadStrategy.NEVER;
}
}
public void setSourceDownloadStrategy(DownloadStrategy ds) {
if (ds != null) {
getPreferences().put(PROP_SOURCE_DOWNLOAD, ds.name());
} else {
getPreferences().remove(PROP_SOURCE_DOWNLOAD);
}
}
public DownloadStrategy getJavadocDownloadStrategy() {
String val = getPreferences().get(PROP_JAVADOC_DOWNLOAD, DownloadStrategy.NEVER.name());
try {
return DownloadStrategy.valueOf(val);
} catch (IllegalArgumentException ex) {
return DownloadStrategy.NEVER;
}
}
public void setJavadocDownloadStrategy(DownloadStrategy ds) {
if (ds != null) {
getPreferences().put(PROP_JAVADOC_DOWNLOAD, ds.name());
} else {
getPreferences().remove(PROP_JAVADOC_DOWNLOAD);
}
}
public DownloadStrategy getBinaryDownloadStrategy() {
String val = getPreferences().get(PROP_BINARY_DOWNLOAD, DownloadStrategy.NEVER.name());
try {
return DownloadStrategy.valueOf(val);
} catch (IllegalArgumentException ex) {
return DownloadStrategy.NEVER;
}
}
public void setBinaryDownloadStrategy(DownloadStrategy ds) {
if (ds != null) {
getPreferences().put(PROP_BINARY_DOWNLOAD, ds.name());
} else {
getPreferences().remove(PROP_BINARY_DOWNLOAD);
}
}
public static @CheckForNull String getCommandLineMavenVersion() {
return getCommandLineMavenVersion(EmbedderFactory.getMavenHome());
}
public static @CheckForNull String getCommandLineMavenVersion(File mavenHome) {
File[] jars = new File(mavenHome, "lib").listFiles(new FilenameFilter() { // NOI18N
public @Override boolean accept(File dir, String name) {
return name.endsWith(".jar"); // NOI18N
}
});
if (jars == null) {
return null;
}
for (File jar : jars) {
try {
// Prefer to use this rather than raw ZipFile since URLMapper since ArchiveURLMapper will cache JARs:
FileObject entry = URLMapper.findFileObject(new URL(FileUtil.urlForArchiveOrDir(jar), "META-INF/maven/org.apache.maven/maven-core/pom.properties")); // NOI18N
if (entry != null) {
InputStream is = entry.getInputStream();
try {
Properties properties = new Properties();
properties.load(is);
return properties.getProperty("version"); // NOI18N
} finally {
is.close();
}
}
} catch (IOException x) {
// ignore for now
}
}
return null;
}
private static List<String> searchMavenRuntimes(String[] paths, boolean stopOnFirstValid) {
List<String> runtimes = new ArrayList<String>();
for (String path : paths) {
File file = new File(path);
path = FileUtil.normalizeFile(file).getAbsolutePath();
String version = getCommandLineMavenVersion(file);
if (version != null) {
runtimes.add(path);
if (stopOnFirstValid) {
break;
}
}
}
return runtimes;
}
/**
* Searches for Maven Runtimes by the environment settings and returns the first valid one.
*
* <p>It searches in this order:
* <ul>
* <li>MAVEN_HOME</li>
* <li>M2_HOME</li>
* <li>PATH</li></ul>
* </p>
* <p>Only the first appereance will be appended.</p>
*
* @returns the default external Maven runtime on the path.
*/
public static String getDefaultExternalMavenRuntime() {
String paths = System.getenv("PATH"); // NOI18N
String mavenHome = System.getenv("MAVEN_HOME"); // NOI18N
String m2Home = System.getenv("M2_HOME"); // NOI18N
List<String> mavenEnvDirs = new ArrayList<String>();
if (mavenHome != null) {
mavenEnvDirs.add(mavenHome);
}
if (m2Home != null) {
mavenEnvDirs.add(m2Home);
}
if (paths != null) {
for (String path : paths.split(File.pathSeparator)) {
if (!path.endsWith("bin")) { // NOI18N
continue;
}
if(path.equals("/bin") || path.equals("bin")) {
mavenEnvDirs.add(path);
} else {
mavenEnvDirs.add(path.substring(0,
path.length() - "bin".length() - File.pathSeparator.length()));
}
}
}
List<String> runtimes = searchMavenRuntimes(mavenEnvDirs.toArray(new String[0]), true);
return !runtimes.isEmpty() ? runtimes.get(0) : null;
}
public List<String> getUserDefinedMavenRuntimes() {
List<String> runtimes = new ArrayList<String>();
String defaultRuntimePath = getDefaultExternalMavenRuntime();
String runtimesPref = getPreferences().get(PROP_MAVEN_RUNTIMES, null);
if (runtimesPref != null) {
for (String runtimePath : runtimesPref.split(File.pathSeparator)) {
if (!"".equals(runtimePath) && !runtimePath.equals(defaultRuntimePath)) {
runtimes.add(runtimePath);
}
}
}
return Collections.unmodifiableList(runtimes);
}
public void setMavenRuntimes(List<String> runtimes) {
if (runtimes == null) {
getPreferences().remove(PROP_MAVEN_RUNTIMES);
} else {
String runtimesPref = "";
for (String path : runtimes) {
runtimesPref += path + File.pathSeparator;
}
if (runtimesPref.endsWith(File.pathSeparator)) {
runtimesPref = runtimesPref.substring(0, runtimesPref.length() - 1);
}
putProperty(PROP_MAVEN_RUNTIMES, runtimesPref);
}
}
}