Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 115716

Summary: XML formatter produces wrong output, and hang up on huge files
Product: [WebTools] WTP Source Editing Reporter: Jochen Hiller <jochen.hiller>
Component: wst.xmlAssignee: Amy Wu <for.work.things>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P2 CC: brian.jakubik, david_williams
Version: 0.7.1   
Target Milestone: 1.5 RC5   
Hardware: PC   
OS: Windows XP   
Whiteboard: PMC_approved
Attachments:
Description Flags
contains all test files
none
org.eclipse.wst.xml.core.patch
none
org.eclipse.wst.xml.core.patch
none
org.eclipse.wst.xml.core.tests.patch none

Description Jochen Hiller CLA 2005-11-09 17:40:55 EST
Hi,

1) see: test1.xml
- Load in XML editor
- Do a format
- will result in test1-format1.xml, which is not the expected result
- Do a format again
- will result in expected format, see test1-format2.xml

2. see: test2.xml
- same applies as above, but with two entries (Yes: file contains two xml files !)

3. see: testn.xml
- same with about >100 entries of same structure
- will either hangup completely, or take a lot of time to format the xml
content. Normally, you have to kill the process, as machine hangs completely

Bye, Jochen
Comment 1 Jochen Hiller CLA 2005-11-09 17:42:44 EST
Created attachment 29650 [details]
contains all test files
Comment 2 David Williams CLA 2005-11-10 05:32:11 EST
Thanks, we've got a couple of these and will (try) and flush out formatting 
issues before 1.0. 

Comment 3 Amy Wu CLA 2006-06-05 18:56:10 EDT
The poor performance in XML formatting is being tracked in bug 102822.
As for the wrong output, if you hit enter at the end of the file and add an additional line, everything will format correctly.  I believe the problem lies in everything sitting on the first line of the file and how the formatter is looking up the line delimiter.  It looks like the formatter is trying to find the line delimiter of the last line, and since there is none, it does not add a line delimiter.  The fix is if no line delimiter is found, use the default line delimiter for the document.

org.eclipse.wst.xml.core.internal.provisional.format.NodeFormatter
#formatIndentationAfterNode
CHANGE:
	String lineDelimiter = doc.getLineDelimiter();
	try {
		lineDelimiter = doc.getLineDelimiter(line);
		if (lineDelimiter == null)
			lineDelimiter = ""; //$NON-NLS-1$
	}
	catch (BadLocationException e) {
		// log for now, unless we find reason not to
		Logger.log(Logger.INFO, e.getMessage());
	}

TO THIS:
	String lineDelimiter = doc.getLineDelimiter();
	try {
		lineDelimiter = doc.getLineDelimiter(line);
	}
	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();
Comment 4 Amy Wu CLA 2006-06-05 18:57:14 EDT
Created attachment 43550 [details]
org.eclipse.wst.xml.core.patch
Comment 5 Amy Wu CLA 2006-06-05 19:05:18 EDT
I'm seeing 2 unit test failures, and it looks like it may be issues with the very last line delimiter at the end of the file.  So I may have to rethink this fix slightly.  (Though I think this fix is better than what we currently have)
Comment 6 Amy Wu CLA 2006-06-06 03:16:23 EDT
Created attachment 43569 [details]
org.eclipse.wst.xml.core.patch

Okay, I figured out the end of file line delimiter issue.  Fix is the same as stated earlier, but I've added additional checks so that when formatting the last node, do not add a line delimiter at the end.
-ElementNodeFormatter#formatNode
==>// only indent if not at last node
==>if (newNode != null && newNode.getNextSibling() != null)
	// format indentation after node
	formatIndentationAfterNode(newNode, formatContraints);
-NodeFormatter#formatIndentationAfterNode
else {
==>	// as long as not at the end of the document
==>	IStructuredDocumentRegion endRegion = node.getLastStructuredDocumentRegion();
==>	if (endRegion != null && endRegion.getNext() != null)
		// append indentation
		insertAfterNode(lastChild, lineDelimiter + lineIndent);
}
I also noticed the same if linedelimiter == null linedelimiter = "" mistake in NodeFormatter#formatIndentationBeforeNode so i went ahead and corrected the logic in that method as well.
Comment 7 Amy Wu CLA 2006-06-06 03:18:05 EDT
Created attachment 43570 [details]
org.eclipse.wst.xml.core.tests.patch

And now the JUnit tests all pass.  And to make sure this bug stays fixed, I added a unit test to check formatting of one line.
Comment 8 David Williams CLA 2006-06-06 10:46:24 EDT
Excellent, thanks Amy. 

Comment 9 David Williams CLA 2006-06-06 14:36:44 EDT
+1
Comment 10 Tim Wagner CLA 2006-06-06 15:07:12 EDT
+1 1.5
Comment 11 Amy Wu CLA 2006-06-06 17:09:26 EDT
Released fix for 1.5RC5.
Comment 12 Jochen Hiller CLA 2006-09-25 12:27:25 EDT
Hi all,

RETESTED: FINE

I did a retest of my posted XML files. It is now working quite well, the formatting results always in same and expected result.

Performance is OK. On a 2 GHz Notebook, it takes about 3 seconds to open a XML file with about 40k. Maybe that really huge files may yet be slow.

Thanks for your quite good work.
Comment 13 Amy Wu CLA 2006-09-25 16:29:19 EDT
thanks, closing
Comment 14 Amy Wu CLA 2006-10-25 18:54:51 EDT
*** Bug 159349 has been marked as a duplicate of this bug. ***