diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java index 34897c916cd..5bb689b6b00 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java @@ -37,6 +37,7 @@ import javax.xml.transform.stream.StreamResult; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager; +import org.eclipse.cdt.internal.core.XmlUtil; import org.eclipse.cdt.internal.core.settings.model.ICProjectDescriptionStorageType.CProjectDescriptionStorageTypeProxy; import org.eclipse.cdt.internal.core.settings.model.xml.XmlProjectDescriptionStorage; import org.eclipse.cdt.internal.core.settings.model.xml2.XmlProjectDescriptionStorage2; @@ -160,6 +161,7 @@ public class CProjectDescriptionStorageManager { Element el = doc.createElement(ICProjectDescriptionStorageType.STORAGE_ROOT_ELEMENT_NAME); el.setAttribute(ICProjectDescriptionStorageType.STORAGE_TYPE_ATTRIBUTE, type.id); doc.appendChild(el); + XmlUtil.prettyFormat(doc); ByteArrayOutputStream stream = new ByteArrayOutputStream(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); 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 890131e99c2..ccfc43fee95 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 @@ -40,6 +40,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingsStorage; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.core.settings.model.extension.ICProjectConverter; 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.settings.model.AbstractCProjectDescriptionStorage; import org.eclipse.cdt.internal.core.settings.model.CProjectDescription; @@ -463,6 +464,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto */ private ByteArrayOutputStream write(ICStorageElement element) throws CoreException { Document doc = ((InternalXmlStorageElement) element).fElement.getOwnerDocument(); + XmlUtil.prettyFormat(doc); ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { 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 new file mode 100644 index 00000000000..7e220e90431 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2009, 2009 Andrew Gvozdev (Quoin Inc.). + * 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: + * Andrew Gvozdev (Quoin Inc.) + *******************************************************************************/ +package org.eclipse.cdt.internal.core; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * XML utilities. + * + */ +public class XmlUtil { + private static final String EOL_XML = "\n"; //$NON-NLS-1$ + private static final String DEFAULT_IDENT = "\t"; //$NON-NLS-1$ + + /** + * As a workaround for {@code javax.xml.transform.Transformer} not being able + * to pretty print XML. This method prepares DOM {@code Document} for the transformer + * to be pretty printed, i.e. providing proper indentations for enclosed tags. + * + * @param doc - DOM document to be pretty printed + */ + public static void prettyFormat(Document doc) { + prettyFormat(doc, DEFAULT_IDENT); + } + + /** + * As a workaround for {@code javax.xml.transform.Transformer} not being able + * to pretty print XML. This method prepares DOM {@code Document} for the transformer + * to be pretty printed, i.e. providing proper indentations for enclosed tags. + * + * @param doc - DOM document to be pretty printed + * @param ident - custom indentation as a string of white spaces + */ + public static void prettyFormat(Document doc, String ident) { + doc.normalize(); + prettyFormat(doc.getDocumentElement(), "", ident); //$NON-NLS-1$ + } + + /** + * The method inserts end-of-line+indentation Text nodes where indentation is necessary. + * + * @param node - node to be pretty formatted + * @param identLevel - initial indentation level of the node + * @param ident - additional indentation inside the node + */ + private static void prettyFormat(Node node, String identLevel, String ident) { + NodeList nodelist = node.getChildNodes(); + int iStart=0; + Node item = nodelist.item(0); + if (item!=null) { + short type = item.getNodeType(); + if (type==Node.ELEMENT_NODE || type==Node.COMMENT_NODE) { + Node newChild = node.getOwnerDocument().createTextNode(EOL_XML + identLevel + ident); + node.insertBefore(newChild, item); + iStart=1; + } + } + for (int i=iStart;i