View Javadoc

1   /*
2    * Copyright (c) 2001-2004,
3    * RedVerst Group, ISP RAS http://www.ispras.ru
4    * All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are met:
8    *
9    * 1. Redistributions of source code must retain the above copyright notice, this
10   *    list of conditions and the following disclaimer.
11   *
12   * 2. Redistributions in binary form must reproduce the above copyright notice,
13   *    this list of conditions and the following disclaimer in the documentation
14   *    and/or other materials provided with the distribution.
15   *
16   * 3. The names "ATP", "TreeDL", "RedVerst", "ISP RAS"
17   *    may not be used to endorse or promote products derived from this software
18   *    without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 &lt;= 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 &lt; 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     // implementation
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/*Integer*/ indent_stack = new Stack/*Integer*/();
204 
205     /***
206      * The current step of indentation.
207      *
208      * @see #DEFAULT_INDENT_STEP
209      */
210     private int indent_step = DEFAULT_INDENT_STEP;
211 }