-
-
Notifications
You must be signed in to change notification settings - Fork 229
Feature : Allow setting custom linefeed on DefaultXmlPrettyPrinter #568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
374e125
eb23bbd
c0b3e41
3b066cb
8595328
79564a4
f515eba
4cc4394
6974014
b75bfdd
18abcc2
c764189
af70ece
7deeb84
8360276
6187f3d
d0aaf64
29a2bbf
fc4fb17
dd198f2
b43811c
05b1f04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,22 @@ public interface Indenter | |
*/ | ||
protected boolean _spacesInObjectEntries = true; | ||
|
||
/** | ||
* By default, will try to set as System.getProperty("line.separator"). | ||
* Can later set custom lineFeed with withCustomlineFeed method. | ||
* @since 2.15 | ||
*/ | ||
private final static String DEFAULT_LINE_FEED; | ||
static { | ||
String lf = null; | ||
try { | ||
lf = System.getProperty("line.separator"); | ||
} catch (Throwable t) { } // access exception? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's just catch There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. late reply, but done 👍🏻 |
||
DEFAULT_LINE_FEED = lf; | ||
} | ||
|
||
protected String _lineFeed = DEFAULT_LINE_FEED; | ||
|
||
/* | ||
/********************************************************** | ||
/* State | ||
|
@@ -126,6 +142,18 @@ public void indentObjectsWith(Indenter i) | |
|
||
public void spacesInObjectEntries(boolean b) { _spacesInObjectEntries = b; } | ||
|
||
/** | ||
* Sets custom linefeed | ||
* @since 2.15 | ||
*/ | ||
public DefaultXmlPrettyPrinter withCustomLineFeed(String lineFeed) { | ||
// 06-Feb-2023, joohyukkim: when JacksonException extends RuntimeExceptions, throw it? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you remove this comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done :) |
||
if (lineFeed != null) { | ||
_lineFeed = lineFeed; | ||
} | ||
return this; | ||
pjfanning marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/* | ||
/********************************************************** | ||
/* Instantiatable impl | ||
|
@@ -443,7 +471,7 @@ public void writeLeafXsiNilElement(XMLStreamWriter2 sw, | |
public void writePrologLinefeed(XMLStreamWriter2 sw) throws XMLStreamException | ||
{ | ||
// 06-Dec-2015, tatu: Alternatively could try calling `writeSpace()`... | ||
sw.writeRaw(Lf2SpacesIndenter.SYSTEM_LINE_SEPARATOR); | ||
sw.writeRaw(_lineFeed); | ||
} | ||
|
||
/* | ||
|
@@ -457,7 +485,7 @@ public void writePrologLinefeed(XMLStreamWriter2 sw) throws XMLStreamException | |
/** | ||
* Dummy implementation that adds no indentation whatsoever | ||
*/ | ||
protected static class NopIndenter | ||
protected class NopIndenter | ||
cowtowncoder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
implements Indenter, java.io.Serializable | ||
{ | ||
private static final long serialVersionUID = 1L; | ||
|
@@ -473,7 +501,7 @@ public NopIndenter() { } | |
* single space for indentation. It is used as the default | ||
* indenter for array values. | ||
*/ | ||
protected static class FixedSpaceIndenter | ||
protected class FixedSpaceIndenter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, keep |
||
implements Indenter, java.io.Serializable | ||
{ | ||
private static final long serialVersionUID = 1L; | ||
|
@@ -501,35 +529,25 @@ public void writeIndentation(JsonGenerator g, int level) throws IOException | |
* Default linefeed-based indenter uses system-specific linefeeds and | ||
* 2 spaces for indentation per level. | ||
*/ | ||
protected static class Lf2SpacesIndenter | ||
protected class Lf2SpacesIndenter | ||
implements Indenter, java.io.Serializable | ||
{ | ||
private static final long serialVersionUID = 1L; | ||
|
||
final static String SYSTEM_LINE_SEPARATOR; | ||
static { | ||
String lf = null; | ||
try { | ||
lf = System.getProperty("line.separator"); | ||
} catch (Throwable t) { } // access exception? | ||
SYSTEM_LINE_SEPARATOR = (lf == null) ? "\n" : lf; | ||
} | ||
|
||
final static int SPACE_COUNT = 64; | ||
final static char[] SPACES = new char[SPACE_COUNT]; | ||
static { | ||
final char[] SPACES = new char[SPACE_COUNT]; | ||
cowtowncoder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public Lf2SpacesIndenter() { | ||
Arrays.fill(SPACES, ' '); | ||
} | ||
|
||
public Lf2SpacesIndenter() { } | ||
|
||
@Override | ||
public boolean isInline() { return false; } | ||
|
||
@Override | ||
public void writeIndentation(XMLStreamWriter2 sw, int level) throws XMLStreamException | ||
{ | ||
sw.writeRaw(SYSTEM_LINE_SEPARATOR); | ||
sw.writeRaw(_lineFeed); | ||
level += level; // 2 spaces per level | ||
while (level > SPACE_COUNT) { // should never happen but... | ||
sw.writeRaw(SPACES, 0, SPACE_COUNT); | ||
|
@@ -541,7 +559,7 @@ public void writeIndentation(XMLStreamWriter2 sw, int level) throws XMLStreamExc | |
@Override | ||
public void writeIndentation(JsonGenerator jg, int level) throws IOException | ||
{ | ||
jg.writeRaw(SYSTEM_LINE_SEPARATOR); | ||
jg.writeRaw(_lineFeed); | ||
level += level; // 2 spaces per level | ||
while (level > SPACE_COUNT) { // should never happen but... | ||
jg.writeRaw(SPACES, 0, SPACE_COUNT); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
import com.fasterxml.jackson.dataformat.xml.XmlTestBase; | ||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; | ||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; | ||
import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter; | ||
|
||
public class XmlPrettyPrinterTest extends XmlTestBase | ||
{ | ||
|
@@ -188,4 +189,76 @@ public void testMultiLevel172() throws Exception | |
+"</Company>\n", | ||
xml); | ||
} | ||
|
||
public void testLineFeed_withCustomLineFeed() throws Exception { | ||
Company root = new Company(); | ||
root.employee.add(new Employee("abc")); | ||
|
||
String xml = _xmlMapper.writer() | ||
.with(new DefaultXmlPrettyPrinter().withCustomLineFeed("\n\rLF\n\r")) | ||
.with(ToXmlGenerator.Feature.WRITE_XML_DECLARATION) | ||
.writeValueAsString(root); | ||
// unify possible apostrophes to quotes | ||
xml = a2q(xml); | ||
|
||
// with indentation, should get linefeeds in prolog/epilog too | ||
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if this line should end with customLineFeed instead of `\n? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see the answer to your follow up question |
||
+ "<Company>\n\rLF\n\r" | ||
+ " <e>\n\rLF\n\r" | ||
+ " <employee>\n\rLF\n\r" | ||
+ " <id>abc</id>\n\rLF\n\r" | ||
+ " <type>FULL_TIME</type>\n\rLF\n\r" | ||
+ " </employee>\n\rLF\n\r" | ||
+ " </e>\n\rLF\n\r" | ||
+ "</Company>\n", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if this line should end with customLineFeed instead of `\n? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes - all the line feeds should be the same actually, could we rename the method as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
noted will make sure tests are applied there?
Agreed and I will change names as below!🙏🏼
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pjfanning So here is an update.
Done.
May I get your opinion here? It seems like writing custom 'new lines' before and after root element might be out of this PR's scope. The 'new lines' before and after the root element are written by method This instance invoking For references,
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes little sense to me not to use the same new lines throughout the XML doc. I'm now -1 on this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JooHyukKim Ok that sounds like a problem indeed! I wonder if it's the case of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not the indenter, actually. There is a separate instance of You can refer to below to code lines.
My first (probable) observation is that writing prolog and epilog with instance of Second observation is It will be great, @cowtowncoder if you can help out a little here? To override DefaultXmlPrettyPrinter of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, pretty printer instance. I will try to see if I can figure it out -- the problem is that XML module extends basic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JooHyukKim Ah. Part of the problem is that you haven't updated copy constructor:
to copy
is called the new instance "forgets"
in that constructor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Woooooow thank you for helping out 🥹 @cowtowncoder |
||
xml); | ||
} | ||
|
||
public void testLineFeed_systemDefault() throws Exception { | ||
Company root = new Company(); | ||
root.employee.add(new Employee("abc")); | ||
|
||
String xml = _xmlMapper.writer() | ||
.with(new DefaultXmlPrettyPrinter()) | ||
.with(ToXmlGenerator.Feature.WRITE_XML_DECLARATION) | ||
.writeValueAsString(root); | ||
// unify possible apostrophes to quotes | ||
xml = a2q(xml); | ||
|
||
// with indentation, should get linefeeds in prolog/epilog too | ||
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, done! 🙏🏼 And plus I checked other similar test cases' assertions and some hard coded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah sounds good wrt hard-coded linefeeds |
||
+ "<Company>\n" | ||
+ " <e>\n" | ||
+ " <employee>\n" | ||
+ " <id>abc</id>\n" | ||
+ " <type>FULL_TIME</type>\n" | ||
+ " </employee>\n" | ||
+ " </e>\n" | ||
+ "</Company>\n", | ||
xml); | ||
} | ||
|
||
public void testLineFeed_UseSystemDefaultLineSeperatorOnNullCustomLineFeed() throws Exception { | ||
Company root = new Company(); | ||
root.employee.add(new Employee("abc")); | ||
|
||
String xml = _xmlMapper.writer() | ||
.with(new DefaultXmlPrettyPrinter().withCustomLineFeed(null)) | ||
.with(ToXmlGenerator.Feature.WRITE_XML_DECLARATION) | ||
.writeValueAsString(root); | ||
// unify possible apostrophes to quotes | ||
xml = a2q(xml); | ||
|
||
// with indentation, should get linefeeds in prolog/epilog too | ||
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
+ "<Company>\n" | ||
+ " <e>\n" | ||
+ " <employee>\n" | ||
+ " <id>abc</id>\n" | ||
+ " <type>FULL_TIME</type>\n" | ||
+ " </employee>\n" | ||
+ " </e>\n" | ||
+ "</Company>\n", | ||
xml); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.