View Javadoc

1   /*
2    * $Id: PrettyPrintWriter.java 471833 2006-11-06 19:13:16Z husted $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.interceptor.debugging;
22  
23  import java.io.PrintWriter;
24  import java.io.Writer;
25  import java.util.Stack;
26  
27  public class PrettyPrintWriter {
28  
29      private final PrintWriter writer;
30      private final Stack<String> elementStack = new Stack<String>();
31      private final char[] lineIndenter;
32  
33      private boolean tagInProgress;
34      private int depth;
35      private boolean readyForNewLine;
36      private boolean tagIsEmpty;
37      private String newLine;
38  
39      private static final char[] NULL = "&#x0;".toCharArray();
40      private static final char[] AMP = "&amp;".toCharArray();
41      private static final char[] LT = "&lt;".toCharArray();
42      private static final char[] GT = "&gt;".toCharArray();
43      private static final char[] SLASH_R = "&#x0D;".toCharArray();
44      private static final char[] QUOT = "&quot;".toCharArray();
45      private static final char[] APOS = "&apos;".toCharArray();
46      private static final char[] CLOSE = "</".toCharArray();
47  
48      public PrettyPrintWriter(Writer writer, char[] lineIndenter, String newLine) {
49          this.writer = new PrintWriter(writer);
50          this.lineIndenter = lineIndenter;
51          this.newLine = newLine;
52      }
53  
54      public PrettyPrintWriter(Writer writer, char[] lineIndenter) {
55          this(writer, lineIndenter, "\n");
56      }
57  
58      public PrettyPrintWriter(Writer writer, String lineIndenter, String newLine) {
59          this(writer, lineIndenter.toCharArray(), newLine);
60      }
61  
62      public PrettyPrintWriter(Writer writer, String lineIndenter) {
63          this(writer, lineIndenter.toCharArray());
64      }
65  
66      public PrettyPrintWriter(Writer writer) {
67          this(writer, new char[]{' ', ' '});
68      }
69  
70      public void startNode(String name) {
71          tagIsEmpty = false;
72          finishTag();
73          writer.write('<');
74          writer.write(name);
75          elementStack.push(name);
76          tagInProgress = true;
77          depth++;
78          readyForNewLine = true;
79          tagIsEmpty = true;
80      }
81  
82      public void setValue(String text) {
83          readyForNewLine = false;
84          tagIsEmpty = false;
85          finishTag();
86  
87          writeText(writer, text);
88      }
89  
90      public void addAttribute(String key, String value) {
91          writer.write(' ');
92          writer.write(key);
93          writer.write('=');
94          writer.write('\"');
95          writeAttributeValue(writer, value);
96          writer.write('\"');
97      }
98  
99      protected void writeAttributeValue(PrintWriter writer, String text) {
100         writeText(text);
101     }
102 
103     protected void writeText(PrintWriter writer, String text) {
104         writeText(text);
105     }
106 
107     private void writeText(String text) {
108         int length = text.length();
109         for (int i = 0; i < length; i++) {
110             char c = text.charAt(i);
111             switch (c) {
112                 case '\0':
113                     this.writer.write(NULL);
114                     break;
115                 case '&':
116                     this.writer.write(AMP);
117                     break;
118                 case '<':
119                     this.writer.write(LT);
120                     break;
121                 case '>':
122                     this.writer.write(GT);
123                     break;
124                 case '"':
125                     this.writer.write(QUOT);
126                     break;
127                 case '\'':
128                     this.writer.write(APOS);
129                     break;
130                 case '\r':
131                     this.writer.write(SLASH_R);
132                     break;
133                 default:
134                     this.writer.write(c);
135             }
136         }
137     }
138 
139     public void endNode() {
140         depth--;
141         if (tagIsEmpty) {
142             writer.write('/');
143             readyForNewLine = false;
144             finishTag();
145             elementStack.pop();
146         } else {
147             finishTag();
148             writer.write(CLOSE);
149             writer.write((String)elementStack.pop());
150             writer.write('>');
151         }
152         readyForNewLine = true;
153         if (depth == 0 ) {
154             writer.flush();
155         }
156     }
157 
158     private void finishTag() {
159         if (tagInProgress) {
160             writer.write('>');
161         }
162         tagInProgress = false;
163         if (readyForNewLine) {
164             endOfLine();
165         }
166         readyForNewLine = false;
167         tagIsEmpty = false;
168     }
169 
170     protected void endOfLine() {
171         writer.write(newLine);
172         for (int i = 0; i < depth; i++) {
173             writer.write(lineIndenter);
174         }
175     }
176 
177     public void flush() {
178         writer.flush();
179     }
180 
181     public void close() {
182         writer.close();
183     }
184 }