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 }