Skip to content

Commit

Permalink
Project properties are now automatically saved whenever a property ch…
Browse files Browse the repository at this point in the history
…anges making its use less error prone.
  • Loading branch information
kelemen committed Aug 31, 2012
1 parent c13ea5c commit de69efb
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 46 deletions.
26 changes: 0 additions & 26 deletions src/org/netbeans/gradle/project/NbGradleProject.java
Expand Up @@ -19,8 +19,6 @@
import org.netbeans.gradle.project.model.GradleModelLoader;
import org.netbeans.gradle.project.model.ModelRetrievedListener;
import org.netbeans.gradle.project.model.NbGradleModel;
import org.netbeans.gradle.project.persistent.PropertiesPersister;
import org.netbeans.gradle.project.persistent.XmlPropertiesPersister;
import org.netbeans.gradle.project.properties.GradleCustomizer;
import org.netbeans.gradle.project.properties.ProjectProperties;
import org.netbeans.gradle.project.properties.ProjectPropertiesProxy;
Expand Down Expand Up @@ -60,21 +58,18 @@ public final class NbGradleProject implements Project {
private final AtomicBoolean hasModelBeenLoaded;
private final AtomicReference<NbGradleModel> currentModelRef;
private final ProjectProperties properties;
private final PropertiesPersister propertiesPersister;
private final ProjectInfoManager projectInfoManager;

private final AtomicReference<ProjectInfoRef> loadErrorRef;

private volatile boolean loadedAtLeastOnce;
private boolean saveOnLoad; // access from the EDT

public NbGradleProject(FileObject projectDir, ProjectState state) throws IOException {
this.projectDir = projectDir;
this.state = state;
this.lookupRef = new AtomicReference<Lookup>(null);
this.properties = new ProjectPropertiesProxy(this);
this.projectInfoManager = new ProjectInfoManager();
this.propertiesPersister = new XmlPropertiesPersister(this);

this.hasModelBeenLoaded = new AtomicBoolean(false);
this.loadErrorRef = new AtomicReference<ProjectInfoRef>(null);
Expand All @@ -83,7 +78,6 @@ public NbGradleProject(FileObject projectDir, ProjectState state) throws IOExcep

this.cpProvider = new GradleClassPathProvider(this);
this.loadedAtLeastOnce = false;
this.saveOnLoad = false;
}

private ProjectInfoRef getLoadErrorRef() {
Expand Down Expand Up @@ -124,19 +118,6 @@ private void reloadProject(boolean mayUseCache) {
loadProject(false, mayUseCache);
}

public void saveProperties() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("This method may only be called from the EDT.");
}

if (loadedAtLeastOnce) {
propertiesPersister.save(properties);
}
else {
saveOnLoad = true;
}
}

public boolean hasLoadedProject() {
return loadedAtLeastOnce;
}
Expand All @@ -146,13 +127,6 @@ private void onModelChange() {

try {
loadedAtLeastOnce = true;
if (saveOnLoad) {
saveOnLoad = false;
propertiesPersister.save(properties);
}
else {
propertiesPersister.load(properties);
}
modelChanges.fireChange();
} finally {
GradleCacheSourceForBinaryQuery.notifyCacheChange();
Expand Down
Expand Up @@ -5,6 +5,6 @@
public interface PropertiesPersister {
// These methods may only be called from the EDT

public void save(ProjectProperties properties);
public void load(ProjectProperties properties);
public void save(ProjectProperties properties, Runnable onDone);
public void load(ProjectProperties properties, Runnable onDone);
}
Expand Up @@ -46,20 +46,11 @@ public final class XmlPropertiesPersister implements PropertiesPersister {
private static final String PLATFORM_NODE = "target-platform";
private static final String SOURCE_LEVEL_NODE = "source-level";

private final NbGradleProject project;
private final File propertiesFile;

public XmlPropertiesPersister(NbGradleProject project) {
if (project == null) throw new NullPointerException("project");

this.project = project;
this.propertiesFile = null;
}

public XmlPropertiesPersister(File propertiesFile) {
if (propertiesFile == null) throw new NullPointerException("propertiesFile");

this.project = null;
this.propertiesFile = propertiesFile;
}

Expand All @@ -82,7 +73,7 @@ public static File getFileForProject(NbGradleProject project) {
}

private File getPropertyFile() throws IOException {
return propertiesFile != null ? propertiesFile : getFileForProject(project);
return propertiesFile;
}

private void checkEDT() {
Expand Down Expand Up @@ -204,7 +195,7 @@ private void saveDocument(Document document) throws TransformerException, IOExce
}

@Override
public void save(ProjectProperties properties) {
public void save(ProjectProperties properties, final Runnable onDone) {
checkEDT();

final Charset sourceEncoding = properties.getSourceEncoding().getValue();
Expand Down Expand Up @@ -249,13 +240,17 @@ public void run() {
LOGGER.log(Level.INFO, "Failed to save the properties.", ex);
} catch (TransformerException ex) {
LOGGER.log(Level.INFO, "Failed to save the properties.", ex);
} finally {
if (onDone != null) {
onDone.run();
}
}
}
});
}

@Override
public void load(final ProjectProperties properties) {
public void load(final ProjectProperties properties, final Runnable onDone) {
checkEDT();

// We must listen for changes, so that we do not overwrite properties
Expand Down Expand Up @@ -322,6 +317,10 @@ public void run() {
if (sourceEncoding != null && !sourceEncodingChanged.hasChanged()) {
properties.getSourceEncoding().setValue(sourceEncoding);
}

if (onDone != null) {
onDone.run();
}
}
});

Expand Down
@@ -0,0 +1,17 @@
package org.netbeans.gradle.project.properties;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collection;

public abstract class AbstractProjectProperties implements ProjectProperties {
public static final Charset DEFAULT_SOURCE_ENCODING = Charset.forName("UTF-8");

@Override
public final Collection<MutableProperty<?>> getAllProperties() {
return Arrays.<MutableProperty<?>>asList(
getPlatform(),
getSourceEncoding(),
getSourceLevel());
}
}
Expand Up @@ -32,7 +32,6 @@ public void showCustomizer() {
dlg.setVisible(true);
if (DialogDescriptor.OK_OPTION == dlgDescriptor.getValue()) {
panel.updateProperties(project.getProperties());
project.saveProperties();
}
}
}
Expand Up @@ -5,9 +5,7 @@
import org.netbeans.api.java.platform.JavaPlatform;
import org.openide.modules.SpecificationVersion;

public final class MemProjectProperties implements ProjectProperties {
public static final Charset DEFAULT_SOURCE_ENCODING = Charset.forName("UTF-8");

public final class MemProjectProperties extends AbstractProjectProperties {
private final MutableProperty<String> sourceLevel;
private final MutableProperty<JavaPlatform> platform;
private final MutableProperty<Charset> sourceEncoding;
Expand Down
@@ -1,10 +1,13 @@
package org.netbeans.gradle.project.properties;

import java.nio.charset.Charset;
import java.util.Collection;
import org.netbeans.api.java.platform.JavaPlatform;

public interface ProjectProperties {
public MutableProperty<String> getSourceLevel();
public MutableProperty<JavaPlatform> getPlatform();
public MutableProperty<Charset> getSourceEncoding();

public Collection<MutableProperty<?>> getAllProperties();
}
Expand Up @@ -2,9 +2,12 @@

import java.io.File;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.netbeans.gradle.project.persistent.PropertiesPersister;
import org.netbeans.gradle.project.persistent.XmlPropertiesPersister;

Expand All @@ -13,6 +16,40 @@ public final class ProjectPropertiesManager {
private static final Map<File, ProjectProperties> PROPERTIES
= new WeakValueHashMap<File, ProjectProperties>();

private static void saveIfRequired(
final AtomicBoolean saveQueued,
final ProjectProperties properties,
final PropertiesPersister persister) {

if (saveQueued.compareAndSet(false, true)) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
saveQueued.set(false);
persister.save(properties, null);
}
});
}
}

private static void setSaveOnChange(
final ProjectProperties properties,
final PropertiesPersister persister) {

final AtomicBoolean saveQueued = new AtomicBoolean(false);

ChangeListener saveIfRequiredTask = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
saveIfRequired(saveQueued, properties, persister);
}
};

for (MutableProperty<?> property: properties.getAllProperties()) {
property.addChangeListener(saveIfRequiredTask);
}
}

public static ProjectProperties getProperties(File propertiesFile) {
if (propertiesFile == null) throw new NullPointerException("propertiesFile");

Expand All @@ -32,7 +69,12 @@ public static ProjectProperties getProperties(File propertiesFile) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
persister.load(newProperties);
persister.load(newProperties, new Runnable() {
@Override
public void run() {
setSaveOnChange(newProperties, persister);
}
});
}
});

Expand Down
Expand Up @@ -17,7 +17,7 @@
import org.netbeans.gradle.project.persistent.XmlPropertiesPersister;
import org.openide.util.ChangeSupport;

public final class ProjectPropertiesProxy implements ProjectProperties {
public final class ProjectPropertiesProxy extends AbstractProjectProperties {
private static final Logger LOGGER = Logger.getLogger(ProjectPropertiesProxy.class.getName());

private final NbGradleProject project;
Expand Down

0 comments on commit de69efb

Please sign in to comment.