1 package com.fasterxml.jackson.core.util; 2 3 import java.io.IOException; 4 5 import com.fasterxml.jackson.core.JsonGenerator; 6 7 /** 8 * Default linefeed-based indenter, used by {@link DefaultPrettyPrinter} (unless 9 * overridden). Uses system-specific linefeeds and 2 spaces for indentation per level. 10 * 11 * @since 2.5 12 */ 13 public class DefaultIndenter 14 extends DefaultPrettyPrinter.NopIndenter 15 { 16 private static final long serialVersionUID = 1L; 17 18 public final static String SYS_LF; 19 static { 20 String lf; 21 try { 22 lf = System.getProperty("line.separator"); 23 } catch (Throwable t) { 24 lf = "\n"; // fallback when security manager denies access 25 } 26 SYS_LF = lf; 27 } 28 29 public static final DefaultIndenter SYSTEM_LINEFEED_INSTANCE = new DefaultIndenter(" ", SYS_LF); 30 31 /** 32 * We expect to rarely get indentation deeper than this number of levels, 33 * and try not to pre-generate more indentations than needed. 34 */ 35 private final static int INDENT_LEVELS = 16; 36 private final char[] indents; 37 private final int charsPerLevel; 38 private final String eol; 39 40 /** 41 * Indent with two spaces and the system's default line feed 42 */ DefaultIndenter()43 public DefaultIndenter() { 44 this(" ", SYS_LF); 45 } 46 47 /** 48 * Create an indenter which uses the <code>indent</code> string to indent one level 49 * and the <code>eol</code> string to separate lines. 50 */ DefaultIndenter(String indent, String eol)51 public DefaultIndenter(String indent, String eol) 52 { 53 charsPerLevel = indent.length(); 54 55 indents = new char[indent.length() * INDENT_LEVELS]; 56 int offset = 0; 57 for (int i=0; i<INDENT_LEVELS; i++) { 58 indent.getChars(0, indent.length(), indents, offset); 59 offset += indent.length(); 60 } 61 62 this.eol = eol; 63 } 64 withLinefeed(String lf)65 public DefaultIndenter withLinefeed(String lf) 66 { 67 if (lf.equals(eol)) { 68 return this; 69 } 70 return new DefaultIndenter(getIndent(), lf); 71 } 72 withIndent(String indent)73 public DefaultIndenter withIndent(String indent) 74 { 75 if (indent.equals(getIndent())) { 76 return this; 77 } 78 return new DefaultIndenter(indent, eol); 79 } 80 81 @Override isInline()82 public boolean isInline() { return false; } 83 84 @Override writeIndentation(JsonGenerator jg, int level)85 public void writeIndentation(JsonGenerator jg, int level) throws IOException 86 { 87 jg.writeRaw(eol); 88 if (level > 0) { // should we err on negative values (as there's some flaw?) 89 level *= charsPerLevel; 90 while (level > indents.length) { // unlike to happen but just in case 91 jg.writeRaw(indents, 0, indents.length); 92 level -= indents.length; 93 } 94 jg.writeRaw(indents, 0, level); 95 } 96 } 97 getEol()98 public String getEol() { 99 return eol; 100 } 101 getIndent()102 public String getIndent() { 103 return new String(indents, 0, charsPerLevel); 104 } 105 }