[324927] Do not serialize configurations that are contributed by Eclipse plug-ins.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigLoaderJob.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigLoaderJob.java
index e32bb39..f842fc3 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigLoaderJob.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigLoaderJob.java
@@ -12,12 +12,6 @@
  *******************************************************************************/
 package org.eclipse.wst.xml.vex.ui.internal.config;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.text.MessageFormat;
 
 import org.eclipse.core.resources.IProject;
@@ -39,9 +33,6 @@
  */
 public class ConfigLoaderJob extends Job {
 
-	public static final String PLUGIN_CONFIG_SER_PREFIX = ".vexConfig-"; //$NON-NLS-1$
-	public static final String PLUGIN_CONFIG_SER_SUFFIX = ".ser"; //$NON-NLS-1$
-
 	/**
 	 * Class constructor.
 	 */
@@ -54,12 +45,9 @@
 		// System.out.println("ConfigLoaderJob starts");
 
 		int pluginCount = Platform.getExtensionRegistry().getNamespaces().length;
-		int projectCount = ResourcesPlugin.getWorkspace().getRoot()
-				.getProjects().length;
+		int projectCount = ResourcesPlugin.getWorkspace().getRoot().getProjects().length;
 
-		monitor
-				.beginTask(
-						Messages.getString("ConfigLoaderJob.loadingConfig"), pluginCount + projectCount); //$NON-NLS-1$
+		monitor.beginTask(Messages.getString("ConfigLoaderJob.loadingConfig"), pluginCount + projectCount); //$NON-NLS-1$
 
 		this.loadPlugins(monitor);
 		this.loadPluginProjects(monitor);
@@ -78,109 +66,23 @@
 	 * Load configurations from all registered plugins.
 	 */
 	private void loadPlugins(IProgressMonitor monitor) {
-
-		ConfigRegistry configRegistry = ConfigRegistry.getInstance();
-		IExtensionRegistry extRegistry = Platform.getExtensionRegistry();
-		for (String namespace : extRegistry.getNamespaces()) {
-			Bundle bundle = Platform.getBundle(namespace);
+		final ConfigRegistry configRegistry = ConfigRegistry.getInstance();
+		final IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		for (final String namespace : extensionRegistry.getNamespaces()) {
+			final Bundle bundle = Platform.getBundle(namespace);
 			if (bundle == null)
 				continue;
 
-			String name = (String) bundle.getHeaders().get(
-					Constants.BUNDLE_NAME);
-			monitor
-					.subTask(Messages.getString("ConfigLoaderJob.loading") + name); //$NON-NLS-1$
+			final String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME);
+			monitor.subTask(Messages.getString("ConfigLoaderJob.loading") + name); //$NON-NLS-1$
 
-			File stateDir = Platform.getStateLocation(bundle).toFile();
-			String version = (String) bundle.getHeaders().get(
-					Constants.BUNDLE_VERSION);
-			String serFile = PLUGIN_CONFIG_SER_PREFIX + version
-					+ PLUGIN_CONFIG_SER_SUFFIX;
-			File configSerFile = new File(stateDir, serFile);
-
-			ConfigSource source = null;
-			if (configSerFile.exists()) {
-				try {
-					// long start = System.currentTimeMillis();
-					source = loadConfigSourceFromFile(configSerFile);
-					// long end = System.currentTimeMillis();
-					// System.out.println("  load from ser file took " +
-					// (end-start) + "ms");
-				} catch (IOException ex) {
-					String message = MessageFormat.format(Messages
-							.getString("ConfigLoaderJob.loadingError"), //$NON-NLS-1$
-							new Object[] { configSerFile });
-					this.log(IStatus.WARNING, message, ex);
-				}
-			}
-
-			if (source == null) {
-
-				source = ConfigPlugin.load(namespace);
-
-				if (source != null) {
-					try {
-						saveConfigSourceToFile(source, configSerFile);
-					} catch (IOException ex) {
-						String message = MessageFormat.format(Messages
-								.getString("ConfigLoaderJob.cacheError"), //$NON-NLS-1$
-								new Object[] { configSerFile });
-						this.log(IStatus.WARNING, message, ex);
-					}
-				} else {
-					if (configSerFile.exists()) {
-						configSerFile.delete(); // Used to have a config, but
-												// now we don't
-					}
-				}
-
-			}
-
-			if (source != null) {
+			final ConfigSource source = ConfigPlugin.load(namespace);
+			if (source != null)
 				configRegistry.addConfigSource(source);
-			}
-
 			monitor.worked(1);
 		}
 	}
 
-	private static ConfigSource loadConfigSourceFromFile(File file)
-			throws IOException {
-
-		FileInputStream fis = null;
-		try {
-			fis = new FileInputStream(file);
-			ObjectInputStream ois = new ObjectInputStream(fis);
-			return (ConfigSource) ois.readObject();
-		} catch (ClassNotFoundException ex) {
-			throw new IOException(ex.getMessage());
-		} finally {
-			if (fis != null) {
-				try {
-					fis.close();
-				} catch (IOException ex) {
-				}
-			}
-		}
-	}
-
-	private static void saveConfigSourceToFile(ConfigSource config, File file)
-			throws IOException {
-		FileOutputStream fos = null;
-		try {
-			fos = new FileOutputStream(file);
-			ObjectOutputStream oos = new ObjectOutputStream(fos);
-			oos.writeObject(config);
-		} finally {
-			if (fos != null) {
-				try {
-					fos.close();
-				} catch (IOException ex) {
-				}
-			}
-		}
-	}
-
 	/**
 	 * Load configurations from all Vex Plugin Projects in the workspace.
 	 */
@@ -191,24 +93,17 @@
 
 		for (IProject project : projects) {
 			try {
-				if (project.isOpen()
-						&& project.hasNature(PluginProjectNature.ID)) {
-					monitor
-							.subTask(Messages
-									.getString("ConfigLoaderJob.loadingProject") + project.getName()); //$NON-NLS-1$
+				if (project.isOpen() && project.hasNature(PluginProjectNature.ID)) {
+					monitor.subTask(Messages.getString("ConfigLoaderJob.loadingProject") + project.getName()); //$NON-NLS-1$
 					PluginProject.load(project);
 					monitor.worked(1);
 				}
 			} catch (CoreException e) {
-				String message = MessageFormat.format(Messages
-						.getString("ConfigLoaderJob.natureError"), //$NON-NLS-1$
+				String message = MessageFormat.format(Messages.getString("ConfigLoaderJob.natureError"), //$NON-NLS-1$
 						new Object[] { project.getName() });
 				VexPlugin.getInstance().log(IStatus.ERROR, message, e);
 			}
 		}
 	}
 
-	private void log(int severity, String message, Throwable exception) {
-		VexPlugin.getInstance().log(severity, message, exception);
-	}
 }
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigRegistry.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigRegistry.java
index 2d03d98..7dd65d5 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigRegistry.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/config/ConfigRegistry.java
@@ -12,7 +12,9 @@
 package org.eclipse.wst.xml.vex.ui.internal.config;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResourceChangeEvent;
@@ -60,6 +62,19 @@
 	}
 
 	/**
+	 * Removes all loaded ConfigSource instances and resets the configLoaded flag.
+	 */
+	public void clear() {
+		try {
+			this.lock();
+			configs.clear();
+			configLoaded = false;
+		} finally {
+			this.unlock();
+		}
+	}
+	
+	/**
 	 * Add a VexConfiguration to the list of configurations.
 	 * 
 	 * @param config
@@ -68,7 +83,7 @@
 	public void addConfigSource(ConfigSource config) {
 		try {
 			this.lock();
-			this.configs.add(config);
+			this.configs.put(config.getUniqueIdentifer(), config);
 		} finally {
 			this.unlock();
 		}
@@ -146,7 +161,7 @@
 		try {
 			this.lock();
 			List<ConfigItem> items = new ArrayList<ConfigItem>();
-			for (ConfigSource config : this.configs) {
+			for (ConfigSource config : this.configs.values()) {
 				items.addAll(config.getValidItems(extensionPoint));
 			}
 			return items;
@@ -164,7 +179,7 @@
 		try {
 			this.lock();
 			List<ConfigSource> result = new ArrayList<ConfigSource>();
-			result.addAll(this.configs);
+			result.addAll(this.configs.values());
 			return result;
 		} finally {
 			this.unlock();
@@ -264,7 +279,7 @@
 	private static ConfigRegistry instance = new ConfigRegistry();
 
 	private ILock lock = Job.getJobManager().newLock();
-	private List<ConfigSource> configs = new ArrayList<ConfigSource>();
+	private Map<String, ConfigSource> configs = new HashMap<String, ConfigSource>();
 	private ListenerList<IConfigListener, ConfigEvent> configListeners =
 	    new ListenerList<IConfigListener, ConfigEvent>(IConfigListener.class);
 	private boolean configLoaded = false;
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/META-INF/MANIFEST.MF b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/META-INF/MANIFEST.MF
index f1fe955..b92aa6f 100644
--- a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/META-INF/MANIFEST.MF
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.wst.xml.vex.ui.tests
+Bundle-SymbolicName: org.eclipse.wst.xml.vex.ui.tests;singleton:=true
 Bundle-Version: 0.5.0.qualifier
 Bundle-Vendor: %providerName
 Require-Bundle: org.eclipse.ui,
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/build.properties b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/build.properties
index aa1a008..8cc14a1 100644
--- a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/build.properties
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/build.properties
@@ -2,4 +2,6 @@
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               plugin.properties
+               plugin.properties,\
+               plugin.xml,\
+               testdata/
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/plugin.xml b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/plugin.xml
new file mode 100644
index 0000000..4528bd3
--- /dev/null
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/plugin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+   <extension

+         id="test"

+         name="test doctype"

+         point="org.eclipse.wst.xml.vex.ui.doctypes">

+      <doctype

+            systemId="test.dtd"

+            dtd="testdata/test.dtd"

+            publicId="-//Vex//DTD Test//EN">

+      </doctype>

+   </extension>

+   <extension

+         id="test"

+         name="test style"

+         point="org.eclipse.wst.xml.vex.ui.styles">

+      <style

+            css="testdata/test.css">

+         <doctypeRef

+               publicId="-//Vex//DTD Test//EN">

+         </doctypeRef>

+      </style>

+   </extension>

+

+</plugin>

diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/internal/config/tests/ConfigLoaderJobTest.java b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/internal/config/tests/ConfigLoaderJobTest.java
new file mode 100644
index 0000000..5262ef3
--- /dev/null
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/internal/config/tests/ConfigLoaderJobTest.java
@@ -0,0 +1,51 @@
+package org.eclipse.wst.xml.vex.ui.internal.config.tests;

+

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertTrue;

+import static org.junit.Assert.fail;

+

+import java.util.HashSet;

+import java.util.List;

+

+import org.eclipse.wst.xml.vex.ui.internal.config.ConfigLoaderJob;

+import org.eclipse.wst.xml.vex.ui.internal.config.ConfigRegistry;

+import org.eclipse.wst.xml.vex.ui.internal.config.ConfigSource;

+import org.junit.Before;

+import org.junit.Test;

+

+@SuppressWarnings("restriction")

+public class ConfigLoaderJobTest {

+

+	@Before

+	public void setUp() throws Exception {

+		ConfigRegistry.getInstance().clear();

+	}

+	

+	@Test

+	public void loadUiTestsPlugin() throws Exception {

+		assertTrue(ConfigRegistry.getInstance().getAllConfigSources().isEmpty());

+		final ConfigLoaderJob job = new ConfigLoaderJob();

+		job.schedule();

+		job.join();

+		List<ConfigSource> allConfigSources = ConfigRegistry.getInstance().getAllConfigSources();

+		assertContainsTestsPlugin(allConfigSources);

+		assertContainsEachPluginOnlyOnce(allConfigSources);

+	}

+	

+	private static void assertContainsTestsPlugin(final List<ConfigSource> configSources) {

+		for (ConfigSource configSource : configSources)

+			if ("org.eclipse.wst.xml.vex.ui.tests".equals(configSource.getUniqueIdentifer())) {

+				assertNotNull(configSource.getItemForResource("testdata/test.dtd"));

+				assertNotNull(configSource.getItemForResource("testdata/test.css"));

+				return;

+			}

+		fail("Cannot find extension from plug-in org.eclipse.wst.xml.vex.ui.tests.");

+	}

+	

+	private static void assertContainsEachPluginOnlyOnce(final List<ConfigSource> configSources) {

+		final HashSet<String> configSourceIds = new HashSet<String>();

+		for (ConfigSource configSource : configSources)

+			assertTrue("ConfigRegistry contains " + configSource.getUniqueIdentifer() + " twice.", configSourceIds.add(configSource.getUniqueIdentifer()));

+	}

+

+}

diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/tests/VexUiTestSuite.java b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/tests/VexUiTestSuite.java
index 0ffd033..5c5be93 100644
--- a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/tests/VexUiTestSuite.java
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/src/org/eclipse/wst/xml/vex/ui/tests/VexUiTestSuite.java
@@ -10,9 +10,11 @@
  *******************************************************************************/
 package org.eclipse.wst.xml.vex.ui.tests;
 
+import junit.framework.JUnit4TestAdapter;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.eclipse.wst.xml.vex.ui.internal.config.tests.ConfigLoaderJobTest;
 import org.eclipse.wst.xml.vex.ui.internal.editor.tests.FindReplaceTargetTest;
 import org.eclipse.wst.xml.vex.ui.internal.tests.ResourceTrackerTest;
 
@@ -24,6 +26,7 @@
 
 	public VexUiTestSuite() {
 		super("Vex UI Tests"); //$NON-NLS-1$
+		addTest(new JUnit4TestAdapter(ConfigLoaderJobTest.class));
 		addTestSuite(IconTest.class);
 		addTestSuite(FindReplaceTargetTest.class);
 		addTestSuite(ResourceTrackerTest.class);
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.css b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.css
new file mode 100644
index 0000000..9a83031
--- /dev/null
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.css
@@ -0,0 +1,53 @@
+
+html {
+  display: block;
+}
+
+body {
+  display: block;
+}
+
+p {
+  display: block;
+}
+
+block {
+  display: block;
+}
+
+pre {
+  display: block;
+  white-space: pre;
+}
+
+
+/* Styles for positioning tests */
+root {
+  border: 3px 7px 11px 13px;
+  padding: 17px 19px 23px 29px;
+}
+
+small {
+  border-width: 1px 2px 3px 4px;
+  border-style: solid;
+  margin: 100px 200px 300px 400px;
+  padding: 10px 20px 30px 40px;
+  display: block;
+}
+
+medium {
+  border-width: 2px 4px 6px 8px;
+  border-style: solid;
+  margin: 200px 400px 600px 800px;
+  padding: 20px 40px 60px 80px;
+  display: block;
+}
+
+large {
+  border-width: 3px 6px 9px 12px;
+  border-style: solid;
+  margin: 300px 600px 900px 1200px;
+  padding: 30px 60px 90px 120px;
+  display: block;
+}
+
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.dtd b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.dtd
new file mode 100644
index 0000000..f246a88
--- /dev/null
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.ui.tests/testdata/test.dtd
@@ -0,0 +1,10 @@
+<!ELEMENT any ANY>
+<!ELEMENT empty EMPTY>
+<!ELEMENT section (title?, para+)>
+<!ELEMENT para (#PCDATA | emphasis)*>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT emphasis (#PCDATA)>
+
+<!-- a dummy attribute, just to make sure attribute def serialization is OK -->
+<!ATTLIST section
+	name	CDATA	#IMPLIED>
\ No newline at end of file