diff options
Diffstat (limited to 'bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/provisional/format/TextNodeFormatter.java')
-rw-r--r-- | bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/provisional/format/TextNodeFormatter.java | 385 |
1 files changed, 0 insertions, 385 deletions
diff --git a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/provisional/format/TextNodeFormatter.java b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/provisional/format/TextNodeFormatter.java deleted file mode 100644 index 873ab766e4..0000000000 --- a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/provisional/format/TextNodeFormatter.java +++ /dev/null @@ -1,385 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2008 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 - * Jens Lukowski/Innoopract - initial renaming/restructuring - * Jesper Steen Møller - xml:space='preserve' support - * - *******************************************************************************/ -package org.eclipse.wst.xml.core.internal.provisional.format; - -import java.util.List; -import java.util.Vector; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.wst.sse.core.internal.format.IStructuredFormatContraints; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.eclipse.wst.sse.core.utils.StringUtils; -import org.eclipse.wst.xml.core.internal.Logger; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.w3c.dom.Node; - - -public class TextNodeFormatter extends NodeFormatter { - static private final String CR = "\r"; //$NON-NLS-1$ - static private final String DELIMITERS = " \t\n\r\f"; //$NON-NLS-1$ - static private final String EMPTY_STRING = ""; //$NON-NLS-1$ - static private final String FF = "\f"; //$NON-NLS-1$ - static private final String LF = "\n"; //$NON-NLS-1$ - static private final String SPACE = " "; //$NON-NLS-1$ - static private final String TAB = "\t"; //$NON-NLS-1$ - - private String compressSpaces(String string, IStructuredFormatContraints formatContraints) { - /* - * Note that the StructuredTextEditor supports mixed new line - * characters (CR, LF, CRLF) in one file. We have to handle that when - * we try to preserve blank lines. - */ - String[] stringArray = null; - boolean clearAllBlankLines = formatContraints.getClearAllBlankLines(); - - if (clearAllBlankLines) - stringArray = StringUtils.asArray(string); - else - stringArray = StringUtils.asArray(string, DELIMITERS, true); - - StringBuffer compressedString = new StringBuffer(); - if (stringArray.length > 0) { - boolean cr = false, lf = false, cr2 = false, nonSpace = true; - - if (stringArray[0].compareTo(CR) == 0) - cr = true; - else if (stringArray[0].compareTo(LF) == 0) - lf = true; - else if ((stringArray[0].compareTo(SPACE) != 0) && (stringArray[0].compareTo(TAB) != 0) && (stringArray[0].compareTo(FF) != 0)) { - compressedString.append(stringArray[0]); - nonSpace = true; - } - - for (int i = 1; i < stringArray.length; i++) { - if (stringArray[i].compareTo(CR) == 0) { - if (cr && lf) { - if (nonSpace) { - compressedString.append(CR + LF); - nonSpace = false; - } - compressedString.append(stringArray[i]); - cr2 = true; - } - else if (cr) { - if (nonSpace) { - compressedString.append(CR); - nonSpace = false; - } - compressedString.append(stringArray[i]); - cr2 = true; - } - else - cr = true; - } - else if (stringArray[i].compareTo(LF) == 0) { - if (cr && lf && cr2) { - compressedString.append(stringArray[i]); - } - else if (lf) { - if (nonSpace) { - compressedString.append(LF); - nonSpace = false; - } - compressedString.append(stringArray[i]); - } - else - lf = true; - } - else if ((stringArray[i].compareTo(SPACE) != 0) && (stringArray[i].compareTo(TAB) != 0) && (stringArray[i].compareTo(FF) != 0)) { - if (compressedString.length() > 0) - compressedString.append(SPACE); - compressedString.append(stringArray[i]); - - cr = false; - lf = false; - cr2 = false; - nonSpace = true; - } - } - } - - return compressedString.toString(); - } - - protected void formatNode(IDOMNode node, IStructuredFormatContraints formatContraints) { - // [111674] If inside xml:space="preserve" element, we bail - if (formatContraints.getInPreserveSpaceElement()) - return; - if (node != null) { - IStructuredDocument doc = node.getStructuredDocument(); - - int lineWidth = getFormatPreferences().getLineWidth(); - int currentAvailableLineWidth = computeAvailableLineWidth(doc, node.getStartOffset(), lineWidth); - - String nodeText = getNodeText(node); - String compressedText = compressSpaces(nodeText, formatContraints); - - IDOMNode parentNode = (IDOMNode) node.getParentNode(); - - if (((enoughSpace(parentNode, currentAvailableLineWidth, compressedText)) && (noSiblingsAndNoFollowingComment(node)) && !firstStructuredDocumentRegionContainsLineDelimiters(parentNode)) || node.getStartOffset() == 0) { - handleNoReflow(node, doc, compressedText, parentNode); - } - else { - // not enough space, need to reflow text - String nodeIndentation = formatContraints.getCurrentIndent(); - currentAvailableLineWidth = lineWidth - getIndentationLength(nodeIndentation); - List vector = reflowText(compressedText, currentAvailableLineWidth); - int vectorSize = vector.size(); - StringBuffer reflowedTextBuffer = new StringBuffer(); - String lineDelimiter = getLineDelimiter(doc, node.getStartOffset()); - // handle first line specially to check for allowWhitespace - if (vectorSize > 0) { - // determines whether or not to allow whitespace if there - // is an entity or cdata before it - boolean allowWhitespace = true; - // [206072] StringIndexOutOfBoundsException - if (nodeText.length() == 0 || !Character.isWhitespace(nodeText.charAt(0))) { - Node previousSibling = node.getPreviousSibling(); - if (previousSibling != null && (previousSibling.getNodeType() == Node.ENTITY_REFERENCE_NODE || previousSibling.getNodeType() == Node.CDATA_SECTION_NODE)) - allowWhitespace = false; - } - String theString = (String) vector.get(0); - if (allowWhitespace) { - reflowedTextBuffer.append(lineDelimiter); - if (theString.trim().length() > 0) - reflowedTextBuffer.append(nodeIndentation).append(theString); - } - else { - reflowedTextBuffer.append(theString); - } - } - // do the rest of the lines - for (int i = 1; i < vectorSize; i++) { - String theString = (String) vector.get(i); - if (theString.trim().length() > 0) - reflowedTextBuffer.append(lineDelimiter).append(nodeIndentation).append(theString); - else - reflowedTextBuffer.append(lineDelimiter); - } - String reflowedText = reflowedTextBuffer.toString(); - if (node.getNextSibling() == null) { - if (isEndTagMissing(parentNode)) { - // don't add indentation to end if parent end tag is - // missing - } - - else { - // add parent's indentation to end - nodeIndentation = getNodeIndent(parentNode); - if (!reflowedText.endsWith(lineDelimiter + nodeIndentation)) { - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, lineDelimiter); - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, nodeIndentation); - } - } - } - else { - if (!reflowedText.endsWith(lineDelimiter + nodeIndentation)) { - // not already ended with the expected indentation - Node nextSibling = node.getNextSibling(); - if (nextSibling.getNodeType() == Node.COMMENT_NODE) { - // add indentation to end if - // currentTextEndsWithLineDelimiter - // or followed by multiLineComment - - int indexOfLastLineDelimiter = StringUtils.indexOfLastLineDelimiter(nodeText); - boolean currentTextEndsWithLineDelimiter = indexOfLastLineDelimiter != -1; - if (currentTextEndsWithLineDelimiter) { - // no more non blank character after the last - // line delimiter - currentTextEndsWithLineDelimiter = StringUtils.indexOfNonblank(nodeText, indexOfLastLineDelimiter) == -1; - } - - String nodeValue = nextSibling.getNodeValue(); - boolean multiLineComment = StringUtils.containsLineDelimiter(nodeValue); - - if (currentTextEndsWithLineDelimiter || multiLineComment) { - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, lineDelimiter); - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, nodeIndentation); - } - } - else if (nextSibling.getNodeType() == Node.ENTITY_REFERENCE_NODE || nextSibling.getNodeType() == Node.CDATA_SECTION_NODE) { - int textLength = nodeText.length(); - if (textLength > 0 && Character.isWhitespace(nodeText.charAt(textLength - 1))) { - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, lineDelimiter); - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, nodeIndentation); - } - } - else { - // not a comment, just add add indentation to end - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, lineDelimiter); - reflowedText = StringUtils.appendIfNotEndWith(reflowedText, nodeIndentation); - } - } - } - - replaceNodeValue(node, reflowedText); - } - } - } - - /** - * Keeps text inline with its parent (no reflow necessary) - * - * @param node - * @param doc - * @param compressedText - * @param parentNode - */ - private void handleNoReflow(IDOMNode node, IStructuredDocument doc, String compressedText, IDOMNode parentNode) { - String nodeIndentation; - // enough space and text has no line delimiters and (node has no - // siblings or followed by inline comment) and - // parentFirstStructuredDocumentRegionContainsLineDelimiters - - if (isEndTagMissing(parentNode)) { - parentNode = (IDOMNode) parentNode.getParentNode(); - while (isEndTagMissing(parentNode)) - parentNode = (IDOMNode) parentNode.getParentNode(); - - // add parent's indentation to end - nodeIndentation = getNodeIndent(parentNode); - String lineDelimiter = getLineDelimiter(doc, node.getStartOffset()); - if (!compressedText.endsWith(lineDelimiter + nodeIndentation)) { - compressedText = StringUtils.appendIfNotEndWith(compressedText, lineDelimiter); - compressedText = StringUtils.appendIfNotEndWith(compressedText, nodeIndentation); - } - } - - if ((parentNode != null) && (parentNode.getNodeType() == Node.DOCUMENT_NODE) && (node.getNodeValue().length() > 0) && (node.getNodeValue().trim().length() == 0) && ((node.getPreviousSibling() == null) || (node.getNextSibling() == null))) - // delete spaces at the beginning or end of the document - compressedText = EMPTY_STRING; - - replaceNodeValue(node, compressedText); - } - - private boolean noSiblingsAndNoFollowingComment(IDOMNode node) { - IDOMNode nextSibling = (IDOMNode) node.getNextSibling(); - return !nodeHasSiblings(node) || (noLineDelimiter(node) && isComment(nextSibling) && noLineDelimiter(nextSibling)); - } - - private boolean isComment(IDOMNode node) { - boolean result = false; - if (node != null) { - result = node.getNodeType() == Node.COMMENT_NODE; - } - return result; - } - - private boolean noLineDelimiter(IDOMNode node) { - boolean result = false; - if (node != null) { - result = !StringUtils.containsLineDelimiter(node.getNodeValue()); - } - return result; - } - - /** - * Calculates if there is enough space on the current line for - * compressedText (and for its parent end tag) - * - * @param parentNode - * @param currentAvailableLineWidth - * @param compressedText - * @return - */ - private boolean enoughSpace(IDOMNode parentNode, int currentAvailableLineWidth, String compressedText) { - int parentEndTagLength = parentNode.getNodeName().length() + 3; - return compressedText.length() <= (currentAvailableLineWidth - parentEndTagLength) && !StringUtils.containsLineDelimiter(compressedText); - } - - protected Vector reflowText(String text, int availableWidth) { - String[] stringArray = null; - boolean clearAllBlankLines = getFormatPreferences().getClearAllBlankLines(); - - if (clearAllBlankLines) - stringArray = StringUtils.asArray(text); - else - stringArray = StringUtils.asArray(text, DELIMITERS, true); - - Vector output = new Vector(); - if ((stringArray != null) && (stringArray.length > 0)) { - StringBuffer buffer = new StringBuffer(); - if (stringArray[0].compareTo(CR) != 0) - buffer.append(stringArray[0]); - int bufferLength = stringArray[0].toString().length(); - boolean cr = stringArray[0].compareTo(CR) == 0; - - for (int i = 1; i < stringArray.length; i++) { - String eachString = stringArray[i]; - if ((eachString.compareTo(SPACE) != 0) && (eachString.compareTo(TAB) != 0) && (eachString.compareTo(FF) != 0)) { - if ((bufferLength + 1 + eachString.length() > availableWidth) || (eachString.compareTo(CR) == 0) || (eachString.compareTo(LF) == 0)) { - if ((eachString.compareTo(LF) == 0) && cr) { - // do nothing - } - else { - output.add(buffer.toString()); - buffer = new StringBuffer(); - bufferLength = 0; - } - cr = eachString.compareTo(CR) == 0; - } - else if (buffer.toString().trim().length() > 0) { - buffer.append(SPACE); - bufferLength++; - } - if ((eachString.compareTo(CR) != 0) && (eachString.compareTo(LF) != 0)) { - buffer.append(eachString); - bufferLength = bufferLength + eachString.length(); - } - } - } - output.add(buffer.toString()); - } - else - output.add(text); - - return output; - } - - private String getLineDelimiter(IStructuredDocument doc, int nodeOffset) { - int line = doc.getLineOfOffset(nodeOffset); - String lineDelimiter = doc.getLineDelimiter(); - try { - if (line > 0) { - lineDelimiter = doc.getLineDelimiter(line - 1); - } - } - catch (BadLocationException e) { - // log for now, unless we find reason not to - Logger.log(Logger.INFO, e.getMessage()); - } - // BUG115716: if cannot get line delimiter from current line, just - // use default line delimiter - if (lineDelimiter == null) - lineDelimiter = doc.getLineDelimiter(); - return lineDelimiter; - } - - private int computeAvailableLineWidth(IStructuredDocument doc, int nodeOffset, int lineWidth) { - // compute current available line width - int currentAvailableLineWidth = 0; - try { - int lineOffset = doc.getLineInformationOfOffset(nodeOffset).getOffset(); - String text = doc.get(lineOffset, nodeOffset - lineOffset); - int usedWidth = getIndentationLength(text); - currentAvailableLineWidth = lineWidth - usedWidth; - } - catch (BadLocationException e) { - // log for now, unless we find reason not to - Logger.log(Logger.INFO, e.getMessage()); - } - return currentAvailableLineWidth; - } - -} |