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      */

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      */

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     
65     public DefaultIndenter withLinefeed(String lf)
66     {
67         if (lf.equals(eol)) {
68             return this;
69         }
70         return new DefaultIndenter(getIndent(), lf);
71     }
72     
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
82     public boolean isInline() { return false; }
83
84     @Override
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     
98     public String getEol() {
99         return eol;
100     }
101     
102     public String getIndent() {
103         return new String(indents, 0, charsPerLevel);
104     }
105 }