1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package com.unitesk.atp.text.filters;
33
34 import java.util.Stack;
35
36 /***
37 * This filter manages indent levels and inserts spaces according
38 * to the current indent level at the start of every line.
39 *
40 * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
41 * @version $Id: IndentFilter.java,v 1.1 2004/10/09 06:36:40 all-x Exp $
42 */
43 public class IndentFilter extends Filter
44 {
45 /***
46 * The default value of indent step.
47 */
48 public static final int DEFAULT_INDENT_STEP = 4;
49
50 /***
51 * Constructs indent filter with default indent step.
52 *
53 * @see #DEFAULT_INDENT_STEP
54 */
55 public IndentFilter( TextReceiver client )
56 {
57 super( client );
58
59 indent_stack.push( new Integer( 0 ) );
60 }
61
62 /***
63 * Constructs indent server with given indent step.
64 *
65 * @param indent_step the indent step value
66 * @throws IllegalArgumentException
67 * <code>if indent_step <= 0</code>
68 */
69 public IndentFilter( TextReceiver client, int indent_step )
70 {
71 this( client );
72
73 if( indent_step <= 0 )
74 {
75 throw
76 new IllegalArgumentException( Integer.toString( indent_step ) );
77 }
78
79 this.indent_step = indent_step;
80 }
81
82 /***
83 * Returns the indent step.
84 */
85 public int getIndentStep()
86 {
87 return indent_step;
88 }
89
90 /***
91 * Pushes in stack new indent level.
92 *
93 * @param indent the new indent level
94 * @throws IllegalArgumentException
95 * if <code>indent</code> is negative
96 */
97 public void pushIndent( int indent )
98 {
99 if( indent < 0 )
100 {
101 throw new IllegalArgumentException( Integer.toString( indent ) );
102 }
103 indent_stack.push( new Integer( indent ) );
104 }
105
106 /***
107 * Returns the current indent level.
108 *
109 * @throws java.util.EmptyStackException
110 * if no indent level is in stack.
111 */
112 public int getIndent()
113 {
114 return ((Integer)indent_stack.peek()).intValue();
115 }
116
117 /***
118 * Restores the previous indent level.
119 *
120 * @throws java.util.EmptyStackException
121 * if no indent level is in stack.
122 */
123 public void popIndent()
124 {
125 indent_stack.pop();
126 }
127
128 /***
129 * Receives string and passes it to the client inserting appropriate
130 * number of spaces at the start of each line
131 *
132 * @param str the string to receive
133 *
134 * @throws NullPointerException
135 * if <code>str</code> is <code>null</code>
136 */
137 public void txt( String str )
138 {
139 if( str.length() == 0 ) return;
140
141 if( is_line_start )
142 {
143 int indent = ((Integer)indent_stack.peek()).intValue();
144 client.txt( fill( ' ', indent ) );
145 is_line_start = false;
146 }
147 client.txt( str );
148 }
149
150 /***
151 * Receives line separator and passes it to the client.
152 * The next string received by {@link TextReceiver#txt(String)} will be
153 * prefixed by indent.
154 *
155 * @throws NullPointerException
156 * if <code>c</code> is <code>null</code>
157 */
158 public void nl()
159 {
160 client.nl();
161 is_line_start = true;
162 }
163
164 /***
165 * Returns the current state of the line start indicator.
166 */
167 public boolean isLineStart()
168 {
169 return is_line_start;
170 }
171
172 /***
173 * Fills a string with characters.
174 *
175 * @param c the character to fill
176 * @param l the length of the string
177 * @return The string of the length <code>l</code> filled by <code>c</code>.
178 * If <code>l < 0</code> empty string is returned.
179 */
180 public static String fill( char c, int l )
181 {
182 StringBuffer sb = new StringBuffer( l );
183
184 while( l-- > 0 )
185 {
186 sb.append( c );
187 }
188
189 return sb.toString();
190 }
191
192
193
194
195 /***
196 * The line start indicator.
197 */
198 private boolean is_line_start = true;
199
200 /***
201 * The stack of indent levels.
202 */
203 private Stack
204
205 /***
206 * The current step of indentation.
207 *
208 * @see #DEFAULT_INDENT_STEP
209 */
210 private int indent_step = DEFAULT_INDENT_STEP;
211 }