/******************************************************************************* * Copyright (c) 2004, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Alexander Kurtakov <akurtako@redhat.com> - Bug 459343 *******************************************************************************/ package org.eclipse.core.tests.internal.resources; import java.io.*; import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.internal.preferences.EclipsePreferences; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.preferences.*; import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.core.tests.resources.ResourceTest; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; /** * @since 3.0 */ public class ProjectPreferencesTest extends ResourceTest { private static final String DIR_NAME = ".settings"; private static final String FILE_EXTENSION = "prefs"; class Tracer implements IEclipsePreferences.IPreferenceChangeListener { public StringBuffer log = new StringBuffer(); private String typeCode(Object value) { if (value == null) { return ""; } if (value instanceof Boolean) { return "B"; } if (value instanceof Integer) { return "I"; } if (value instanceof Long) { return "L"; } if (value instanceof Float) { return "F"; } if (value instanceof Double) { return "D"; } if (value instanceof String) { return "S"; } assertTrue("0.0", false); return null; } @Override public void preferenceChange(PreferenceChangeEvent event) { log.append("["); log.append(event.getKey()); log.append(":"); log.append(typeCode(event.getOldValue())); log.append(event.getOldValue() == null ? "null" : event.getOldValue()); log.append("->"); log.append(typeCode(event.getNewValue())); log.append(event.getNewValue() == null ? "null" : event.getNewValue()); log.append("]"); } } public static Test suite() { // all test methods are named "test..." return new TestSuite(ProjectPreferencesTest.class); // TestSuite suite = new TestSuite(); // suite.addTest(new ProjectPreferencesTest("testLoadIsImport")); // return suite; } public ProjectPreferencesTest(String name) { super(name); } public void testSimple() { IProject project = getProject("foo"); String qualifier = "org.eclipse.core.tests.resources"; String key = "key" + getUniqueString(); String instanceValue = "instance" + getUniqueString(); String projectValue = "project" + getUniqueString(); IScopeContext projectContext = new ProjectScope(project); IScopeContext instanceContext = InstanceScope.INSTANCE; ensureExistsInWorkspace(project, true); ArrayList<IScopeContext[]> list = new ArrayList<>(); list.add(null); list.add(new IScopeContext[0]); list.add(new IScopeContext[] {null}); IScopeContext[][] contextsWithoutScope = list.toArray(new IScopeContext[list.size()][]); list = new ArrayList<>(); list.add(new IScopeContext[] {projectContext}); list.add(new IScopeContext[] {null, projectContext}); IScopeContext[][] contextsWithScope = list.toArray(new IScopeContext[list.size()][]); // set a preference value in the instance scope IPreferencesService service = Platform.getPreferencesService(); Preferences node = instanceContext.getNode(qualifier); node.put(key, instanceValue); String actual = node.get(key, null); assertNotNull("1.0", actual); assertEquals("1.1", instanceValue, actual); // get the value through service searching for (int i = 0; i < contextsWithoutScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithoutScope[i]); assertNotNull("2.0." + i, actual); assertEquals("2.1." + i, instanceValue, actual); } for (int i = 0; i < contextsWithScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithScope[i]); assertNotNull("2.2." + i, actual); assertEquals("2.3." + i, instanceValue, actual); } // set a preference value in the project scope node = projectContext.getNode(qualifier); node.put(key, projectValue); actual = node.get(key, null); assertNotNull("3.0", actual); assertEquals("3.1", projectValue, actual); // get the value through service searching for (int i = 0; i < contextsWithoutScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithoutScope[i]); assertNotNull("4.0." + i, actual); assertEquals("4.1." + i, instanceValue, actual); } for (int i = 0; i < contextsWithScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithScope[i]); assertNotNull("4.2." + i, actual); assertEquals("4.3." + i, projectValue, actual); } // remove the project scope value node = projectContext.getNode(qualifier); node.remove(key); actual = node.get(key, null); assertNull("5.0", actual); // get the value through service searching for (int i = 0; i < contextsWithoutScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithoutScope[i]); assertNotNull("6.0." + i, actual); assertEquals("6.1." + i, instanceValue, actual); } for (int i = 0; i < contextsWithScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithScope[i]); assertNotNull("6.2." + i, actual); assertEquals("6.3." + i, instanceValue, actual); } // remove the instance value so there is nothing node = instanceContext.getNode(qualifier); node.remove(key); actual = node.get(key, null); for (int i = 0; i < contextsWithoutScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithoutScope[i]); assertNull("7.0." + i, actual); } for (int i = 0; i < contextsWithScope.length; i++) { actual = service.getString(qualifier, key, null, contextsWithScope[i]); assertNull("7.1." + i, actual); } } public void testListener() { // setup IProject project = getProject(getUniqueString()); String qualifier = "org.eclipse.core.tests.resources"; String key = "key" + getUniqueString(); String value = "value" + getUniqueString(); IScopeContext projectContext = new ProjectScope(project); // create project ensureExistsInWorkspace(project, true); // set preferences Preferences node = projectContext.getNode(qualifier); node.put(key, value); String actual = node.get(key, null); assertNotNull("1.0", actual); assertEquals("1.1", value, actual); try { // flush node.flush(); } catch (BackingStoreException e) { fail("0.0", e); } // get settings filename File file = getFileInFilesystem(project, qualifier); Properties props = new Properties(); InputStream input = null; try { input = new BufferedInputStream(new FileInputStream(file)); props.load(input); } catch (IOException e) { fail("1.0", e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { // ignore } } } // change settings in the file String newKey = "newKey" + getUniqueString(); String newValue = "newValue" + getUniqueString(); props.put(newKey, newValue); // save the file and ensure timestamp is different OutputStream output = null; try { output = new BufferedOutputStream(new FileOutputStream(file)); props.store(output, null); } catch (IOException e) { fail("2.0", e); } finally { if (output != null) { try { output.close(); } catch (IOException e) { // ignore } } } IFile workspaceFile = getFileInWorkspace(project, qualifier); // ensure that the file is out-of-sync with the workspace // by changing the lastModified time touchInFilesystem(workspaceFile); // resource change is fired try { workspaceFile.refreshLocal(IResource.DEPTH_ZERO, getMonitor()); } catch (CoreException e) { fail("3.1", e); } // validate new settings actual = node.get(key, null); assertEquals("4.1", value, actual); actual = node.get(newKey, null); assertEquals("4.2", newValue, actual); } /** * Regression test for bug 60896 - Project preferences remains when deleting/creating project */ public void testProjectDelete() { // create the project IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); // set some settings String qualifier = getUniqueString(); String key = getUniqueString(); String value = getUniqueString(); IScopeContext context = new ProjectScope(project); Preferences node = context.getNode(qualifier); Preferences parent = node.parent().parent(); node.put(key, value); assertEquals("1.0", value, node.get(key, null)); try { // delete the project project.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, getMonitor()); } catch (CoreException e) { fail("2.0", e); } try { // project pref should not exist assertTrue("3.0", !parent.nodeExists(project.getName())); } catch (BackingStoreException e) { fail("3.1", e); } // create a project with the same name ensureExistsInWorkspace(project, true); // ensure that the preference value is not set assertNull("4.0", context.getNode(qualifier).get(key, null)); } /** See bug 91244, bug 93398 and bug 211006. */ public void testProjectMove() { IProject project1 = getProject(getUniqueString()); IProject project2 = getProject(getUniqueString()); ensureExistsInWorkspace(new IResource[] {project1}, true); String qualifier = getUniqueString(); String key = getUniqueString(); String value = getUniqueString(); Preferences node = new ProjectScope(project1).getNode(qualifier); node.put(key, value); try { node.flush(); } catch (BackingStoreException e) { fail("1.0", e); } // move project try { project1.move(new Path(project2.getName()), false, null); } catch (CoreException e) { fail("2.0", e); } // ensure that preferences for the old project are removed node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); assertNotNull("2.1", node); try { assertTrue("2.2", !node.nodeExists(project1.getName())); } catch (BackingStoreException e) { fail("2.3", e); } // ensure preferences are preserved node = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); assertNotNull("2.3", node); try { assertTrue("2.4", node.nodeExists(project2.getName())); } catch (BackingStoreException e) { fail("2.5", e); } node = node.node(project2.getName()); assertNotNull("3.1", node); try { assertTrue("3.2", node.nodeExists(qualifier)); } catch (BackingStoreException e) { fail("3.3", e); } node = node.node(qualifier); assertNotNull("4.1", node); assertEquals("4.2", value, node.get(key, null)); } /** * Regression test for Bug 60925 - project preferences do not show up in workspace. * * Initially we were using java.io.File APIs and writing the preferences files * directly to disk. We need to convert to use Resource APIs so changes * show up in the workspace immediately. */ public void test_60925() { // setup IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); String qualifier = getUniqueString(); IFile file = getFileInWorkspace(project, qualifier); // should be nothing in the file system assertTrue("0.0", !file.exists()); assertTrue("0.1", !file.getLocation().toFile().exists()); // store a preference key/value pair IScopeContext context = new ProjectScope(project); String key = getUniqueString(); String value = getUniqueString(); Preferences node = context.getNode(qualifier); node.put(key, value); // flush changes to disk try { node.flush(); } catch (BackingStoreException e) { fail("1.0", e); } // changes should appear in the workspace assertTrue("2.0", file.exists()); assertTrue("2.1", file.isSynchronized(IResource.DEPTH_ZERO)); } /** * Bug 55410 - [runtime] prefs: keys and valid chars * * Problems with a dot "." as a key name */ public void test_55410() { IProject project1 = getProject(getUniqueString()); ensureExistsInWorkspace(new IResource[] {project1}, true); Preferences node = new ProjectScope(project1).getNode(ResourcesPlugin.PI_RESOURCES).node("subnode"); String key1 = "."; String key2 = "x"; String value1 = getUniqueString(); String value2 = getUniqueString(); node.put(key1, value1); node.put(key2, value2); assertEquals("0.8", value1, node.get(key1, null)); assertEquals("0.9", value2, node.get(key2, null)); IFile prefsFile = getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES); assertTrue("1.0", !prefsFile.exists()); try { node.flush(); } catch (BackingStoreException e) { fail("1.1", e); } assertTrue("1.1", prefsFile.exists()); Properties props = new Properties(); InputStream contents = null; try { contents = prefsFile.getContents(); } catch (CoreException e) { fail("1.2", e); } try { props.load(contents); } catch (IOException e) { fail("1.3", e); } finally { if (contents != null) { try { contents.close(); } catch (IOException e) { // ignore } } } assertEquals("2.0", value2, props.getProperty("subnode/" + key2)); assertEquals("2.1", value1, props.getProperty("subnode/" + key1)); } /** * Bug 61277 - preferences and project moves * * Investigate what happens with project preferences when the * project is moved. */ public void test_61277a() { IProject project = getProject(getUniqueString()); IProject destProject = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); ensureDoesNotExistInWorkspace(destProject); IScopeContext context = new ProjectScope(project); String qualifier = getUniqueString(); Preferences node = context.getNode(qualifier); String key = getUniqueString(); String value = getUniqueString(); node.put(key, value); assertEquals("1.0", value, node.get(key, null)); try { // save the prefs node.flush(); } catch (BackingStoreException e) { fail("1.1", e); } // rename the project try { project.move(destProject.getFullPath(), true, getMonitor()); } catch (CoreException e) { fail("2.0", e); } context = new ProjectScope(destProject); node = context.getNode(qualifier); assertEquals("3.0", value, node.get(key, null)); } /** * Bug 61277 - preferences and project moves * * Investigate what happens with project preferences when the * project is moved. */ public void test_61277b() { IProject project1 = getProject(getUniqueString()); IProject project2 = getProject(getUniqueString()); ensureExistsInWorkspace(new IResource[] {project1}, true); Preferences node = new ProjectScope(project1).getNode(ResourcesPlugin.PI_RESOURCES); node.put("key", "value"); assertTrue("1.0", !getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES).exists()); try { node.flush(); } catch (BackingStoreException e) { fail("1.99", e); } assertTrue("1.1", getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES).exists()); // move project and ensures charsets settings are preserved try { project1.move(project2.getFullPath(), false, null); } catch (CoreException e) { fail("2.99", e); } assertTrue("2.0", getFileInWorkspace(project2, ResourcesPlugin.PI_RESOURCES).exists()); node = new ProjectScope(project2).getNode(ResourcesPlugin.PI_RESOURCES); assertEquals("2.1", "value", node.get("key", null)); } /** * Bug 61277 - preferences and project moves * * Investigate what happens with project preferences when the * project is moved. * * Problems with a key which is the empty string. */ public void test_61277c() { IProject project1 = getProject(getUniqueString()); ensureExistsInWorkspace(new IResource[] {project1}, true); Preferences node = new ProjectScope(project1).getNode(ResourcesPlugin.PI_RESOURCES); String key1 = "key"; String emptyKey = ""; String value1 = getUniqueString(); String value2 = getUniqueString(); node.put(key1, value1); node.put(emptyKey, value2); assertTrue("1.0", !getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES).exists()); try { node.flush(); } catch (BackingStoreException e) { fail("1.1", e); } assertTrue("1.2", getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES).exists()); // move project and ensures charsets settings are preserved IProject project2 = getProject(getUniqueString()); try { project1.move(project2.getFullPath(), false, null); } catch (CoreException e) { fail("2.99", e); } assertTrue("2.0", getFileInWorkspace(project2, ResourcesPlugin.PI_RESOURCES).exists()); node = new ProjectScope(project2).getNode(ResourcesPlugin.PI_RESOURCES); assertEquals("2.1", value1, node.get(key1, null)); assertEquals("2.2", value2, node.get(emptyKey, null)); } /* * Bug 61843 - Saving project preferences failed * * The project preferences are being accessing (for the first time) from * within a resource change listener reacting to a change in the workspace. */ public void test_61843() { // create the project and manually give it a settings file final String qualifier = getUniqueString(); final IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); IFile settingsFile = getFileInWorkspace(project, qualifier); // write some property values in the settings file Properties properties = new Properties(); properties.put("key", "value"); OutputStream output = null; try { File file = settingsFile.getLocation().toFile(); file.getParentFile().mkdirs(); output = new BufferedOutputStream(new FileOutputStream(file)); properties.store(output, null); } catch (FileNotFoundException e) { fail("1.0", e); } catch (IOException e) { fail("1.1", e); } finally { try { if (output != null) { output.close(); } } catch (IOException e) { // ignore } } // add a log listener to ensure that no errors are reported silently ILogListener logListener = new ILogListener() { @Override public void logging(IStatus status, String plugin) { Throwable exception = status.getException(); if (exception == null || !(exception instanceof CoreException)) { return; } if (IResourceStatus.WORKSPACE_LOCKED == ((CoreException) exception).getStatus().getCode()) { fail("3.0"); } } }; // listener to react to changes in the workspace IResourceChangeListener rclistener = new IResourceChangeListener() { @Override public void resourceChanged(IResourceChangeEvent event) { new ProjectScope(project).getNode(qualifier); } }; // add the listeners Platform.addLogListener(logListener); getWorkspace().addResourceChangeListener(rclistener, IResourceChangeEvent.POST_CHANGE); try { project.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.0", e); } finally { Platform.removeLogListener(logListener); getWorkspace().removeResourceChangeListener(rclistener); } } /* * Bug 65068 - When the preferences file is deleted, the corresponding preferences * should be forgotten. */ public void test_65068() { IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); Preferences node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); String key = "key"; String value = getUniqueString(); node.put(key, value); try { node.flush(); } catch (BackingStoreException e) { fail("1.1", e); } assertTrue("1.2", getFileInWorkspace(project, ResourcesPlugin.PI_RESOURCES).exists()); node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); assertEquals("1.3", value, node.get(key, null)); ensureDoesNotExistInWorkspace(project.getFolder(DIR_NAME)); node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); assertNull("2.0", node.get(key, null)); } /* * Bug 95052 - external property removals are not detected. */ public void test_95052() { IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); Preferences node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); node.put("key1", "value1"); node.put("key2", "value2"); node.put("key3", "value3"); try { node.flush(); } catch (BackingStoreException e) { fail("1.1", e); } IFile prefFile = getFileInWorkspace(project, ResourcesPlugin.PI_RESOURCES); assertTrue("1.2", prefFile.exists()); Properties properties = new Properties(); InputStream contents = null; try { contents = prefFile.getContents(); } catch (CoreException e) { fail("1.3", e); } try { properties.load(contents); } catch (IOException e) { fail("1.4", e); } finally { try { contents.close(); } catch (IOException e) { // } } assertEquals("2.0", "value1", properties.get("key1")); assertEquals("2.1", "value2", properties.get("key2")); assertEquals("2.2", "value3", properties.get("key3")); // add a new property properties.put("key0", "value0"); // change an existing property properties.put("key2", "value2".toUpperCase()); // removes a property properties.remove("key3"); ByteArrayOutputStream tempOutput = new ByteArrayOutputStream(); try { properties.store(tempOutput, null); } catch (IOException e) { // should never happen, we are not doing I/O fail("2.4", e); } ByteArrayInputStream tempInput = new ByteArrayInputStream(tempOutput.toByteArray()); try { prefFile.setContents(tempInput, false, false, getMonitor()); } catch (CoreException e) { fail("2.5", e); } // here, project preferences should have caught up with the changes node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); // property was added assertEquals("3.0", "value0", node.get("key0", null)); // property value was not changed assertEquals("3.1", "value1", node.get("key1", null)); // property value was changed to upper case assertEquals("3.2", "value2".toUpperCase(), node.get("key2", null)); // property was deleted assertNull("3.3", node.get("key3", null)); } /* * Bug 256900 - When the preferences file is copied between projects, the corresponding preferences * should be updated. */ public void test_256900() { IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); // create the destination project and the .settings folder inside IProject project2 = getProject(getUniqueString()); ensureExistsInWorkspace(project2, true); ensureExistsInWorkspace(project2.getFolder(DIR_NAME), true); // get the pref node for the project and add a sample key/value to it Preferences node = new ProjectScope(project).getNode(ResourcesPlugin.PI_RESOURCES); String key = "key"; String value = getUniqueString(); node.put(key, value); try { node.flush(); } catch (BackingStoreException e) { fail("1.0", e); } IFile prefFile = getFileInWorkspace(project, ResourcesPlugin.PI_RESOURCES); assertTrue("2.0", prefFile.exists()); // get the pref node for the destination project Preferences project2Node = new ProjectScope(project2).getNode(ResourcesPlugin.PI_RESOURCES); assertNull("3.0", project2Node.get(key, null)); // copy the pref file to the destination project try { prefFile.copy(getFileInWorkspace(project2, ResourcesPlugin.PI_RESOURCES).getFullPath(), true, null); } catch (CoreException e) { fail("4.0", e); } assertEquals("5.0", value, project2Node.get(key, null)); } /** * Bug 325000 Project properties not sorted on IBM VMs * Creates property file with various characters on front and verifies that they are written in alphabetical order. */ public void test_325000() { IProject project1 = getProject(getUniqueString()); ensureExistsInWorkspace(new IResource[] {project1}, true); Preferences node = new ProjectScope(project1).getNode(ResourcesPlugin.PI_RESOURCES).node("subnode"); List<String> keys = new ArrayList<>(); keys.add("z" + getUniqueString()); keys.add("a" + getUniqueString()); keys.add("1" + getUniqueString()); keys.add("z" + getUniqueString()); keys.add("_" + getUniqueString()); keys.add(getUniqueString()); for (String key : keys) { node.put(key, getUniqueString()); } try { node.flush(); } catch (BackingStoreException e) { fail("1.0", e); } IFile prefsFile = getFileInWorkspace(project1, ResourcesPlugin.PI_RESOURCES); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(prefsFile.getContents())); String currentLine = null; String prevLine = null; while ((currentLine = reader.readLine()) != null) { boolean isUserProperty = false; for (String key : keys) { if (currentLine.contains(key)) { isUserProperty = true; break; } } if (!isUserProperty) { continue; } if (prevLine == null) { prevLine = currentLine; continue; } if (prevLine.compareTo(currentLine) > 0) { fail("1.1"); } prevLine = currentLine; } } catch (CoreException e) { fail("1.2", e); } catch (IOException e) { fail("1.3", e); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { fail("1.4", e); } } } } public void test_335591() { String projectName = getUniqueString(); String nodeName = "node"; IProject project = getProject(projectName); //create project but do not open it yet try { project.create(getMonitor()); } catch (CoreException e) { fail("1.0", e); } //create file with preferences that will be discovered during refresh try { File folder = new File(project.getLocation().toOSString() + "/.settings"); folder.mkdir(); BufferedWriter bw = new BufferedWriter(new FileWriter(folder.getPath() + "/" + nodeName + ".prefs")); bw.write("#Fri Jan 28 10:28:45 CET 2011\neclipse.preferences.version=1\nKEY=VALUE"); bw.close(); } catch (IOException e) { fail("2.0", e); } //create /project/<projectName> preference node on closed project so that the node will not get initialized //we cannot call new ProjectScope(project) because this does not create /project/<projectName> preference node //we could use new ProjectScope(project).getNode("dummyNode") instead - this is the case that happened in bug 334241 Preferences projectNode = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE).node(projectName); //open the project. the new file will be found during refresh and preferences will be loaded into nodes try { project.open(getMonitor()); } catch (CoreException e) { fail("3.0", e); } //the node was created on refresh so we can now take the node without creating it Preferences node = projectNode.node(nodeName); //correct value should be available assertEquals("VALUE", node.get("KEY", null)); //add some preference to make the node dirty node.put("NEW_KEY", "NEW_VALUE"); //node is dirty so we can flush it and the flush should change the content of the file try { node.flush(); } catch (BackingStoreException e) { fail("4.0", e); } //preferences were changed so the new file should contain two lines: 'KEY=VALUE' and 'NEW_KEY=NEW_VALUE' try { File folder = new File(project.getLocation().toOSString() + "/.settings"); BufferedReader br = new BufferedReader(new FileReader(folder.getPath() + "/" + nodeName + ".prefs")); List<String> lines = new ArrayList<>(); String line = br.readLine(); while (line != null) { if ((!line.startsWith("#")) && (!line.startsWith("eclipse.preferences.version"))) { lines.add(line); } line = br.readLine(); } br.close(); assertEquals(2, lines.size()); Collections.sort(lines); assertTrue(lines.get(0).equals("KEY=VALUE")); assertTrue(lines.get(1).equals("NEW_KEY=NEW_VALUE")); } catch (IOException e) { fail("5.0", e); } //call sync to reload the node from file try { node.sync(); } catch (BackingStoreException e) { fail("6.0", e); } //after reloading both preferences should be available assertEquals("VALUE", node.get("KEY", null)); assertEquals("NEW_VALUE", node.get("NEW_KEY", null)); } public void test_384151() throws BackingStoreException, CoreException { // make sure each line separator is different String systemValue = System.getProperty("line.separator"); String newInstanceValue; String newProjectValue; if (systemValue.equals("\n")) { // for unix "\n" newInstanceValue = "\r"; newProjectValue = "\r\n"; } else if (systemValue.equals("\r")) { // for macos "\r" newInstanceValue = "\n"; newProjectValue = "\r\n"; } else { // for windows "\r\n" newInstanceValue = "\r"; newProjectValue = "\n"; } IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); Preferences rootNode = Platform.getPreferencesService().getRootNode(); Preferences instanceNode = rootNode.node(InstanceScope.SCOPE).node(Platform.PI_RUNTIME); Preferences projectNode = rootNode.node(ProjectScope.SCOPE).node(project.getName()).node(Platform.PI_RUNTIME); String oldInstanceValue = instanceNode.get(Platform.PREF_LINE_SEPARATOR, null); String oldProjectValue = projectNode.get(Platform.PREF_LINE_SEPARATOR, null); String qualifier = "qualifier"; IFile file = project.getFile(new Path(".settings/" + qualifier + ".prefs")); Preferences node = rootNode.node(ProjectScope.SCOPE).node(project.getName()).node(qualifier); String key = "key"; try { node.put(key, getUniqueString()); node.flush(); // if there is no preference, OS default line separator should be used assertEquals("1.0", systemValue, getLineSeparatorFromFile(file)); file.delete(true, getMonitor()); instanceNode.put(Platform.PREF_LINE_SEPARATOR, newInstanceValue); instanceNode.flush(); node.put(key, getUniqueString()); node.flush(); // if there is instance preference then it should be used assertEquals("2.0", newInstanceValue, getLineSeparatorFromFile(file)); file.delete(true, getMonitor()); projectNode.put(Platform.PREF_LINE_SEPARATOR, newProjectValue); projectNode.flush(); node.put(key, getUniqueString()); node.flush(); // if there is project preference then it should be used String recentlyUsedLineSeparator = getLineSeparatorFromFile(file); assertEquals("3.0", newProjectValue, recentlyUsedLineSeparator); // don't delete the prefs file, it will be used in the next step // remove preferences for the next step if (oldInstanceValue == null) { instanceNode.remove(Platform.PREF_LINE_SEPARATOR); } else { instanceNode.put(Platform.PREF_LINE_SEPARATOR, oldInstanceValue); } if (oldProjectValue == null) { projectNode.remove(Platform.PREF_LINE_SEPARATOR); } else { projectNode.put(Platform.PREF_LINE_SEPARATOR, oldProjectValue); } instanceNode.flush(); projectNode.flush(); node.put(key, getUniqueString()); node.flush(); // if the prefs file exists, line delimiter from the existing file should be used assertEquals("4.0", recentlyUsedLineSeparator, getLineSeparatorFromFile(file)); } finally { // revert instance preference to original value if (oldInstanceValue == null) { instanceNode.remove(Platform.PREF_LINE_SEPARATOR); } else { instanceNode.put(Platform.PREF_LINE_SEPARATOR, oldInstanceValue); } instanceNode.flush(); project.delete(true, getMonitor()); } } public void test_336211() throws BackingStoreException, CoreException, IOException { String projectName = getUniqueString(); String nodeName = "node"; IProject project = getProject(projectName); //create project but do not open it yet project.create(getMonitor()); //create file with preferences that will be discovered during refresh File folder = new File(project.getLocation().toOSString() + "/.settings"); folder.mkdir(); BufferedWriter bw = new BufferedWriter(new FileWriter(folder.getPath() + "/" + nodeName + ".prefs")); bw.write("#Fri Jan 28 10:28:45 CET 2011\neclipse.preferences.version=1\nKEY=VALUE"); bw.close(); //create project preference node Preferences projectNode = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE).node(projectName); assertFalse(projectNode.nodeExists(nodeName)); //create node for storing preferences Preferences node = projectNode.node(nodeName); //open the project; the new file will be found during refresh project.open(getMonitor()); //loading preferences from a file must not remove nodes that were previously created assertTrue(node == projectNode.node(nodeName)); assertEquals("VALUE", node.get("KEY", null)); } public void testProjectOpenClose() { IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); String qualifier = getUniqueString(); String key = getUniqueString(); String value = getUniqueString(); Preferences node = new ProjectScope(project).getNode(qualifier); node.put(key, value); try { node.flush(); } catch (BackingStoreException e) { fail("1.0", e); } // close the project try { project.close(getMonitor()); } catch (CoreException e) { fail("1.1", e); } // now reopen the project and ensure the settings were not forgotten try { project.open(getMonitor()); } catch (CoreException e) { fail("2.0", e); } node = new ProjectScope(project).getNode(qualifier); assertEquals("2.1", value, node.get(key, null)); } public void testContentType() { IContentType prefsType = Platform.getContentTypeManager().getContentType(ResourcesPlugin.PI_RESOURCES + ".preferences"); assertNotNull("1.0", prefsType); IContentType associatedType = Platform.getContentTypeManager().findContentTypeFor("some.qualifier." + EclipsePreferences.PREFS_FILE_EXTENSION); assertEquals("1.1", prefsType, associatedType); } public void testListenerOnChangeFile() { // setup IProject project = getProject(getUniqueString()); String qualifier = "org.eclipse.core.tests.resources"; String key = "key" + getUniqueString(); String value = "value" + getUniqueString(); IScopeContext projectContext = new ProjectScope(project); // create project ensureExistsInWorkspace(project, true); // set preferences Preferences node = projectContext.getNode(qualifier); node.put(key, value); Tracer tracer = new Tracer(); ((IEclipsePreferences) node).addPreferenceChangeListener(tracer); String actual = node.get(key, null); assertNotNull("1.0", actual); assertEquals("1.1", value, actual); try { // flush node.flush(); } catch (BackingStoreException e) { fail("0.0", e); } // get settings filename File file = getFileInFilesystem(project, qualifier); Properties props = new Properties(); InputStream input = null; try { input = new BufferedInputStream(new FileInputStream(file)); props.load(input); } catch (IOException e) { fail("1.0", e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { // ignore } } } // reset the listener tracer.log.setLength(0); // change settings in the file String newKey = "newKey" + getUniqueString(); String newValue = "newValue" + getUniqueString(); props.put(newKey, newValue); // save the file via the IFile API IFile workspaceFile = getFileInWorkspace(project, qualifier); ByteArrayOutputStream output = new ByteArrayOutputStream(); try { props.store(output, null); // don't need to close stream since its a byte array } catch (IOException e) { fail("2.0", e); } input = new ByteArrayInputStream(output.toByteArray()); try { workspaceFile.setContents(input, IResource.NONE, getMonitor()); } catch (CoreException e) { fail("2.1", e); } // validate new settings actual = node.get(key, null); assertEquals("4.1", value, actual); actual = node.get(newKey, null); assertEquals("4.2", newValue, actual); // validate the change events assertEquals("4.3", "[" + newKey + ":null->S" + newValue + "]", tracer.log.toString()); } private static IProject getProject(String name) { return getWorkspace().getRoot().getProject(name); } private static IFile getFileInWorkspace(IProject project, String qualifier) { return project.getFile(new Path(DIR_NAME).append(qualifier).addFileExtension(FILE_EXTENSION)); } private static File getFileInFilesystem(IProject project, String qualifier) { return project.getLocation().append(DIR_NAME).append(qualifier).addFileExtension(FILE_EXTENSION).toFile(); } /* * Test to ensure that discovering a new pref file (e.g. loading from a repo) * is the same as doing an import. (ensure the modify listeners are called) */ public void testLoadIsImport() { // setup IProject project = getProject(getUniqueString()); ensureExistsInWorkspace(project, true); IScopeContext context = new ProjectScope(project); String qualifier = "test.load.is.import"; IEclipsePreferences node = context.getNode(qualifier); String key = "key"; String oldValue = "old value"; String newValue = "new value"; IPreferencesService service = Platform.getPreferencesService(); // set the values in the nodes and flush the values to the file system node.put(key, oldValue); try { node.flush(); } catch (BackingStoreException e) { fail("1.99", e); } assertEquals("1.00", oldValue, node.get(key, null)); // copy the data into a buffer for later use File fileInFS = getFileInFilesystem(project, qualifier); InputStream input = null; OutputStream output = null; byte[] buffer = null; try { input = new BufferedInputStream(new FileInputStream(fileInFS)); output = new ByteArrayOutputStream(1024); transferData(input, output); buffer = ((ByteArrayOutputStream) output).toByteArray(); } catch (IOException e) { fail("2.99", e); } // remove the file from the project IFile fileInWS = getFileInWorkspace(project, qualifier); try { fileInWS.delete(IResource.NONE, getMonitor()); } catch (CoreException e) { fail("3.90", e); } assertTrue("3.0", !fileInWS.exists()); assertTrue("3.1", !fileInFS.exists()); IEclipsePreferences projectNode = (IEclipsePreferences) service.getRootNode().node(ProjectScope.SCOPE).node(project.getName()); try { // when the pref file is deleted, the node will be cleared, but not removed assertTrue("3.2", isNodeCleared(projectNode, new String[] {qualifier})); } catch (BackingStoreException e) { fail("3.91", e); } // assertNull("3.3", projectNode.node(qualifier).get(oldKey, null)); // create the file in the project and discover it via a refresh local try { output = new BufferedOutputStream(new FileOutputStream(fileInFS)); } catch (FileNotFoundException e) { fail("4.90", e); } input = new BufferedInputStream(new ByteArrayInputStream(buffer)); transferData(input, output); try { project.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.91", e); } // ensure that the resource changes happen waitForBuild(); // verification - note that the preference modify listener gets called // here so that's why we are checking for "new value" and not the original one node = context.getNode(qualifier); assertEquals("5.0", newValue, node.get(key, null)); } /** * @param node the node to check * @param childrenNames the names of children to check * @return true, if the node and its children have no associated values * @throws BackingStoreException */ private boolean isNodeCleared(Preferences node, String[] childrenNames) throws BackingStoreException { // check if the node has associate values if (node.keys().length != 0) { return false; } // perform a subsequent check for the node children Preferences childNode = null; for (String childrenName : childrenNames) { childNode = node.node(childrenName); if (!isNodeCleared(childNode, childNode.childrenNames())) { return false; } } return true; } public void testChildrenNamesAgainstInitialize() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(""); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(""); String[] childrenNames = node.childrenNames(); assertEquals(1, childrenNames.length); assertEquals(nodeA, childrenNames[0]); node = node.node(nodeA); childrenNames = node.childrenNames(); assertEquals(1, childrenNames.length); assertEquals(nodeB, childrenNames[0]); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testChildrenNamesAgainstLoad() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA); String[] childrenNames = node.childrenNames(); assertEquals(1, childrenNames.length); assertEquals(nodeB, childrenNames[0]); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testClear() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node(nodeB); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA).node(nodeB); node.clear(); assertEquals(0, node.keys().length); assertNull(node.get(key, null)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testGet() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node(nodeB); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA).node(nodeB); assertEquals(value, node.get(key, null)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testKeys() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node(nodeB); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA).node(nodeB); String[] keys = node.keys(); assertEquals(1, keys.length); assertEquals(key, keys[0]); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testNodeExistsAgainstInitialize() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode("nodeC"); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(""); assertTrue(node.nodeExists(nodeA)); node = node.node(nodeA); assertTrue(node.nodeExists(nodeB)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testNodeExistsAgainstLoad() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node("nodeC"); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA); assertTrue(node.nodeExists(nodeB)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testPut() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; String anotherValue = "anotherValue"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node(nodeB); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA).node(nodeB); node.put(key, anotherValue); assertEquals(anotherValue, node.get(key, null)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } public void testRemove() throws BackingStoreException, CoreException { String nodeA = "nodeA"; String nodeB = "nodeB"; String key = "key"; String value = "value"; IProject project1 = getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); Preferences prefs1 = new ProjectScope(project1).getNode(nodeA).node(nodeB); prefs1.put(key, value); prefs1.flush(); assertEquals(value, prefs1.get(key, null)); IProject project2 = getProject(getUniqueString()); project1.move(project2.getFullPath(), IResource.NONE, getMonitor()); Preferences prefs2 = new ProjectScope(project2).getNode(nodeA).node(nodeB); assertEquals(value, prefs2.get(key, null)); // this will trigger the creation of "phantom" preferences node for the now-missing project new ProjectScope(project1).getNode(nodeA).node(nodeB); project2.move(project1.getFullPath(), IResource.NONE, getMonitor()); Preferences node = new ProjectScope(project1).getNode(nodeA).node(nodeB); node.remove(key); assertNull(node.get(key, null)); project1.delete(true, getMonitor()); project2.delete(true, getMonitor()); } }