package org.netbeans.gradle.project.properties.global; import java.io.IOException; import java.nio.file.Path; import java.util.Collection; import java.util.Collections; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jtrim.event.ListenerRef; import org.jtrim.property.MutableProperty; import org.netbeans.gradle.project.api.config.ProfileKey; import org.netbeans.gradle.project.api.config.PropertyDef; import org.netbeans.gradle.project.properties.ConfigSaveOptions; import org.netbeans.gradle.project.properties.DomElementKey; import org.netbeans.gradle.project.properties.GenericProfileSettings; import org.netbeans.gradle.project.properties.LoadableSingleProfileSettingsEx; import org.netbeans.gradle.project.properties.MultiProfileProperties; import org.netbeans.gradle.project.properties.ProfileFileDef; import org.netbeans.gradle.project.properties.ProfileLocationProvider; import org.netbeans.gradle.project.properties.SingleProfileSettingsEx; import org.netbeans.gradle.project.util.LazyValue; import org.netbeans.gradle.project.util.NbFileUtils; import org.netbeans.gradle.project.util.NbSupplier; import org.w3c.dom.Element; final class GlobalProfileSettings implements LoadableSingleProfileSettingsEx { private static final GlobalProfileSettings DEFAULT = new GlobalProfileSettings(); private final GenericProfileSettings impl; private GlobalProfileSettings() { this.impl = new GenericProfileSettings(new GlobalProfileLocationProvider()); } public static GlobalProfileSettings getInstance() { GlobalProfileSettings result = DEFAULT; LegacyUtils.moveLegacyConfig(result.impl); return result; } @Override public Collection<DomElementKey> getAuxConfigKeys() { return impl.getAuxConfigKeys(); } @Override public Element getAuxConfigValue(DomElementKey key) { return impl.getAuxConfigValue(key); } @Override public boolean setAuxConfigValue(DomElementKey key, Element value) { return impl.setAuxConfigValue(key, value); } @Override public void saveAndWait() { impl.saveAndWait(); } @Override public ProfileKey getKey() { return impl.getKey(); } @Override public <ValueType> MutableProperty<ValueType> getProperty(PropertyDef<?, ValueType> propertyDef) { return impl.getProperty(propertyDef); } @Override public void ensureLoadedAndWait() { impl.ensureLoadedAndWait(); } @Override public void ensureLoaded() { impl.ensureLoaded(); } @Override public ListenerRef notifyWhenLoaded(Runnable runnable) { return impl.notifyWhenLoaded(runnable); } private static final class GlobalProfileLocationProvider implements ProfileLocationProvider { private static final String BASE_FILE_NAME = ProfileKey.GLOBAL_PROFILE.getFileName() + ".xml"; private final LazyValue<Path> outputPathRef; public GlobalProfileLocationProvider() { this.outputPathRef = new LazyValue<>(new NbSupplier<Path>() { @Override public Path get() { return GlobalSettingsUtils.tryGetGlobalConfigPath(BASE_FILE_NAME); } }); } @Override public ProfileKey getKey() { return ProfileKey.GLOBAL_PROFILE; } @Override public Path tryGetOutputPath() throws IOException { return outputPathRef.get(); } @Override public ProfileFileDef tryGetOutputDef() throws IOException { Path output = tryGetOutputPath(); if (output == null) { return null; } ConfigSaveOptions saveOptions = getSaveOptions(output); return new ProfileFileDef(output, saveOptions); } private static ConfigSaveOptions getSaveOptions(Path output) { String lineSeparator = NbFileUtils.tryGetLineSeparatorForTextFile(output); return new ConfigSaveOptions(lineSeparator); } } private static class LegacyUtils { private static final Lock MOVE_LOCK = new ReentrantLock(); private static volatile boolean moveInProgress = false; private static volatile boolean moved = false; public static void moveLegacyConfig(GenericProfileSettings settings) { if (moved) { return; } String movedToNewConfig = NbGlobalPreference.DEFAULT.get("movedToNewConfig"); if ("true".equalsIgnoreCase(movedToNewConfig)) { MOVE_LOCK.lock(); try { moved = true; } finally { MOVE_LOCK.unlock(); } return; } settings.ensureLoadedAndWait(); MultiProfileProperties activeSettings = new MultiProfileProperties(Collections.<SingleProfileSettingsEx>singletonList(settings)); CommonGlobalSettings globalSettings = new CommonGlobalSettings(activeSettings); MOVE_LOCK.lock(); try { if (!moved && !moveInProgress) { try { // moveInProgress prevents infinite recursion and possible cycles in initialization moveInProgress = true; moveToNewSettings(globalSettings); } finally { moveInProgress = false; } moved = true; } } finally { MOVE_LOCK.unlock(); } NbGlobalPreference.DEFAULT.put("movedToNewConfig", "true"); } @SuppressWarnings("deprecation") private static void moveToNewSettings(CommonGlobalSettings globalSettings) { LegacyGlobalGradleSettings.moveDefaultToNewSettings(globalSettings); } } }