diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java
index d7ea664574b..a9ea09964e7 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java
@@ -36,6 +36,7 @@ import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.internal.core.XmlUtil;
+import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings;
import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo;
import org.eclipse.cdt.internal.core.settings.model.SettingsModelMessages;
@@ -557,7 +558,11 @@ public class LanguageSettingsProvidersSerializer {
try {
serializingLockWsp.acquire();
- XmlUtil.serializeXml(doc, uriStoreWsp);
+ String eol = Util.getLineSeparator(uriStoreWsp);
+ if (eol == null) {
+ eol = Util.getDefaultLineSeparator();
+ }
+ XmlUtil.serializeXml(doc, uriStoreWsp, eol);
// manufacture events while inside the lock
events = createLanguageSettingsChangeEvents(broadcastingWorkspaceProviders);
} finally {
@@ -881,7 +886,11 @@ public class LanguageSettingsProvidersSerializer {
if (isWorkspaceStoreEmpty) {
new java.io.File(uriStoreWsp).delete();
} else {
- XmlUtil.serializeXml(docStoreWsp, uriStoreWsp);
+ String eol = Util.getLineSeparator(uriStoreWsp);
+ if (eol == null) {
+ eol = Util.getDefaultLineSeparator(project);
+ }
+ XmlUtil.serializeXml(docStoreWsp, uriStoreWsp, eol);
}
// manufacture the event only if serialization was successful
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 d095c94cda7..86bfac18507 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
@@ -16,6 +16,7 @@
package org.eclipse.cdt.internal.core.model;
import java.io.BufferedInputStream;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -30,6 +31,7 @@ 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.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -412,7 +414,10 @@ public class Util implements ICLogConstants {
// not found
return null;
}
-
+
+ /**
+ * Returns value of line separator preference from the given preference node.
+ */
private static String getLineSeparatorFromPreferences(Preferences node) {
try {
// be careful looking up for our node so not to create any nodes as side effect
@@ -425,54 +430,103 @@ public class Util implements ICLogConstants {
}
/**
- * Returns line separator appropriate for the given file. The returned value
+ * Returns the first line separator found in the given file.
+ *
+ * @param fileUri - URI if the file on the local file-system.
+ * @return the first line separator in the given file or {@code null} if none was read.
+ */
+ public static String getLineSeparator(URI fileUri) {
+ String value = null;
+ InputStream input = null;
+ try {
+ java.io.File file = new java.io.File(fileUri);
+ if (file.exists()) {
+ input = new FileInputStream(file);
+ value = getLineSeparator(input);
+ }
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ try {
+ if (input != null)
+ input.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Returns the line separator for the given file. If line separator is not found in the file
+ * default value for the project or workspace is returned.
+ *
+ * @param file - the file to look for a line separator.
+ * @return the line separator for the given file. The method does not return {@code null}.
+ */
+ public static String getLineSeparator(IFile file) {
+ String value = null;
+ InputStream input = null;
+ try {
+ input = file.getContents();
+ value = getLineSeparator(input);
+ } catch (CoreException e) {
+ // ignore
+ } finally {
+ try {
+ if (input != null)
+ input.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+
+ if (value == null)
+ value = getDefaultLineSeparator(file.getProject());
+
+ return value;
+ }
+
+ /**
+ * Returns default line separator for the given project. The returned value
* will be the first available value from the list below:
*
- * - Line separator currently used in that file.
*
- Line separator defined in project preferences.
*
- Line separator defined in instance preferences.
*
- Line separator defined in default preferences.
*
- 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
+ * @param project - the project. If {@code null} no project preferences are inquired.
+ * @return line separator for the given project. The method does not return {@code null}.
*/
- 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
- }
- }
+ public static String getDefaultLineSeparator(IProject project) {
+ String value = null;
+ Preferences rootNode = Platform.getPreferencesService().getRootNode();
+ // if the file does not exist or has no content yet, try with project preferences
+ if (project != null) {
+ value = getLineSeparatorFromPreferences(rootNode.node(ProjectScope.SCOPE).node(project.getName()));
+ if (value != null)
+ return value;
}
+ value = getDefaultLineSeparator();
+ return value;
+ }
+
+ /**
+ * Returns default line separator for the workspace. The returned value
+ * will be the first available value from the list below:
+ *
+ * - Line separator defined in instance preferences.
+ *
- Line separator defined in default preferences.
+ *
- Operating system default line separator.
+ *
+ * @return line separator for the workspace. The method does not return {@code null}.
+ */
+ public static String getDefaultLineSeparator() {
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)
@@ -485,6 +539,31 @@ public class Util implements ICLogConstants {
return LINE_SEPARATOR;
}
+ /**
+ * Returns the first line separator used by the input stream.
+ *
+ * @param input - input stream to inspect.
+ * @return line separator for the given input stream or {@code null} if no line separator was read.
+ */
+ private static String getLineSeparator(InputStream input) {
+ try {
+ 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') {
+ int c2 = input.read();
+ if (c2 == '\n')
+ return "\r\n"; //$NON-NLS-1$
+ return "\r"; //$NON-NLS-1$
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ return null;
+ }
+
/**
* 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 3c5b78b11dc..c4b542662b5 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
@@ -121,7 +121,6 @@ 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);
@@ -573,12 +572,8 @@ 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);
+ String eol = Util.getLineSeparator(projectFile);
+ utfString = XmlUtil.replaceLineSeparatorInternal(utfString, eol);
} finally {
if (stream != null)
stream.close(); // Cleanup the stream
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java
index dfdbf9120e4..adb4d29a5e2 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java
@@ -35,6 +35,7 @@ import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper;
import org.eclipse.cdt.core.errorparsers.RegexErrorParser;
import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
import org.eclipse.cdt.internal.core.XmlUtil;
+import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
@@ -314,7 +315,11 @@ public class ErrorParserExtensionManager {
}
}
- XmlUtil.serializeXml(doc, getStoreURI(STORAGE_ERRORPARSER_EXTENSIONS));
+ URI uri = getStoreURI(STORAGE_ERRORPARSER_EXTENSIONS);
+ String eol = Util.getLineSeparator(uri);
+ if (eol == null)
+ eol = Util.getDefaultLineSeparator();
+ XmlUtil.serializeXml(doc, uri, eol);
} catch (Exception e) {
throw new CoreException(CCorePlugin.createStatus("Failed serializing to file " + STORAGE_ERRORPARSER_EXTENSIONS, e)); //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
index 76ffb5efe70..2f860bbab12 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
@@ -17,6 +17,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.net.URI;
import javax.xml.parsers.DocumentBuilder;
@@ -31,6 +32,7 @@ import javax.xml.transform.stream.StreamResult;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.resources.ResourcesUtil;
+import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
@@ -45,8 +47,10 @@ import org.w3c.dom.NodeList;
*
*/
public class XmlUtil {
+ private static final String ENCODING_UTF_8 = "UTF-8"; //$NON-NLS-1$
private static final String EOL_XML = "\n"; //$NON-NLS-1$
private static final String DEFAULT_IDENT = "\t"; //$NON-NLS-1$
+ private static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
/**
* Convenience method to create new XML DOM Document.
@@ -97,7 +101,7 @@ public class XmlUtil {
Document doc = parent instanceof Document ? (Document)parent : parent.getOwnerDocument();
Element element = doc.createElement(name);
if (attributes!=null) {
- int attrLen = attributes.length;
+ int attrLen = attributes.length;
for (int i=0;iDo not use outside of CDT. This method is a workaround for {@link javax.xml.transform.Transformer}
+ * not being able to specify the line separator. This method replaces a string generated by
+ * {@link javax.xml.transform.Transformer} which contains the system line.separator with the line separators
+ * from an existing file or the preferences if it's a new file.
+ *
+ * @param string - the string to be replaced
+ * @param lineSeparator - line separator to be used in the string
+ *
+ * @noreference This method is not intended to be referenced by clients.
+ * This is an internal method which ideally should be made private.
+ */
+ public static String replaceLineSeparatorInternal(String string, String lineSeparator) {
+ string = string.replace(LINE_SEPARATOR, lineSeparator);
+ return string;
+ }
+
/**
* Serialize XML Document into a workspace file.
* Note: clients should synchronize access to this method.
@@ -361,11 +380,18 @@ public class XmlUtil {
public static void serializeXml(Document doc, IFile file) throws CoreException {
XmlUtil.prettyFormat(doc);
- InputStream input = new ByteArrayInputStream(toByteArray(doc));
- if (file.exists()) {
- file.setContents(input, IResource.FORCE, null);
- } else {
- file.create(input, IResource.FORCE, null);
+ try {
+ String utfString = new String(toByteArray(doc), ENCODING_UTF_8);
+ String lineSeparator = Util.getLineSeparator(file);
+ utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator);
+ InputStream input = new ByteArrayInputStream(utfString.getBytes(ENCODING_UTF_8));
+
+ if (file.exists()) {
+ file.setContents(input, IResource.FORCE, null);
+ } else {
+ file.create(input, IResource.FORCE, null);
+ }
+ } catch (UnsupportedEncodingException e) {
}
}