[412185] Automatic saving of project/repo properties does not work
https://bugs.eclipse.org/bugs/show_bug.cgi?id=412185
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectImpl.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectImpl.java
index 3ba80e3..e18867e 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectImpl.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectImpl.java
@@ -52,6 +52,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -327,11 +328,6 @@
}
/** {@inheritDoc} */
- public ECPContainer getContext() {
- return this;
- }
-
- /** {@inheritDoc} */
public boolean canDelete() {
return true;
}
@@ -601,7 +597,13 @@
return project;
}
- /** {@inheritDoc} */
+ @Override
+ protected void propertiesChanged(Collection<Entry<String, String>> oldProperties,
+ Collection<Entry<String, String>> newProperties) {
+ ECPProjectManagerImpl.INSTANCE.storeElement(this);
+ }
+
+ @Deprecated
public void saveProperties() {
ECPProjectManagerImpl.INSTANCE.storeElement(this);
}
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectManagerImpl.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectManagerImpl.java
index e6c2c90..2481eaf 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectManagerImpl.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPProjectManagerImpl.java
@@ -171,11 +171,6 @@
return (Collection) projects;
}
- @Override
- public void storeElement(InternalProject project) {
- super.storeElement(project);
- }
-
/**
* This is called by projects to notify observers about project changes.
*
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryImpl.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryImpl.java
index 4c65222..3dc6d0c 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryImpl.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryImpl.java
@@ -13,6 +13,8 @@
package org.eclipse.emf.ecp.internal.core;
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.ECPProvider;
import org.eclipse.emf.ecp.core.ECPRepository;
@@ -24,10 +26,10 @@
import org.eclipse.emf.ecp.spi.core.InternalProject;
import org.eclipse.emf.ecp.spi.core.InternalProvider;
import org.eclipse.emf.ecp.spi.core.InternalProvider.LifecycleEvent;
+import org.eclipse.emf.ecp.spi.core.InternalRepository;
import org.eclipse.emf.ecp.spi.core.util.DisposeException;
import org.eclipse.emf.ecp.spi.core.util.ECPDisposable;
import org.eclipse.emf.ecp.spi.core.util.ECPDisposable.DisposeListener;
-import org.eclipse.emf.ecp.spi.core.InternalRepository;
import org.eclipse.core.runtime.Platform;
@@ -38,6 +40,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map.Entry;
/**
* This Class describes a repository.
@@ -46,6 +49,7 @@
* @author Eugen Neufeld
*/
public final class ECPRepositoryImpl extends PropertiesElement implements InternalRepository, DisposeListener {
+ @ExcludeFromDump
private final Disposable disposable = new Disposable(this) {
@Override
protected void doDispose() {
@@ -262,4 +266,10 @@
// TODO Consider to cache the result
return result.toArray(new InternalProject[result.size()]);
}
+
+ @Override
+ protected void propertiesChanged(Collection<Entry<String, String>> oldProperties,
+ Collection<Entry<String, String>> newProperties) {
+ ECPRepositoryManagerImpl.INSTANCE.storeElement(this);
+ }
}
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryManagerImpl.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryManagerImpl.java
index 6b8ca44..1372407 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryManagerImpl.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/ECPRepositoryManagerImpl.java
@@ -14,6 +14,7 @@
package org.eclipse.emf.ecp.internal.core;
import org.eclipse.net4j.util.AdapterUtil;
+import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.emf.ecp.core.ECPProvider;
import org.eclipse.emf.ecp.core.ECPRepository;
@@ -23,12 +24,14 @@
import org.eclipse.emf.ecp.core.util.ECPRepositoryAware;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.core.util.observer.ECPObserver;
+import org.eclipse.emf.ecp.core.util.observer.ECPPropertiesObserver;
import org.eclipse.emf.ecp.core.util.observer.ECPProvidersChangedObserver;
import org.eclipse.emf.ecp.core.util.observer.ECPRepositoriesChangedObserver;
import org.eclipse.emf.ecp.core.util.observer.ECPRepositoryContentChangedObserver;
import org.eclipse.emf.ecp.internal.core.util.ExtensionParser;
import org.eclipse.emf.ecp.internal.core.util.ExtensionParser.ExtensionDescriptor;
import org.eclipse.emf.ecp.internal.core.util.InternalUtil;
+import org.eclipse.emf.ecp.internal.core.util.Properties;
import org.eclipse.emf.ecp.internal.core.util.PropertiesStore;
import org.eclipse.emf.ecp.spi.core.InternalProvider;
import org.eclipse.emf.ecp.spi.core.InternalProvider.LifecycleEvent;
@@ -37,11 +40,19 @@
import org.eclipse.core.runtime.IConfigurationElement;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInput;
+import java.io.ObjectInputStream;
import java.io.ObjectOutput;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -57,6 +68,11 @@
*/
public static ECPRepositoryManagerImpl INSTANCE;
+ /**
+ * The file extension that is used for dynamic properties of statically declared repositories.
+ */
+ private static final String DYNAMIC_PROPERTIES_EXTENSION = ".dynamic_properties";
+
private final RepositoryParser extensionParser = new RepositoryParser();
public ECPRepositoryManagerImpl() {
@@ -138,6 +154,19 @@
}
@Override
+ protected File getFile(InternalRepository element) {
+ if (element instanceof RepositoryDescriptor) {
+ return new File(getFolder(), element.getName() + DYNAMIC_PROPERTIES_EXTENSION);
+ }
+ return super.getFile(element);
+ }
+
+ @Override
+ protected boolean isLoadableElement(File file) {
+ return super.isLoadableElement(file) && !file.getName().endsWith(DYNAMIC_PROPERTIES_EXTENSION);
+ }
+
+ @Override
protected InternalRepository loadElement(ObjectInput in) throws IOException {
return new ECPRepositoryImpl(in);
}
@@ -156,8 +185,8 @@
@Override
protected void doActivate() throws Exception {
- super.doActivate();
- extensionParser.activate();
+ super.doActivate(); // 1. Load dynamic repositories
+ extensionParser.activate(); // 2. Register static repositories
ECPUtil.getECPObserverBus().register(this);
}
@@ -192,7 +221,38 @@
*/
private final class RepositoryDescriptor extends ExtensionDescriptor<InternalRepository> implements
InternalRepository {
- private ECPProperties properties = ECPUtil.createProperties();
+ private Set<String> declaredPropertyKeys;
+ private ECPProperties properties = new Properties() {
+ @Override
+ public void addProperty(String key, String value) {
+ excludeDeclaredProperties(key);
+ super.addProperty(key, value);
+ }
+
+ @Override
+ public void removeProperty(String key) {
+ excludeDeclaredProperties(key);
+ super.removeProperty(key);
+ }
+
+ private void excludeDeclaredProperties(String key) {
+ if (declaredPropertyKeys != null && declaredPropertyKeys.contains(key)) {
+ throw new IllegalArgumentException("Statically declared property can not be changed: " + key);
+ }
+ }
+
+ @Override
+ protected Collection<Map.Entry<String, String>> getElementsToWrite() {
+ List<Map.Entry<String, String>> elementsToWrite = new ArrayList<Map.Entry<String, String>>();
+ for (Map.Entry<String, String> entry : getElements()) {
+ if (!declaredPropertyKeys.contains(entry.getKey())) {
+ elementsToWrite.add(entry);
+ }
+ }
+
+ return elementsToWrite;
+ }
+ };
public RepositoryDescriptor(String name, IConfigurationElement configurationElement) {
super(ECPRepositoryManagerImpl.this, name, TYPE, configurationElement);
@@ -201,16 +261,42 @@
String value = property.getAttribute("value");
properties.addProperty(key, value);
}
+
+ declaredPropertyKeys = new HashSet<String>(properties.getKeys());
+
+ InputStream stream = null;
+
+ try {
+ File file = getFile(this);
+ stream = new FileInputStream(file);
+ ObjectInputStream in = new ObjectInputStream(stream);
+
+ Properties dynamicProperties = new Properties(in);
+ for (Entry<String, String> property : dynamicProperties.getProperties()) {
+ properties.addProperty(property.getKey(), property.getValue());
+ }
+ } catch (IOException ex) {
+ Activator.log(ex);
+ } finally {
+ IOUtil.close(stream);
+ }
+
+ properties.addObserver(new ECPPropertiesObserver() {
+ public void propertiesChanged(ECPProperties properties,
+ Collection<Entry<String, String>> oldProperties, Collection<Entry<String, String>> newProperties) {
+ ECPRepositoryManagerImpl.INSTANCE.storeElement(RepositoryDescriptor.this);
+ }
+ });
}
/** {@inheritDoc} */
public boolean isStorable() {
- return false;
+ return true;
}
/** {@inheritDoc} */
public void write(ObjectOutput out) throws IOException {
- throw new UnsupportedOperationException();
+ ((Properties) properties).write(out);
}
/** {@inheritDoc} */
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/Properties.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/Properties.java
index 7607db8..3b426cc 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/Properties.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/Properties.java
@@ -44,7 +44,7 @@
}
public void write(ObjectOutput out) throws IOException {
- Collection<Entry<String, String>> entries = getElements();
+ Collection<Entry<String, String>> entries = getElementsToWrite();
out.writeInt(entries.size());
for (Entry<String, String> entry : entries) {
out.writeUTF(entry.getKey());
@@ -53,13 +53,13 @@
}
/** {@inheritDoc} */
- public final void addProperty(String key, String value) {
+ public void addProperty(String key, String value) {
Map.Entry<String, String> property = new Property(key, value);
doChangeElements(null, Collections.singleton(property));
}
/** {@inheritDoc} */
- public final void removeProperty(String key) {
+ public void removeProperty(String key) {
doChangeElements(Collections.singleton(key), null);
}
@@ -99,6 +99,10 @@
return element.getKey();
}
+ protected Collection<Entry<String, String>> getElementsToWrite() {
+ return getElements();
+ }
+
/*
* (non-Javadoc)
* @see
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesElement.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesElement.java
index da38b30..c7e7cb5 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesElement.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesElement.java
@@ -13,11 +13,14 @@
import org.eclipse.emf.ecp.core.util.ECPProperties;
import org.eclipse.emf.ecp.core.util.ECPPropertiesAware;
+import org.eclipse.emf.ecp.core.util.observer.ECPPropertiesObserver;
import org.eclipse.emf.ecp.internal.core.util.PropertiesStore.StorableElement;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Map.Entry;
/**
* @author Eike Stepper
@@ -28,11 +31,13 @@
public PropertiesElement(String name, ECPProperties properties) {
super(name);
this.properties = properties;
+ observeProperties();
}
public PropertiesElement(ObjectInput in) throws IOException {
super(in.readUTF());
properties = new Properties(in);
+ observeProperties();
}
/** {@inheritDoc} */
@@ -45,4 +50,18 @@
public final ECPProperties getProperties() {
return properties;
}
+
+ protected void propertiesChanged(Collection<Entry<String, String>> oldProperties,
+ Collection<Entry<String, String>> newProperties) {
+ // Do nothing
+ }
+
+ private void observeProperties() {
+ properties.addObserver(new ECPPropertiesObserver() {
+ public void propertiesChanged(ECPProperties properties, Collection<Entry<String, String>> oldProperties,
+ Collection<Entry<String, String>> newProperties) {
+ PropertiesElement.this.propertiesChanged(oldProperties, newProperties);
+ }
+ });
+ }
}
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesStore.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesStore.java
index 3a10dd6..6b0314f 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesStore.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/internal/core/util/PropertiesStore.java
@@ -76,7 +76,7 @@
Set<ELEMENT> elements = new HashSet<ELEMENT>();
for (File file : folder.listFiles()) {
try {
- if (file.isFile()) {
+ if (isLoadableElement(file)) {
InputStream stream = null;
try {
@@ -97,9 +97,7 @@
elements.add(element);
}
} finally {
- if (stream != null) {
- stream.close();
- }
+ IOUtil.close(stream);
}
}
} catch (IOException ex) {
@@ -110,6 +108,10 @@
doChangeElements(null, elements);
}
+ protected boolean isLoadableElement(File file) {
+ return file.isFile();
+ }
+
protected abstract ELEMENT loadElement(ObjectInput in) throws IOException;
@Override
@@ -136,7 +138,7 @@
}
}
- protected void storeElement(ELEMENT element) {
+ public void storeElement(ELEMENT element) {
File file = getFile(element);
File temp = new File(file.getParentFile(), file.getName() + ".tmp");
if (temp.isFile()) {
diff --git a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/spi/core/InternalProject.java b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/spi/core/InternalProject.java
index 564a652..ecbb7e8 100644
--- a/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/spi/core/InternalProject.java
+++ b/bundles/org.eclipse.emf.ecp.core/src/org/eclipse/emf/ecp/spi/core/InternalProject.java
@@ -92,7 +92,10 @@
/**
* Saves the properties, such as visible packages or the name of the project into the workspace.
+ *
+ * @deprecated As of 1.1 properties are saved automatically when they're changed.
*/
+ @Deprecated
void saveProperties();
/**