You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2016/02/24 10:15:28 UTC

svn commit: r1732043 - in /directory/shared/trunk/util/src/main/java/org/apache/directory/api/util: FileUtils.java IOUtils.java StringBuilderWriter.java

Author: elecharny
Date: Wed Feb 24 09:15:28 2016
New Revision: 1732043

URL: http://svn.apache.org/viewvc?rev=1732043&view=rev
Log:
Added some missing methods (mainly used by ApacheDS)

Added:
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/StringBuilderWriter.java
Modified:
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java
    directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java

Modified: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java?rev=1732043&r1=1732042&r2=1732043&view=diff
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java (original)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/FileUtils.java Wed Feb 24 09:15:28 2016
@@ -20,9 +20,16 @@
 
 package org.apache.directory.api.util;
 
+
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
 
 /**
  * This code comes from Apache commons.io library.
@@ -37,12 +44,13 @@ public final class FileUtils
      * The Windows separator character.
      */
     private static final char WINDOWS_SEPARATOR = '\\';
-    
+
     /**
      * The system separator character.
      */
     private static final char SYSTEM_SEPARATOR = File.separatorChar;
-    
+
+
     /**
      * Creates a new instance of FileUtils.
      */
@@ -50,7 +58,7 @@ public final class FileUtils
     {
         // Nothing to do.
     }
-    
+
 
     /**
      * Deletes a directory recursively.
@@ -58,25 +66,25 @@ public final class FileUtils
      * @param directory  directory to delete
      * @throws IOException in case deletion is unsuccessful
      */
-    public static void deleteDirectory( File directory ) throws IOException 
+    public static void deleteDirectory( File directory ) throws IOException
     {
-        if ( !directory.exists() ) 
+        if ( !directory.exists() )
         {
             return;
         }
-    
-        if ( !isSymlink( directory ) ) 
+
+        if ( !isSymlink( directory ) )
         {
             cleanDirectory( directory );
         }
-    
-        if ( !directory.delete() ) 
+
+        if ( !directory.delete() )
         {
             String message = "Unable to delete directory " + directory + ".";
             throw new IOException( message );
         }
     }
-    
+
 
     /**
      * Determines whether the specified file is a Symbolic Link rather than an actual file.
@@ -95,84 +103,84 @@ public final class FileUtils
      * @throws IOException if an IO error occurs while checking the file
      * @since 2.0
      */
-    public static boolean isSymlink( File file ) throws IOException 
+    public static boolean isSymlink( File file ) throws IOException
     {
-        if ( file == null ) 
+        if ( file == null )
         {
             throw new NullPointerException( "File must not be null" );
         }
-        
-        if ( SYSTEM_SEPARATOR == WINDOWS_SEPARATOR ) 
+
+        if ( SYSTEM_SEPARATOR == WINDOWS_SEPARATOR )
         {
             return false;
         }
-        
+
         File fileInCanonicalDir = null;
-        
-        if ( file.getParent() == null ) 
+
+        if ( file.getParent() == null )
         {
             fileInCanonicalDir = file;
-        } 
-        else 
+        }
+        else
         {
             File canonicalDir = file.getParentFile().getCanonicalFile();
             fileInCanonicalDir = new File( canonicalDir, file.getName() );
         }
-        
-        return !fileInCanonicalDir.getCanonicalFile().equals( fileInCanonicalDir.getAbsoluteFile() ); 
+
+        return !fileInCanonicalDir.getCanonicalFile().equals( fileInCanonicalDir.getAbsoluteFile() );
     }
-    
-    
+
+
     /**
      * Deletes a directory recursively.
      *
      * @param directory  directory to delete
      * @throws IOException in case deletion is unsuccessful
      */
-    public static void cleanDirectory( File directory ) throws IOException 
+    public static void cleanDirectory( File directory ) throws IOException
     {
-        if ( !directory.exists() ) 
+        if ( !directory.exists() )
         {
             String message = directory + " does not exist";
             throw new IllegalArgumentException( message );
         }
-        
-        if ( !directory.isDirectory() ) 
+
+        if ( !directory.isDirectory() )
         {
             String message = directory + " is not a directory";
             throw new IllegalArgumentException( message );
         }
-        
+
         File[] files = directory.listFiles();
-        
-        if ( files == null ) 
+
+        if ( files == null )
         {
             // null if security restricted
             String message = "Failed to list contents of " + directory;
             throw new IOException( message );
         }
-        
+
         IOException exception = null;
-        
+
         for ( File file : files )
         {
-            try 
+            try
             {
                 forceDelete( file );
-            } 
+            }
             catch ( IOException ioe )
             {
                 exception = ioe;
             }
         }
-        
-        if ( null != exception ) 
+
+        if ( null != exception )
         {
             throw exception;
         }
     }
-    
-    
+
+
     /**
      * Deletes a file. If file is a directory, delete it and all sub-directories.
      * <p>
@@ -188,27 +196,220 @@ public final class FileUtils
      * @throws FileNotFoundException if the file was not found
      * @throws IOException in case deletion is unsuccessful
      */
-     public static void forceDelete( File file ) throws IOException 
-     {
-        if ( file.isDirectory() ) 
+    public static void forceDelete( File file ) throws IOException
+    {
+        if ( file.isDirectory() )
         {
             deleteDirectory( file );
-        } 
-        else 
+        }
+        else
         {
             boolean filePresent = file.exists();
-            
-            if ( !file.delete() ) 
+
+            if ( !file.delete() )
             {
                 if ( !filePresent )
                 {
                     String message = "File does not exist: " + file;
                     throw new FileNotFoundException( message );
                 }
-                
+
                 String message = "Unable to delete file: " + file;
                 throw new IOException( message );
             }
         }
     }
+
+
+    /**
+     * Returns the path to the system temporary directory.
+     *
+     * @return the path to the system temporary directory.
+     *
+     * @since 2.0
+     */
+    public static String getTempDirectoryPath()
+    {
+        return System.getProperty( "java.io.tmpdir" );
+    }
+
+
+    /**
+     * Reads the contents of a file into a String using the default encoding for the VM.
+     * The file is always closed.
+     *
+     * @param file  the file to read, must not be {@code null}
+     * @return the file contents, never {@code null}
+     * @throws IOException in case of an I/O error
+     * @since 1.3.1
+     * @deprecated 2.5 use {@link #readFileToString(File, Charset)} instead
+     */
+    @Deprecated
+    public static String readFileToString( File file ) throws IOException
+    {
+        return readFileToString( file, Charset.defaultCharset() );
+    }
+
+
+    /**
+     * Reads the contents of a file into a String.
+     * The file is always closed.
+     *
+     * @param file  the file to read, must not be {@code null}
+     * @param encoding  the encoding to use, {@code null} means platform default
+     * @return the file contents, never {@code null}
+     * @throws IOException in case of an I/O error
+     * @since 2.3
+     */
+    public static String readFileToString( File file, Charset encoding ) throws IOException
+    {
+        InputStream in = null;
+
+        try
+        {
+            in = openInputStream( file );
+            return IOUtils.toString( in, IOUtils.toCharset( encoding ) );
+        }
+        finally
+        {
+            IOUtils.closeQuietly( in );
+        }
+    }
+
+
+    /**
+     * Opens a {@link FileInputStream} for the specified file, providing better
+     * error messages than simply calling <code>new FileInputStream(file)</code>.
+     * <p>
+     * At the end of the method either the stream will be successfully opened,
+     * or an exception will have been thrown.
+     * <p>
+     * An exception is thrown if the file does not exist.
+     * An exception is thrown if the file object exists but is a directory.
+     * An exception is thrown if the file exists but cannot be read.
+     *
+     * @param file  the file to open for input, must not be {@code null}
+     * @return a new {@link FileInputStream} for the specified file
+     * @throws FileNotFoundException if the file does not exist
+     * @throws IOException if the file object is a directory
+     * @throws IOException if the file cannot be read
+     * @since 1.3
+     */
+    public static FileInputStream openInputStream( File file ) throws IOException
+    {
+        if ( file.exists() )
+        {
+            if ( file.isDirectory() )
+            {
+                throw new IOException( "File '" + file + "' exists but is a directory" );
+            }
+
+            if ( !file.canRead() )
+            {
+                throw new IOException( "File '" + file + "' cannot be read" );
+            }
+        }
+        else
+        {
+            throw new FileNotFoundException( "File '" + file + "' does not exist" );
+        }
+
+        return new FileInputStream( file );
+    }
+
+
+    /**
+     * Writes a String to a file creating the file if it does not exist using the default encoding for the VM.
+     *
+     * @param file  the file to write
+     * @param data  the content to write to the file
+     * @throws IOException in case of an I/O error
+     * @deprecated 2.5 use {@link #writeStringToFile(File, String, Charset)} instead
+     */
+    @Deprecated
+    public static void writeStringToFile( File file, String data ) throws IOException
+    {
+        writeStringToFile( file, data, Charset.defaultCharset(), false );
+    }
+
+
+    /**
+     * Writes a String to a file creating the file if it does not exist.
+     *
+     * @param file  the file to write
+     * @param data  the content to write to the file
+     * @param encoding  the encoding to use, {@code null} means platform default
+     * @param append if {@code true}, then the String will be added to the
+     * end of the file rather than overwriting
+     * @throws IOException in case of an I/O error
+     * @since 2.3
+     */
+    public static void writeStringToFile( File file, String data, Charset encoding, boolean append ) throws IOException
+    {
+        OutputStream out = null;
+
+        try
+        {
+            out = openOutputStream( file, append );
+            IOUtils.write( data, out, encoding );
+            out.close(); // don't swallow close Exception if copy completes normally
+        }
+        finally
+        {
+            IOUtils.closeQuietly( out );
+        }
+    }
+
+
+    /**
+     * Opens a {@link FileOutputStream} for the specified file, checking and
+     * creating the parent directory if it does not exist.
+     * <p>
+     * At the end of the method either the stream will be successfully opened,
+     * or an exception will have been thrown.
+     * <p>
+     * The parent directory will be created if it does not exist.
+     * The file will be created if it does not exist.
+     * An exception is thrown if the file object exists but is a directory.
+     * An exception is thrown if the file exists but cannot be written to.
+     * An exception is thrown if the parent directory cannot be created.
+     *
+     * @param file  the file to open for output, must not be {@code null}
+     * @param append if {@code true}, then bytes will be added to the
+     * end of the file rather than overwriting
+     * @return a new {@link FileOutputStream} for the specified file
+     * @throws IOException if the file object is a directory
+     * @throws IOException if the file cannot be written to
+     * @throws IOException if a parent directory needs creating but that fails
+     * @since 2.1
+     */
+    public static FileOutputStream openOutputStream( File file, boolean append ) throws IOException
+    {
+        if ( file.exists() )
+        {
+            if ( file.isDirectory() )
+            {
+                throw new IOException( "File '" + file + "' exists but is a directory" );
+            }
+            
+            if ( !file.canWrite() )
+            {
+                throw new IOException( "File '" + file + "' cannot be written to" );
+            }
+        }
+        else
+        {
+            File parent = file.getParentFile();
+            
+            if ( parent != null )
+            {
+                if ( !parent.mkdirs() && !parent.isDirectory() )
+                {
+                    throw new IOException( "Directory '" + parent + "' could not be created" );
+                }
+            }
+        }
+        
+        return new FileOutputStream( file, append );
+    }
 }

Modified: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java?rev=1732043&r1=1732042&r2=1732043&view=diff
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java (original)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/IOUtils.java Wed Feb 24 09:15:28 2016
@@ -20,9 +20,16 @@
 
 package org.apache.directory.api.util;
 
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
 
 /**
  * This code comes from Apache commons.io library.
@@ -34,13 +41,25 @@ import java.io.InputStream;
 public final class IOUtils
 {
     /**
+     * The default buffer size ({@value}) to use for
+     * {@link #copyLarge(InputStream, OutputStream)}
+     * and
+     * {@link #copyLarge(Reader, Writer)}
+     */
+    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+    /** The end of file */
+    private static final int EOF = -1;
+
+
+    /**
      * Creates a new instance of FileUtils.
      */
     private IOUtils()
     {
         // Nothing to do.
     }
-    
+
 
     /**
     * Closes an <code>InputStream</code> unconditionally.
@@ -65,12 +84,12 @@ public final class IOUtils
     *
     * @param input  the InputStream to close, may be null or already closed
     */
-    public static void closeQuietly( InputStream input ) 
+    public static void closeQuietly( InputStream input )
     {
         closeQuietly( ( Closeable ) input );
     }
-    
-    
+
+
     /**
      * Closes a <code>Closeable</code> unconditionally.
      * <p>
@@ -107,18 +126,180 @@ public final class IOUtils
      *            the objects to close, may be null or already closed
      * @since 2.0
      */
-    public static void closeQuietly( Closeable closeable ) 
+    public static void closeQuietly( Closeable closeable )
     {
-        try 
+        try
         {
-            if ( closeable != null ) 
+            if ( closeable != null )
             {
                 closeable.close();
             }
-        } 
-        catch ( IOException ioe ) 
+        }
+        catch ( IOException ioe )
         {
             // ignore
         }
     }
+
+
+    /**
+    * Gets the contents of an <code>InputStream</code> as a String
+    * using the specified character encoding.
+    * <p>
+    * This method buffers the input internally, so there is no need to use a
+    * <code>BufferedInputStream</code>.
+    * </p>
+    * @param input  the <code>InputStream</code> to read from
+    * @param encoding  the encoding to use, null means platform default
+    * @return the requested String
+    * @throws NullPointerException if the input is null
+    * @throws IOException if an I/O error occurs
+    * @since 2.3
+    */
+    public static String toString( InputStream input, Charset encoding ) throws IOException
+    {
+        StringBuilderWriter sw = new StringBuilderWriter();
+        copy( input, sw, encoding );
+
+        return sw.toString();
+    }
+
+
+    /**
+     * Returns the given Charset or the default Charset if the given Charset is null.
+     * 
+     * @param charset A charset or null.
+     * @return the given Charset or the default Charset if the given Charset is null
+     */
+    public static Charset toCharset( Charset charset )
+    {
+        return charset == null ? Charset.defaultCharset() : charset;
+    }
+
+
+    /**
+     * Copies bytes from an <code>InputStream</code> to chars on a
+     * <code>Writer</code> using the specified character encoding.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedInputStream</code>.
+     * <p>
+     * This method uses {@link InputStreamReader}.
+     *
+     * @param input  the <code>InputStream</code> to read from
+     * @param output  the <code>Writer</code> to write to
+     * @param inputEncoding  the encoding to use for the input stream, null means platform default
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 2.3
+     */
+    public static void copy( InputStream input, Writer output, Charset inputEncoding ) throws IOException
+    {
+        InputStreamReader in = new InputStreamReader( input, toCharset( inputEncoding ) );
+        copy( in, output );
+    }
+
+
+    /**
+     * Copies chars from a <code>Reader</code> to a <code>Writer</code>.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedReader</code>.
+     * <p>
+     * Large streams (over 2GB) will return a chars copied value of
+     * <code>-1</code> after the copy has completed since the correct
+     * number of chars cannot be returned as an int. For large streams
+     * use the <code>copyLarge(Reader, Writer)</code> method.
+     *
+     * @param input  the <code>Reader</code> to read from
+     * @param output  the <code>Writer</code> to write to
+     * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 1.1
+     */
+    public static int copy( Reader input, Writer output ) throws IOException
+    {
+        long count = copyLarge( input, output );
+
+        if ( count > Integer.MAX_VALUE )
+        {
+            return -1;
+        }
+
+        return ( int ) count;
+    }
+
+
+    /**
+     * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedReader</code>.
+     * <p>
+     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+     *
+     * @param input  the <code>Reader</code> to read from
+     * @param output  the <code>Writer</code> to write to
+     * @return the number of characters copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 1.3
+     */
+    public static long copyLarge( Reader input, Writer output ) throws IOException
+    {
+        return copyLarge( input, output, new char[DEFAULT_BUFFER_SIZE] );
+    }
+
+
+    /**
+     * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
+     * <p>
+     * This method uses the provided buffer, so there is no need to use a
+     * <code>BufferedReader</code>.
+     * <p>
+     *
+     * @param input  the <code>Reader</code> to read from
+     * @param output  the <code>Writer</code> to write to
+     * @param buffer the buffer to be used for the copy
+     * @return the number of characters copied
+     * @throws NullPointerException if the input or output is null
+     * @throws IOException if an I/O error occurs
+     * @since 2.2
+     */
+    public static long copyLarge( Reader input, Writer output, char[] buffer ) throws IOException
+    {
+        long count = 0;
+        int n = 0;
+
+        while ( EOF != ( n = input.read( buffer ) ) )
+        {
+            output.write( buffer, 0, n );
+            count += n;
+        }
+
+        return count;
+    }
+    
+    
+    /**
+     * Writes chars from a <code>String</code> to bytes on an
+     * <code>OutputStream</code> using the specified character encoding.
+     * <p>
+     * This method uses {@link String#getBytes(String)}.
+     *
+     * @param data  the <code>String</code> to write, null ignored
+     * @param output  the <code>OutputStream</code> to write to
+     * @param encoding  the encoding to use, null means platform default
+     * @throws NullPointerException if output is null
+     * @throws IOException if an I/O error occurs
+     * @since 2.3
+     */
+    public static void write( String data, OutputStream output, Charset encoding ) throws IOException 
+    {
+        if ( data != null ) 
+        {
+            output.write( data.getBytes( toCharset( encoding ) ) );
+        }
+    }
 }

Added: directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/StringBuilderWriter.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/StringBuilderWriter.java?rev=1732043&view=auto
==============================================================================
--- directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/StringBuilderWriter.java (added)
+++ directory/shared/trunk/util/src/main/java/org/apache/directory/api/util/StringBuilderWriter.java Wed Feb 24 09:15:28 2016
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.directory.api.util;
+
+
+import java.io.Writer;
+
+
+/**
+ * {@link Writer} implementation that outputs to a {@link StringBuilder}.
+ * <p>
+ * <strong>NOTE:</strong> This implementation, as an alternative to
+ * <code>java.io.StringWriter</code>, provides an <i>un-synchronized</i>
+ * (i.e. for use in a single thread) implementation for better performance.
+ * For safe usage with multiple {@link Thread}s then
+ * <code>java.io.StringWriter</code> should be used.
+ *
+ * @version $Id: StringBuilderWriter.java 1415850 2012-11-30 20:51:39Z ggregory $
+ * @since 2.0
+ */
+public class StringBuilderWriter extends Writer
+{
+
+    private final StringBuilder builder;
+
+
+    /**
+     * Construct a new {@link StringBuilder} instance with default capacity.
+     */
+    public StringBuilderWriter()
+    {
+        builder = new StringBuilder();
+    }
+
+
+    /**
+     * Construct a new {@link StringBuilder} instance with the specified capacity.
+     *
+     * @param capacity The initial capacity of the underlying {@link StringBuilder}
+     */
+    public StringBuilderWriter( int capacity )
+    {
+        builder = new StringBuilder( capacity );
+    }
+
+
+    /**
+     * Construct a new instance with the specified {@link StringBuilder}.
+     *
+     * @param builder The String builder
+     */
+    public StringBuilderWriter( StringBuilder builder )
+    {
+        this.builder = builder != null ? builder : new StringBuilder();
+    }
+
+
+    /**
+     * Append a single character to this Writer.
+     *
+     * @param value The character to append
+     * @return This writer instance
+     */
+    @Override
+    public Writer append( char value )
+    {
+        builder.append( value );
+        
+        return this;
+    }
+
+
+    /**
+     * Append a character sequence to this Writer.
+     *
+     * @param value The character to append
+     * @return This writer instance
+     */
+    @Override
+    public Writer append( CharSequence value )
+    {
+        builder.append( value );
+        
+        return this;
+    }
+
+
+    /**
+     * Append a portion of a character sequence to the {@link StringBuilder}.
+     *
+     * @param value The character to append
+     * @param start The index of the first character
+     * @param end The index of the last character + 1
+     * @return This writer instance
+     */
+    @Override
+    public Writer append( CharSequence value, int start, int end )
+    {
+        builder.append( value, start, end );
+        
+        return this;
+    }
+
+
+    /**
+     * Closing this writer has no effect. 
+     */
+    @Override
+    public void close()
+    {
+    }
+
+
+    /**
+     * Flushing this writer has no effect. 
+     */
+    @Override
+    public void flush()
+    {
+    }
+
+
+    /**
+     * Write a String to the {@link StringBuilder}.
+     * 
+     * @param value The value to write
+     */
+    @Override
+    public void write( String value )
+    {
+        if ( value != null )
+        {
+            builder.append( value );
+        }
+    }
+
+
+    /**
+     * Write a portion of a character array to the {@link StringBuilder}.
+     *
+     * @param value The value to write
+     * @param offset The index of the first character
+     * @param length The number of characters to write
+     */
+    @Override
+    public void write( char[] value, int offset, int length )
+    {
+        if ( value != null )
+        {
+            builder.append( value, offset, length );
+        }
+    }
+
+
+    /**
+     * Return the underlying builder.
+     *
+     * @return The underlying builder
+     */
+    public StringBuilder getBuilder()
+    {
+        return builder;
+    }
+
+
+    /**
+     * Returns {@link StringBuilder#toString()}.
+     *
+     * @return The contents of the String builder.
+     */
+    @Override
+    public String toString()
+    {
+        return builder.toString();
+    }
+}