package org.netbeans.gradle.project.properties; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import org.jtrim.event.ListenerRef; import org.jtrim.property.MutableProperty; import org.jtrim.property.PropertyFactory; import org.jtrim.property.PropertySource; import org.jtrim.property.ValueConverter; import org.jtrim.swing.concurrent.SwingTaskExecutor; import org.jtrim.utils.ExceptionHelper; import org.netbeans.gradle.model.util.CollectionUtils; import org.netbeans.gradle.project.NbGradleProject; import org.netbeans.gradle.project.api.config.ActiveSettingsQuery; import org.netbeans.gradle.project.api.config.CustomProfileQuery; import org.netbeans.gradle.project.api.config.ProfileDef; import org.netbeans.gradle.project.api.config.ProfileKey; import org.netbeans.gradle.project.model.NbGradleModel; import org.netbeans.gradle.project.model.ProjectModelChangeListener; import org.netbeans.gradle.project.util.NbFunction; import org.netbeans.spi.project.ProjectConfigurationProvider; import org.netbeans.spi.project.ui.CustomizerProvider; public final class NbGradleSingleProjectConfigProvider implements ProjectConfigurationProvider<NbGradleConfiguration>, ProjectModelChangeListener { private final NbGradleProject project; private final AtomicReference<Path> currentRootDir; private final MutableProperty<NbGradleConfigProvider> commonConfigRef; private final PropertySource<NbGradleConfiguration> activeConfig; private final PropertySource<Collection<NbGradleConfiguration>> configs; private final ActiveSettingsQueryEx activeSettingsQuery; private final SwingPropertyChangeForwarder propertyChangeForwarder; private volatile Set<NbGradleConfiguration> extensionProfiles; private NbGradleSingleProjectConfigProvider( NbGradleProject project, NbGradleConfigProvider multiProjectProvider) { ExceptionHelper.checkNotNullArgument(project, "project"); ExceptionHelper.checkNotNullArgument(multiProjectProvider, "multiProjectProvider"); this.project = project; this.currentRootDir = new AtomicReference<>(multiProjectProvider.getRootDirectory()); this.commonConfigRef = PropertyFactory.memPropertyConcurrent(multiProjectProvider, SwingTaskExecutor.getStrictExecutor(false)); this.extensionProfiles = Collections.emptySet(); this.activeConfig = NbProperties.propertyOfProperty(commonConfigRef, new NbFunction<NbGradleConfigProvider, PropertySource<NbGradleConfiguration>>() { @Override public PropertySource<NbGradleConfiguration> apply(NbGradleConfigProvider arg) { return arg.activeConfiguration(); } }); this.configs = NbProperties.propertyOfProperty(commonConfigRef, new NbFunction<NbGradleConfigProvider, PropertySource<Collection<NbGradleConfiguration>>>() { @Override public PropertySource<Collection<NbGradleConfiguration>> apply(NbGradleConfigProvider arg) { return arg.configurations(); } }); PropertySource<ActiveSettingsQueryEx> activeSettingsQueryRef; activeSettingsQueryRef = PropertyFactory.convert(commonConfigRef, new ValueConverter<NbGradleConfigProvider, ActiveSettingsQueryEx>() { @Override public ActiveSettingsQueryEx convert(NbGradleConfigProvider arg) { return arg.getActiveSettingsQuery(); } }); this.activeSettingsQuery = new ActiveSettingsQueryExProxy(activeSettingsQueryRef); this.propertyChangeForwarder = createPropertyChanges(); } private SwingPropertyChangeForwarder createPropertyChanges() { SwingPropertyChangeForwarder.Builder result = new SwingPropertyChangeForwarder.Builder(); result.addProperty(PROP_CONFIGURATION_ACTIVE, activeConfig, this); result.addPropertyNoValue(PROP_CONFIGURATIONS, configs, this); return result.create(); } public static NbGradleSingleProjectConfigProvider create(Path rootDir, NbGradleProject project) { return new NbGradleSingleProjectConfigProvider( project, NbGradleConfigProvider.getConfigProvider(rootDir)); } public NbGradleCommonProperties getCommonProperties(ActiveSettingsQuery settings) { return new NbGradleCommonProperties(project, settings); } public ProfileSettingsKey getProjectProfileKey(ProfileKey profileKey) { return ProjectProfileSettingsKey.getForProject(project, profileKey); } private NbGradleConfigProvider getCommonConfig() { return commonConfigRef.getValue(); } public ActiveSettingsQueryEx getActiveSettingsQuery() { return activeSettingsQuery; } public ProfileSettingsContainer getProfileSettingsContainer() { return getCommonConfig().getProfileSettingsContainer(); } private void updateExtensionProfiles() { List<ProfileDef> customProfileDefs = new ArrayList<>(); for (CustomProfileQuery profileQuery: project.getLookup().lookupAll(CustomProfileQuery.class)) { for (ProfileDef profileDef: profileQuery.getCustomProfiles()) { customProfileDefs.add(profileDef); } } Set<NbGradleConfiguration> customProfiles = CollectionUtils.newHashSet(customProfileDefs.size()); for (ProfileDef profileDef: customProfileDefs) { customProfiles.add(new NbGradleConfiguration(profileDef)); } extensionProfiles = Collections.unmodifiableSet(customProfiles); propertyChangeForwarder.firePropertyChange(new PropertyChangeEvent(this, PROP_CONFIGURATIONS, null, null)); } @Override public void onModelChanged() { NbGradleModel currentModel = project.currentModel().getValue(); Path newRootDir = currentModel.getSettingsDir(); Path prevRootDir = currentRootDir.getAndSet(newRootDir); if (!Objects.equals(prevRootDir, newRootDir)) { commonConfigRef.setValue(NbGradleConfigProvider.getConfigProvider(newRootDir)); } updateExtensionProfiles(); } @Override public Collection<NbGradleConfiguration> getConfigurations() { Collection<NbGradleConfiguration> commonProfiles = getCommonConfig().getConfigurations(); Collection<NbGradleConfiguration> currentExtProfiles = extensionProfiles; List<NbGradleConfiguration> result = new ArrayList<>(commonProfiles.size() + currentExtProfiles.size()); result.addAll(commonProfiles); result.addAll(currentExtProfiles); NbGradleConfiguration.sortProfiles(result); return result; } @Override public NbGradleConfiguration getActiveConfiguration() { NbGradleConfigProvider commonConfig = getCommonConfig(); NbGradleConfiguration config = commonConfig.getActiveConfiguration(); if (!extensionProfiles.contains(config) && !commonConfig.getConfigurations().contains(config)) { return NbGradleConfiguration.DEFAULT_CONFIG; } return config; } @Override public void setActiveConfiguration(NbGradleConfiguration configuration) throws IOException { getCommonConfig().setActiveConfiguration(configuration); } private CustomizerProvider getCustomizerProvider() { return project.getCustomizer(); } @Override public boolean hasCustomizer() { return getCustomizerProvider() != null; } @Override public void customize() { CustomizerProvider customizerProvider = getCustomizerProvider(); if (customizerProvider != null) { customizerProvider.showCustomizer(); } } @Override public boolean configurationsAffectAction(String command) { return getCommonConfig().configurationsAffectAction(command); } @Override public void addPropertyChangeListener(PropertyChangeListener lst) { propertyChangeForwarder.addPropertyChangeListener(lst); } @Override public void removePropertyChangeListener(PropertyChangeListener lst) { propertyChangeForwarder.removePropertyChangeListener(lst); } public void removeConfiguration(NbGradleConfiguration config) { getCommonConfig().removeConfiguration(config); } public void addConfiguration(NbGradleConfiguration config) { getCommonConfig().addConfiguration(config); } public ListenerRef addActiveConfigChangeListener(Runnable listener) { return activeConfig.addChangeListener(listener); } }