001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2016 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.util;
022    
023    
024    
025    import java.io.Serializable;
026    
027    
028    
029    /**
030     * This class provides a data structure with information about a column to use
031     * with the {@link ColumnFormatter}.
032     */
033    @NotMutable()
034    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
035    public final class FormattableColumn
036           implements Serializable
037    {
038      /**
039       * The serial version UID for this serializable class.
040       */
041      private static final long serialVersionUID = -67186391702592665L;
042    
043    
044    
045      // The alignment for this column.
046      private final HorizontalAlignment alignment;
047    
048      // The width for this column.
049      private final int width;
050    
051      // The lines that comprise the heading label for this column.
052      private final String[] labelLines;
053    
054    
055    
056      /**
057       * Creates a new formattable column with the provided information.
058       *
059       * @param  width       The width to use for this column.  It must be greater
060       *                     than or equal to 1.
061       * @param  alignment   The alignment to use for this column.  It must not be
062       *                     {@code null}.
063       * @param  labelLines  The lines to use as the label for this column.  It must
064       *                     not be {@code null}.
065       */
066      public FormattableColumn(final int width, final HorizontalAlignment alignment,
067                               final String... labelLines)
068      {
069        Validator.ensureTrue(width >= 1);
070        Validator.ensureNotNull(alignment, labelLines);
071    
072        this.width      = width;
073        this.alignment  = alignment;
074        this.labelLines = labelLines;
075      }
076    
077    
078    
079      /**
080       * Retrieves the width for this column.
081       *
082       * @return  The width for this column.
083       */
084      public int getWidth()
085      {
086        return width;
087      }
088    
089    
090    
091      /**
092       * Retrieves the alignment for this column.
093       *
094       * @return  The alignment for this column.
095       */
096      public HorizontalAlignment getAlignment()
097      {
098        return alignment;
099      }
100    
101    
102    
103      /**
104       * Retrieves the lines to use as the label for this column.
105       *
106       * @return  The lines to use as the label for this column.
107       */
108      public String[] getLabelLines()
109      {
110        return labelLines;
111      }
112    
113    
114    
115      /**
116       * Retrieves a single-line representation of the label.  If there are multiple
117       * header lines, then they will be concatenated and separated by a space.
118       *
119       * @return  A single-line representation of the label.
120       */
121      public String getSingleLabelLine()
122      {
123        switch (labelLines.length)
124        {
125          case 0:
126            return "";
127          case 1:
128            return labelLines[0];
129          default:
130            final StringBuilder buffer = new StringBuilder();
131            buffer.append(labelLines[0]);
132            for (int i=1; i < labelLines.length; i++)
133            {
134              buffer.append(' ');
135              buffer.append(labelLines[i]);
136            }
137            return buffer.toString();
138        }
139      }
140    
141    
142    
143      /**
144       * Appends a formatted representation of the provided text to the given
145       * buffer.
146       *
147       * @param  buffer  The buffer to which the text should be appended.  It must
148       *                 not be {@code null}.
149       * @param  text    The text to append to the buffer.  It must not be
150       *                 {@code null}.
151       * @param  format  The format to use for the text.  It must not be
152       *                 {@code null}.
153       */
154      public void format(final StringBuilder buffer, final String text,
155                         final OutputFormat format)
156      {
157        switch (format)
158        {
159          case TAB_DELIMITED_TEXT:
160            buffer.append(text);
161            break;
162    
163          case CSV:
164            boolean quotesNeeded = false;
165            final int length = text.length();
166            final int startPos = buffer.length();
167            for (int i=0; i < length; i++)
168            {
169              final char c = text.charAt(i);
170              if (c == ',')
171              {
172                buffer.append(',');
173                quotesNeeded = true;
174              }
175              else if (c == '"')
176              {
177                buffer.append("\"\"");
178                quotesNeeded = true;
179              }
180              else if ((c >= ' ') && (c <= '~'))
181              {
182                buffer.append(c);
183              }
184            }
185    
186            if (quotesNeeded)
187            {
188              buffer.insert(startPos, '"');
189              buffer.append('"');
190            }
191            break;
192    
193          case COLUMNS:
194            alignment.format(buffer, text, width);
195            break;
196        }
197      }
198    
199    
200    
201      /**
202       * Retrieves a string representation of this formattable column.
203       *
204       * @return  A string representation of this formattable column.
205       */
206      @Override()
207      public String toString()
208      {
209        final StringBuilder buffer = new StringBuilder();
210        toString(buffer);
211        return buffer.toString();
212      }
213    
214    
215    
216      /**
217       * Appends a string representation of this formattable column to the provided
218       * buffer.
219       *
220       * @param  buffer  The buffer to which the string representation should be
221       *                 appended.
222       */
223      public void toString(final StringBuilder buffer)
224      {
225        buffer.append("FormattableColumn(width=");
226        buffer.append(width);
227        buffer.append(", alignment=");
228        buffer.append(alignment);
229        buffer.append(", label=\"");
230        buffer.append(getSingleLabelLine());
231        buffer.append("\")");
232      }
233    }