package org.netbeans.gradle.project.properties.global; import java.io.File; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import org.jtrim.collections.CollectionsEx; import org.jtrim.event.ListenerRef; import org.jtrim.property.MutableProperty; import org.jtrim.utils.ExceptionHelper; import org.netbeans.api.java.platform.JavaPlatform; import org.netbeans.api.java.platform.JavaPlatformManager; import org.netbeans.gradle.project.api.config.ActiveSettingsQuery; import org.netbeans.gradle.project.api.config.PropertyReference; import org.netbeans.gradle.project.java.JavaExtensionDef; import org.netbeans.gradle.project.java.properties.DebugMode; import org.netbeans.gradle.project.java.properties.JavaProjectProperties; import org.netbeans.gradle.project.properties.ExtensionActiveSettingsQuery; import org.netbeans.gradle.project.properties.GradleLocationDef; import org.netbeans.gradle.project.properties.ModelLoadingStrategy; import org.netbeans.gradle.project.properties.NbGradleCommonProperties; import org.netbeans.gradle.project.properties.PlatformSelectionMode; import org.netbeans.gradle.project.properties.ScriptPlatform; import org.netbeans.gradle.project.util.StringUtils; import org.netbeans.gradle.project.view.DisplayableTaskVariable; import org.openide.filesystems.FileObject; import org.openide.util.Utilities; /** * @deprecated Use {@link CommonGlobalSettings} instead. */ @Deprecated final class LegacyGlobalGradleSettings { private static final Logger LOGGER = Logger.getLogger(LegacyGlobalGradleSettings.class.getName()); private static final LegacyGlobalGradleSettings DEFAULT = new LegacyGlobalGradleSettings(null); private static final BasicPreference PREFERENCE = NbGlobalPreference.DEFAULT; private final StringBasedProperty<GradleLocationDef> gradleLocation; private final StringBasedProperty<File> gradleUserHomeDir; private final StringBasedProperty<List<String>> gradleArgs; private final StringBasedProperty<List<String>> gradleJvmArgs; private final StringBasedProperty<JavaPlatform> gradleJdk; private final StringBasedProperty<Boolean> skipTests; private final StringBasedProperty<Boolean> skipCheck; private final StringBasedProperty<Integer> projectCacheSize; private final StringBasedProperty<Boolean> alwaysClearOutput; private final StringBasedProperty<SelfMaintainedTasks> selfMaintainedTasks; private final StringBasedProperty<Boolean> mayRelyOnJavaOfScript; private final StringBasedProperty<ModelLoadingStrategy> modelLoadingStrategy; private final StringBasedProperty<Integer> gradleDaemonTimeoutSec; private final StringBasedProperty<Boolean> compileOnSave; private final StringBasedProperty<PlatformOrder> platformPreferenceOrder; private final StringBasedProperty<String> displayNamePattern; private final StringBasedProperty<JavaSourcesDisplayMode> javaSourcesDisplayMode; private final StringBasedProperty<Boolean> replaceLfOnStdIn; private final StringBasedProperty<DebugMode> debugMode; private final StringBasedProperty<Boolean> loadRootProjectFirst; private final StringBasedProperty<Boolean> detectProjectDependenciesByJarName; public LegacyGlobalGradleSettings(String namespace) { // "gradle-home" is probably not the best name but it must remain so // for backward compatibility reason. gradleLocation = new GlobalProperty<>( withNS(namespace, "gradle-home"), GradleLocationConverter.INSTANCE); gradleUserHomeDir = new GlobalProperty<>( withNS(namespace, "gradle-user-home"), FileConverter.INSTANCE); gradleArgs = new GlobalProperty<>( withNS(namespace, "gradle-args"), StringToStringListConverter.INSTANCE); gradleJvmArgs = new GlobalProperty<>( withNS(namespace, "gradle-jvm-args"), StringToStringListConverter.INSTANCE); gradleJdk = new GlobalProperty<>( withNS(namespace, "gradle-jdk"), JavaPlaformConverter.INSTANCE); skipTests = new GlobalProperty<>( withNS(namespace, "skip-tests"), new BooleanConverter(false)); skipCheck = new GlobalProperty<>( withNS(namespace, "skip-check"), new BooleanConverter(false)); projectCacheSize = new GlobalProperty<>( withNS(namespace, "project-cache-size"), new IntegerConverter(1, Integer.MAX_VALUE, 100)); alwaysClearOutput = new GlobalProperty<>( withNS(namespace, "always-clear-output"), new BooleanConverter(false)); selfMaintainedTasks = new GlobalProperty<>( withNS(namespace, "omit-init-script"), new EnumConverter<>(SelfMaintainedTasks.FALSE)); mayRelyOnJavaOfScript = new GlobalProperty<>( withNS(namespace, "rely-on-java-of-script"), new BooleanConverter(false)); modelLoadingStrategy = new GlobalProperty<>( withNS(namespace, "model-load-strategy"), new EnumConverter<>(ModelLoadingStrategy.NEWEST_POSSIBLE)); gradleDaemonTimeoutSec = new GlobalProperty<>( withNS(namespace, "gradle-daemon-timeout-sec"), new IntegerConverter(1, Integer.MAX_VALUE, null)); compileOnSave = new GlobalProperty<>( withNS(namespace, "compile-on-save"), new BooleanConverter(false)); platformPreferenceOrder = new GlobalProperty<>( withNS(namespace, "platform-pref-order"), PlatformOrderConverter.INSTANCE ); displayNamePattern = new GlobalProperty<>( withNS(namespace, "display-name-pattern"), new StringConverter(DisplayableTaskVariable.PROJECT_NAME.getScriptReplaceConstant()) ); javaSourcesDisplayMode = new GlobalProperty<>( withNS(namespace, "java-sources-display-mode"), new EnumConverter<>(JavaSourcesDisplayMode.DEFAULT_MODE)); replaceLfOnStdIn = new GlobalProperty<>( withNS(namespace, "replace-lf-on-stdin"), new BooleanConverter(true)); debugMode = new GlobalProperty<>( withNS(namespace, "debug-mode"), new EnumConverter<>(DebugMode.DEBUGGER_ATTACHES)); loadRootProjectFirst = new GlobalProperty<>( withNS(namespace, "load-root-first"), new BooleanConverter(true)); detectProjectDependenciesByJarName = new GlobalProperty<>( withNS(namespace, "detect-project-dep-by-jar-name"), new BooleanConverter(false)); } private <T> void moveToNewSettings( StringBasedProperty<? extends T> oldProperty, PropertyReference<? super T> newProperty) { if (oldProperty.getValueAsString() != null) { newProperty.setValue(oldProperty.getValue()); } } private void moveJdkToNewSettings( StringBasedProperty<? extends JavaPlatform> oldProperty, PropertyReference<? super ScriptPlatform> newProperty) { if (oldProperty.getValueAsString() != null) { JavaPlatform platform = oldProperty.getValue(); newProperty.setValue(platform != null ? new ScriptPlatform(platform, PlatformSelectionMode.BY_LOCATION) : null); } } public static void moveDefaultToNewSettings(CommonGlobalSettings newSettings) { DEFAULT.moveToNewSettings(newSettings); } private void moveToNewSettings(CommonGlobalSettings newSettings) { moveToNewSettings(gradleLocation, newSettings.gradleLocation()); moveToNewSettings(gradleUserHomeDir, newSettings.gradleUserHomeDir()); moveToNewSettings(gradleArgs, newSettings.gradleArgs()); moveToNewSettings(gradleJvmArgs, newSettings.gradleJvmArgs()); moveJdkToNewSettings(gradleJdk, newSettings.defaultJdk()); moveToNewSettings(skipTests, newSettings.skipTests()); moveToNewSettings(skipCheck, newSettings.skipCheck()); moveToNewSettings(projectCacheSize, newSettings.projectCacheSize()); moveToNewSettings(alwaysClearOutput, newSettings.alwaysClearOutput()); moveToNewSettings(selfMaintainedTasks, newSettings.selfMaintainedTasks()); moveToNewSettings(mayRelyOnJavaOfScript, newSettings.mayRelyOnJavaOfScript()); moveToNewSettings(modelLoadingStrategy, newSettings.modelLoadingStrategy()); moveToNewSettings(gradleDaemonTimeoutSec, newSettings.gradleDaemonTimeoutSec()); moveToNewSettings(compileOnSave, newSettings.compileOnSave()); moveToNewSettings(platformPreferenceOrder, newSettings.platformPreferenceOrder()); moveToNewSettings(displayNamePattern, NbGradleCommonProperties.displayNamePattern(newSettings.getActiveSettingsQuery())); moveToNewSettings(replaceLfOnStdIn, newSettings.replaceLfOnStdIn()); moveToNewSettings(loadRootProjectFirst, newSettings.loadRootProjectFirst()); moveToNewSettings(detectProjectDependenciesByJarName, newSettings.detectProjectDependenciesByJarName()); ActiveSettingsQuery javaExtQuery = new ExtensionActiveSettingsQuery( newSettings.getActiveSettingsQuery(), JavaExtensionDef.EXTENSION_NAME); moveToNewSettings(debugMode, JavaProjectProperties.debugMode(javaExtQuery)); moveToNewSettings(javaSourcesDisplayMode, JavaProjectProperties.javaSourcesDisplayMode(javaExtQuery)); } private static String withNS(String namespace, String name) { return namespace == null ? name : namespace + "." + name; } MutableProperty<List<String>> gradleJvmArgs() { return gradleJvmArgs; } private static List<String> stringToStringList(String strValue) { if (strValue == null || strValue.isEmpty()) { return null; } return Collections.unmodifiableList(Arrays.asList(StringUtils.splitLines(strValue))); } private static String stringListToString(Collection<String> value) { if (value == null || value.isEmpty()) { return null; } int length = value.size() - 1; for (String line: value) { length += line.length(); } StringBuilder result = new StringBuilder(length); Iterator<String> valueItr = value.iterator(); // valueItr.next() should succeed since the list is not empty. result.append(valueItr.next()); while (valueItr.hasNext()) { result.append('\n'); result.append(valueItr.next()); } return result.toString(); } private enum PlatformOrderConverter implements ValueConverter<PlatformOrder> { INSTANCE; @Override public PlatformOrder toValue(String strValue) { return strValue != null ? fromStringFormat(strValue) : PlatformOrder.DEFAULT_ORDER; } @Override public String toString(PlatformOrder value) { return value != null ? toStringFormat(value) : null; } public static PlatformOrder fromStringFormat(String strValue) { List<String> platformIds = stringToStringList(strValue); if (platformIds == null) { return null; } return PlatformOrder.fromPlatformIds(platformIds); } public String toStringFormat(PlatformOrder order) { return stringListToString(order.getPlatformIds()); } } private enum StringToStringListConverter implements ValueConverter<List<String>> { INSTANCE; @Override public List<String> toValue(String strValue) { return stringToStringList(strValue); } @Override public String toString(List<String> value) { return stringListToString(value); } } private static class IntegerConverter implements ValueConverter<Integer> { private final Integer defaultValue; private final int minValue; private final int maxValue; public IntegerConverter(int minValue, int maxValue, Integer defaultValue) { if (minValue > maxValue) { throw new IllegalArgumentException("minValue > maxValue"); } if (defaultValue != null && (minValue > defaultValue || maxValue < defaultValue)) { throw new IllegalArgumentException("minValue > defaultValue || maxValue < defaultValue"); } this.minValue = minValue; this.maxValue = maxValue; this.defaultValue = defaultValue; } @Override public Integer toValue(String strValue) { if (strValue == null || strValue.isEmpty()) { return defaultValue; } try { int result = Integer.parseInt(strValue); if (result < minValue) result = minValue; else if (result > maxValue) result = maxValue; return result; } catch (NumberFormatException ex) { LOGGER.log(Level.WARNING, "Invalid integer in the settings: {0}", strValue); } return defaultValue; } @Override public String toString(Integer value) { if (Utilities.compareObjects(value, defaultValue)) { return null; } return value != null ? value.toString() : null; } } private static class EnumConverter<EnumType extends Enum<EnumType>> implements ValueConverter<EnumType> { private final EnumType defaultValue; private final Class<EnumType> enumClass; private final Map<String, EnumType> byNameValues; @SuppressWarnings("unchecked") public EnumConverter(EnumType defaultValue) { this.defaultValue = defaultValue; this.enumClass = (Class<EnumType>)defaultValue.getClass(); EnumType[] allValues = enumClass.getEnumConstants(); byNameValues = CollectionsEx.newHashMap(allValues.length); for (EnumType value: allValues) { byNameValues.put(value.name().toUpperCase(Locale.ROOT), value); } } @Override public EnumType toValue(String strValue) { if (strValue == null || strValue.isEmpty()) { return defaultValue; } EnumType result = byNameValues.get(strValue.toUpperCase(Locale.ROOT)); if (result == null) { LOGGER.log(Level.INFO, "Illegal enum value for config: {0} expected an instance of {1}", new Object[]{strValue, enumClass.getSimpleName()}); result = defaultValue; } return result; } @Override public String toString(EnumType value) { if (value == defaultValue || value == null) { return null; } return value.name(); } } private static class BooleanConverter implements ValueConverter<Boolean> { private static final String TRUE_STR = Boolean.TRUE.toString(); private static final String FALSE_STR = Boolean.FALSE.toString(); private final Boolean defaultValue; public BooleanConverter(Boolean defaultValue) { this.defaultValue = defaultValue; } @Override public Boolean toValue(String strValue) { if (strValue == null || strValue.isEmpty()) { return defaultValue; } if (TRUE_STR.equals(strValue)) return true; if (FALSE_STR.equals(strValue)) return false; return defaultValue; } @Override public String toString(Boolean value) { if (Objects.equals(value, defaultValue)) { return null; } return value != null ? value.toString() : null; } } private enum JavaPlaformConverter implements ValueConverter<JavaPlatform> { INSTANCE; @Override public JavaPlatform toValue(String strValue) { if (strValue == null || strValue.isEmpty()) { return JavaPlatform.getDefault(); } JavaPlatform[] platforms = JavaPlatformManager.getDefault().getInstalledPlatforms(); for (JavaPlatform platform: platforms) { if (strValue.equals(toString(platform))) { return platform; } } return JavaPlatform.getDefault(); } @Override public String toString(JavaPlatform value) { if (value == null) { return null; } StringBuilder result = new StringBuilder(1024); for (FileObject installFolder: value.getInstallFolders()) { String path = installFolder.getPath(); if (result.length() > 0) { result.append(";"); } result.append(path); } return result.toString(); } } private enum FileConverter implements ValueConverter<File> { INSTANCE; @Override public File toValue(String strValue) { if (strValue == null || strValue.isEmpty()) { return null; } return new File(strValue); } @Override public String toString(File value) { return value != null ? value.getPath() : null; } } private static final class StringConverter implements ValueConverter<String> { private final String defaultValue; public StringConverter(String defaultValue) { this.defaultValue = defaultValue; } @Override public String toValue(String strValue) { return strValue != null ? strValue : defaultValue; } @Override public String toString(String value) { return Objects.equals(value, defaultValue) ? null : value; } } private enum GradleLocationConverter implements ValueConverter<GradleLocationDef> { INSTANCE; @Override public GradleLocationDef toValue(String strValue) { if (strValue == null) { return GradleLocationDef.DEFAULT; } return GradleLocationDef.parseFromString(strValue); } @Override public String toString(GradleLocationDef value) { if (value == null) { return null; } if (Objects.equals(value, GradleLocationDef.DEFAULT)) { return null; } else { return value.toStringFormat(); } } } private static interface ValueConverter<ValueType> { public ValueType toValue(String strValue); public String toString(ValueType value); } private static class GlobalProperty<ValueType> implements StringBasedProperty<ValueType> { private final String settingsName; private final ValueConverter<ValueType> converter; public GlobalProperty(String settingsName, ValueConverter<ValueType> converter) { ExceptionHelper.checkNotNullArgument(settingsName, "settingsName"); ExceptionHelper.checkNotNullArgument(converter, "converter"); this.settingsName = settingsName; this.converter = converter; } @Override public void setValue(ValueType value) { String strValue = converter.toString(value); setValueFromString(strValue); } @Override public ValueType getValue() { return converter.toValue(getValueAsString()); } @Override public ListenerRef addChangeListener(final Runnable listener) { ExceptionHelper.checkNotNullArgument(listener, "listener"); return PREFERENCE.addPreferenceChangeListener(new PreferenceChangeListener() { @Override public void preferenceChange(PreferenceChangeEvent evt) { if (GlobalProperty.this.settingsName.equals(evt.getKey())) { listener.run(); } } }); } @Override public void setValueFromString(String strValue) { if (strValue != null) { PREFERENCE.put(settingsName, strValue); } else { PREFERENCE.remove(settingsName); } } @Override public String getValueAsString() { return PREFERENCE.get(settingsName); } } private interface StringBasedProperty<ValueType> extends MutableProperty<ValueType> { public void setValueFromString(String strValue); public String getValueAsString(); } private LegacyGlobalGradleSettings() { throw new AssertionError(); } }