From a7f9c65430432afc09dd80a937737c9e97381e89 Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Sun, 11 Aug 2013 23:22:23 -0400 Subject: [PATCH] Bug 414831 - .cproject line delimiters change to the system default when saving Reused some code from org.eclipse.core.internal.utils.FileUtil to determine the line separator to use when saving the .cproject. Change-Id: Ibda9724bdc73143c2ec37601727bec024d3dca26 Signed-off-by: Marc-Andre Laperle Reviewed-on: https://git.eclipse.org/r/15399 Reviewed-by: Andrew Gvozdev IP-Clean: Andrew Gvozdev Tested-by: Andrew Gvozdev --- .../eclipse/cdt/internal/core/model/Util.java | 81 ++++++++++++++++++- .../xml/XmlProjectDescriptionStorage.java | 19 +++-- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java index dac4ec123c8..d095c94cda7 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2012 IBM Corporation and others. + * Copyright (c) 2002, 2013 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 @@ -10,6 +10,7 @@ * Markus Schorn (Wind River Systems) * Anton Leherbauer (Wind River Systems) * IBM Corporation - EFS support + * Marc-Andre Laperle (Ericsson) *******************************************************************************/ package org.eclipse.cdt.internal.core.model; @@ -29,10 +30,16 @@ import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; import com.ibm.icu.text.MessageFormat; @@ -405,6 +412,78 @@ public class Util implements ICLogConstants { // not found return null; } + + private static String getLineSeparatorFromPreferences(Preferences node) { + try { + // be careful looking up for our node so not to create any nodes as side effect + if (node.nodeExists(Platform.PI_RUNTIME)) + return node.node(Platform.PI_RUNTIME).get(Platform.PREF_LINE_SEPARATOR, null); + } catch (BackingStoreException e) { + // ignore + } + return null; + } + + /** + * Returns line separator appropriate for the given file. The returned value + * will be the first available value from the list below: + *
    + *
  1. Line separator currently used in that file. + *
  2. Line separator defined in project preferences. + *
  3. Line separator defined in instance preferences. + *
  4. Line separator defined in default preferences. + *
  5. Operating system default line separator. + *
+ * @param file the file for which line separator should be returned + * @return line separator for the given file + * + * Note: This was copied from org.eclipse.core.internal.utils.FileUtil + */ + public static String getLineSeparator(IFile file) { + if (file.exists()) { + InputStream input = null; + try { + input = file.getContents(); + int c = input.read(); + while (c != -1 && c != '\r' && c != '\n') + c = input.read(); + if (c == '\n') + return "\n"; //$NON-NLS-1$ + if (c == '\r') { + if (input.read() == '\n') + return "\r\n"; //$NON-NLS-1$ + return "\r"; //$NON-NLS-1$ + } + } catch (CoreException e) { + // ignore + } catch (IOException e) { + // ignore + } finally { + try { + if (input != null) + input.close(); + } catch (IOException e) { + //ignore + } + } + } + Preferences rootNode = Platform.getPreferencesService().getRootNode(); + String value = null; + // if the file does not exist or has no content yet, try with project preferences + value = getLineSeparatorFromPreferences(rootNode.node(ProjectScope.SCOPE).node(file.getProject().getName())); + if (value != null) + return value; + // try with instance preferences + value = getLineSeparatorFromPreferences(rootNode.node(InstanceScope.SCOPE)); + if (value != null) + return value; + // try with default preferences + value = getLineSeparatorFromPreferences(rootNode.node(DefaultScope.SCOPE)); + if (value != null) + return value; + // if there is no preference set, fall back to OS default value + return LINE_SEPARATOR; + } /** * Return true if the file is not a directory and has length > 0 diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java index ee65ea7b3b6..3c5b78b11dc 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java @@ -1,15 +1,16 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Intel Corporation and others. + * Copyright (c) 2007, 2013 Intel 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: - * Intel Corporation - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation - * James Blackburn (Broadcom Corp.) + * Intel Corporation - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation + * James Blackburn (Broadcom Corp.) + * Marc-Andre Laperle (Ericsson) *******************************************************************************/ package org.eclipse.cdt.internal.core.settings.model.xml; @@ -43,6 +44,7 @@ import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.internal.core.XmlUtil; import org.eclipse.cdt.internal.core.envvar.ContributedEnvironment; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; +import org.eclipse.cdt.internal.core.model.Util; import org.eclipse.cdt.internal.core.settings.model.AbstractCProjectDescriptionStorage; import org.eclipse.cdt.internal.core.settings.model.CProjectDescription; import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; @@ -119,6 +121,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto static final String CONFIGURATION = "cconfiguration"; //$NON-NLS-1$ private static final QualifiedName LOAD_FLAG = new QualifiedName(CCorePlugin.PLUGIN_ID, "descriptionLoadded"); //$NON-NLS-1$ + private static final String LINE_SEPARATOR = "line.separator"; //$NON-NLS-1$ public XmlProjectDescriptionStorage(CProjectDescriptionStorageTypeProxy type, IProject project, Version version) { super(type, project, version); @@ -570,6 +573,12 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto // Get the ProjectDescription as a utf-8 string stream = write(element); utfString = stream.toString("UTF-8"); //$NON-NLS-1$ + + // Make sure we keep the same line separator if the file exists + // or use the preferences if it's a new file + String fileLineSeparator = Util.getLineSeparator(projectFile); + String sysLineSeparator = System.getProperty(LINE_SEPARATOR); + utfString = utfString.replace(sysLineSeparator, fileLineSeparator); } finally { if (stream != null) stream.close(); // Cleanup the stream