001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.util.table;
028    
029    
030    
031    import java.io.BufferedWriter;
032    import java.io.OutputStream;
033    import java.io.OutputStreamWriter;
034    import java.io.PrintWriter;
035    import java.io.Writer;
036    
037    
038    
039    /**
040     * An interface for creating a tab-separated formatted table.
041     * <p>
042     * This table printer will replace any tab, line-feeds, or carriage
043     * return control characters encountered in a cell with a single
044     * space.
045     */
046    public final class TabSeparatedTablePrinter extends TablePrinter {
047    
048      /**
049       * Table serializer implementation.
050       */
051      private final class Serializer extends TableSerializer {
052    
053        // The current column being output.
054        private int column = 0;
055    
056        // Counts the number of separators that should be output the next
057        // time a non-empty cell is displayed. The tab separators are
058        // not displayed immediately so that we can avoid displaying
059        // unnecessary trailing separators.
060        private int requiredSeparators = 0;
061    
062    
063    
064        // Private constructor.
065        private Serializer() {
066          // No implementation required.
067        }
068    
069    
070    
071        /**
072         * {@inheritDoc}
073         */
074        @Override
075        public void addCell(String s) {
076          // Avoid printing tab separators for trailing empty cells.
077          if (s.length() == 0) {
078            requiredSeparators++;
079          } else {
080            for (int i = 0; i < requiredSeparators; i++) {
081              writer.print('\t');
082            }
083            requiredSeparators = 1;
084          }
085    
086          // Replace all new-lines and tabs with a single space.
087          writer.print(s.replaceAll("[\\t\\n\\r]", " "));
088          column++;
089        }
090    
091    
092    
093        /**
094         * {@inheritDoc}
095         */
096        @Override
097        public void addHeading(String s) {
098          if (displayHeadings) {
099            addCell(s);
100          }
101        }
102    
103    
104    
105        /**
106         * {@inheritDoc}
107         */
108        @Override
109        public void endHeader() {
110          if (displayHeadings) {
111            writer.println();
112          }
113        }
114    
115    
116    
117        /**
118         * {@inheritDoc}
119         */
120        @Override
121        public void endRow() {
122          writer.println();
123        }
124    
125    
126    
127        /**
128         * {@inheritDoc}
129         */
130        @Override
131        public void endTable() {
132          writer.flush();
133        }
134    
135    
136    
137        /**
138         * {@inheritDoc}
139         */
140        @Override
141        public void startHeader() {
142          column = 0;
143          requiredSeparators = 0;
144        }
145    
146    
147    
148        /**
149         * {@inheritDoc}
150         */
151        @Override
152        public void startRow() {
153          column = 0;
154          requiredSeparators = 0;
155        }
156      }
157    
158      // Indicates whether or not the headings should be output.
159      private boolean displayHeadings = false;
160    
161      // The output destination.
162      private PrintWriter writer = null;
163    
164    
165    
166      /**
167       * Creates a new tab separated table printer for the specified
168       * output stream. Headings will not be displayed by default.
169       *
170       * @param stream
171       *          The stream to output tables to.
172       */
173      public TabSeparatedTablePrinter(OutputStream stream) {
174        this(new BufferedWriter(new OutputStreamWriter(stream)));
175      }
176    
177    
178    
179      /**
180       * Creates a new tab separated table printer for the specified
181       * writer. Headings will not be displayed by default.
182       *
183       * @param writer
184       *          The writer to output tables to.
185       */
186      public TabSeparatedTablePrinter(Writer writer) {
187        this.writer = new PrintWriter(writer);
188      }
189    
190    
191    
192      /**
193       * Specify whether or not table headings should be displayed.
194       *
195       * @param displayHeadings
196       *          <code>true</code> if table headings should be
197       *          displayed.
198       */
199      public void setDisplayHeadings(boolean displayHeadings) {
200        this.displayHeadings = displayHeadings;
201      }
202    
203    
204    
205      /**
206       * {@inheritDoc}
207       */
208      @Override
209      protected TableSerializer getSerializer() {
210        return new Serializer();
211      }
212    
213    }