image
 
image
MultiOutputStream.java


/*::.
==================================================================================================================================
=================================================¦ Copyright © 2014 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       MultiOutputStream.java
Originator: Allen Baker (2014.07.05 20:48)
LayoutRev:  5
================================================================================================================================== */
package cosmicabyss.com.lib;

import java.io.*;
import java.util.*;
import java.net.*;



/*::
======================================================================================================================== *//**
Instances of this class represent a group of OutputStreams, all of which are sent the exact same output. It allows you
to send the same output to multiple endpoints with one I/O operation. A simple example is if you wanted to send the same
output from a program to two separate files. You would open both files, each as a separate and independent OutputStream
and then "wrap" both those OutputStreams inside of one MultiOutputStream. Each write method call on the
MultiOutputStream would be routed by the MultiOutputStream to both of the wrapped file OutputStreams.<P>

Another more interesting example allows you to make Java's standard console output - System.out (or System.err) send its
output to both the normal System.out (or System.err) and also to a file for logging purposes. To do so, you would open
the log file as a independent OutputStream and then wrap it together with System.out (or System.err) inside a single
MultiOutputStream. Then you would wrap the MultiOutputStream in a PrintStream and set the PrintStream as System.out (or
System.err).<P>

Salient characteristics of a MultiOutputStream are:
   <BLOCKQUOTE>
      => It allows the same output to be sent to multilple OutputStreams with a single output request.<BR>
      => It allows additional OutputStreams to be added to the MultiOutputStream at any time with no practical limit on
         Their numbers.<BR>
      => It allows OutputStreams to be removed from the MultiOutputStream at any time.
   </BLOCKQUOTE>

Subclass
   This class is derived from the OutputStream class. The abstraction it layers on top of OutputStream includes the
   following:
      <BLOCKQUOTE>
         => It allows the same output to be sent to multilple OutputStreams with a single output request.
      </BLOCKQUOTE>

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  //.
                  =========================================================================================
                  This example shows how to route both System.out and System.err to two destinations each.
                  System.out will be routed to both the normal System.out - the console - and to a log
                  file. The same will be done with System.err.
                  ----------------------------------------------------------------------------------------- //
                  try
                     {
                     //.
                     =========================================================================================
                     Create some file streams to send output to, one each for stdout and stderr messages.
                        Just for added excitement, set the stdout file stream to append to the end of the file
                        instead of overwritting it.
                     ----------------------------------------------------------------------------------------- //
                     FileOutputStream stdoutLogFile = new FileOutputStream("stdout.log", true);
                     FileOutputStream stderrLogFile = new FileOutputStream("stderr.log");
                     //.
                     =========================================================================================
                     Create a MultiOutputStream that routes stdout messages to both System.out (the console)
                     and the stdout file stream created above.
                     ----------------------------------------------------------------------------------------- //
                     MultiOutputStream multiStdout = new MultiOutputStream(System.out, stdoutLogFile);
                     //.
                     =========================================================================================
                     Create a MultiOutputStream that rerres stderr messages to both System.err (the error dump)
                     and the stderr file stream created above.
                     ----------------------------------------------------------------------------------------- //
                     MultiOutputStream multiStderr = new MultiOutputStream(System.err, stderrLogFile);
                     //.
                     =========================================================================================
                     Wrap each MultiOutputStream in a PrintStream
                     ----------------------------------------------------------------------------------------- //
                     PrintStream stdout = new PrintStream(multiStdout);
                     PrintStream stderr = new PrintStream(multiStderr);
                     //.
                     =========================================================================================
                     Reassigns the "standard" output stream to be our stdout PrintStream-wrapped
                     MultiOutputStream
                     ----------------------------------------------------------------------------------------- //
                     System.setOut(stdout);
                     //.
                     =========================================================================================
                     Reassigns the "standard" error stream to be our stderr PrintStream-wrapped
                     MultiOutputStream
                     ----------------------------------------------------------------------------------------- //
                     System.setErr(stderr);
                     }
                  catch (FileNotFoundException e)
                     {
                     =========================================================================================
                     Just rethrow the error if not able to create or open a file.
                     ----------------------------------------------------------------------------------------- //
                     throw e;
                     }
                  //.
                  =========================================================================================
                  Send a message to the stdout PrintStream which wraps the stdout MultiOutputStream. With
                  one write request, the message will be sent to both System.out (the console) and the
                  stdout file stream created above.
                  ----------------------------------------------------------------------------------------- //
                  System.out.println("This is a test of the emergency broadcast system. This is only a test.");
                  //.
                  =========================================================================================
                  Send a message to the stderr PrintStream which wraps the stderr MultiOutputStream. With
                  one write request, the message will be sent to both System.err (the console) and the
                  stderr file stream created above.
                  ----------------------------------------------------------------------------------------- //
                  System.err.println
                     (
                     "We interrupt this program. This is a national emergency. The President of the " +
                     "United States or his designated representative will appear shortly over the "   +
                     "Emergency Broadcast System."
                     );
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="MultiOutputStream.java.html">
               MultiOutputStream.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class MultiOutputStream extends OutputStream
   {



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Constants  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   CLASS_NAME:
      The name of this class
   DFLT_LINE_LEN:
      The default line length for word wrapping
   ------------------------------------------------------------------------------------------ */
   private static final XString  CLASS_NAME    = new XString(MultiOutputStream.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Types  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Enums  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Structs  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Interfaces  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   cOut:
      Formatted and time-stamped console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream cOut = ConsoleStream.getSingleton();
   /*.
   ==========================================================================================
   iOutputStreams:
      An array of all the OutputStreams currently wrapped inside this MultiOutputStream
      instance.
   ------------------------------------------------------------------------------------------ */
   private ArrayList<OutputStream> iOutputStreams = new ArrayList<OutputStream>();



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Functions  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    :METHOD:000:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates a MultiOutputStream class object with no OutputStreams to route write requests
   to.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#000">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream()
      {
      initializeInstanceConstantsAndVariables();
      }



   /*:                                    :METHOD:001:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates a MultiOutputStream class object and sets the ArrayList of OutputStreams to
   which this instance will route write requests from a list of OutputStreams passed in as arguments
   through the pOutputStreams parameter. If the list of OutputStreams in the argument is empty, this
   instance will of course be initialized to route write requests to NO OutputStreams.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#001">View source</A>

   @param
      pOutputStreams is an array of OutputStreams to wrap inside the MultiOutputStream instance that is
      created by this constructor.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream(OutputStream... pOutputStreams)
      {
      this();
      for (OutputStream outStream: pOutputStreams) this.iOutputStreams.add(outStream);
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Initialization  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   static
      {
      /*.
      ==========================================================================================
      Make sure all the class constants and variables are initialized the first time the JVM
      loads this class code and before anything else in this class is accessed
      ------------------------------------------------------------------------------------------ */
      initializeClassConstantsAndVariables();
      }



   /*:                                    :METHOD:002:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the class constants and variables

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#002">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private static void initializeClassConstantsAndVariables()
      {
      }



   /*:                                    :METHOD:003:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the instance constants and variables. The intent of this method is to
   encapsulate all the common instance initializations in one place that can be called from all the
   constructors.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#003">View source</A>

   @return
      True if the initialization succeeded, flase otherwise.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   private boolean initializeInstanceConstantsAndVariables()
      {
      boolean  successCode = true;

      if (successCode)
         {
         }
      return successCode;
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    :METHOD:004:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   The description of this method is the same as the one for the method of the same name in the JDK SE
   API OutputStream Class documentation.<P>

      <B>
         Documentation:
      </B>
       <A HREF="http://docs.oracle.com/javase/8/docs/api/java/lang/OutputStream.html">
         View JDK SE API OutputStream Class
      </A>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#004">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void write(int pBytes) throws IOException
      {
      for (OutputStream outStream: iOutputStreams) outStream.write(pBytes);
      }



   /*:                                    :METHOD:005:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   The description of this method is the same as the one for the method of the same name in the JDK SE
   API OutputStream Class documentation.<P>

      <B>
         Documentation:
      </B>
       <A HREF="http://docs.oracle.com/javase/8/docs/api/java/lang/OutputStream.html">
         View JDK SE API OutputStream Class
      </A>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#005">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void write(byte[] pBytes) throws IOException
      {
      for (OutputStream outStream: iOutputStreams) outStream.write(pBytes);
      }



   /*:                                    :METHOD:006:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   The description of this method is the same as the one for the method of the same name in the JDK SE
   API OutputStream Class documentation.<P>

      <B>
         Documentation:
      </B>
       <A HREF="http://docs.oracle.com/javase/8/docs/api/java/lang/OutputStream.html">
         View JDK SE API OutputStream Class
      </A>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#006">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void write(byte[] pBytes, int pOffset, int pNumberOfBytes) throws IOException
      {
      for (OutputStream outStream: iOutputStreams) outStream.write(pBytes, pOffset, pNumberOfBytes);
      }



   /*:                                    :METHOD:007:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   The description of this method is the same as the one for the method of the same name in the JDK SE
   API OutputStream Class documentation.<P>

      <B>
         Documentation:
      </B>
       <A HREF="http://docs.oracle.com/javase/8/docs/api/java/lang/OutputStream.html">
         View JDK SE API OutputStream Class
      </A>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#007">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void flush() throws IOException
      {
      for (OutputStream outStream: iOutputStreams) outStream.flush();
      }



   /*:                                    :METHOD:008:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   The description of this method is the same as the one for the method of the same name in the JDK SE
   API OutputStream Class documentation.<P>

      <B>
         Documentation:
      </B>
       <A HREF="http://docs.oracle.com/javase/8/docs/api/java/lang/OutputStream.html">
         View JDK SE API OutputStream Class
      </A>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#008">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void close() throws IOException
      {
      for (OutputStream outStream: iOutputStreams) outStream.close();
      }



   /*:                                    :METHOD:009:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds all the OutputStreams in a Collection of OutputStreams to this MultiOutputStream
   instance.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#009">View source</A>

   @return
      A reference to this object

   @param
      pOutputStreams is a Collection of OutputStreams, all the elements of which are added by this
      method to this MultiOutputStream instance.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream add(Collection<OutputStream> pOutputStreams)
      {
      for (OutputStream outStream: pOutputStreams) this.iOutputStreams.add(outStream);
      return this;
      }



   /*:                                    :METHOD:010:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds all the OutputStreams passed in as arguments to this MultiOutputStream instance.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#010">View source</A>

   @return
      A reference to this object

   @param
      pOutputStreams is an variable sized [0..n] group of OutputStream arguments, all of which are
      added by this method to this MultiOutputStream object.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream add(OutputStream... pOutputStreams)
      {
      for (OutputStream outStream: pOutputStreams) this.iOutputStreams.add(outStream);
      return this;
      }



   public MultiOutputStream add(XFile pFile) throws Exception
      {
      FileOutputStream  outStream = new FileOutputStream(pFile.getCanonicalPath());
      this.iOutputStreams.add(outStream);
      return this;
      }
   public MultiOutputStream add(TextWriter pFile) throws Exception
      {
      FileOutputStream  outStream = new FileOutputStream(pFile.getCanonicalPath());
      this.iOutputStreams.add(outStream);
      return this;
      }
   public MultiOutputStream add(String pFileName) throws Exception
      {
      FileOutputStream  outStream = new FileOutputStream(pFileName);
      this.iOutputStreams.add(outStream);
      return this;
      }



   /*:                                    :METHOD:011:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method removes all the OutputStreams in a Collection of OutputStreams from this
   MultiOutputStream instance.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#011">View source</A>

   @return
      A reference to this object

   @param
      pOutputStreams is a Collection of OutputStreams, all the elements of which are removed by this
      method from this MultiOutputStream object.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream remove(Collection<OutputStream> pOutputStreams)
      {
      for (OutputStream outStream: pOutputStreams) this.iOutputStreams.remove(outStream);
      return this;
      }



   /*:                                    :METHOD:012:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method removes all the OutputStreams passed in as arguments from this MultiOutputStream
   instance.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#012">View source</A>

   @return
      A reference to this object

   @param
      pOutputStreams is an variable sized [0..n] group of OutputStream arguments, all of which are
      removed by this method from this MultiOutputStream object.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream remove(OutputStream... pOutputStreams)
      {
      for (OutputStream outStream: pOutputStreams) this.iOutputStreams.remove(outStream);
      return this;
      }



   /*:                                    :METHOD:013:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method removes all the OutputStreams from this MultiOutputStream instance.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#013">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream clear()
      {
      this.iOutputStreams.clear();
      return this;
      }



   /*:                                    :METHOD:014:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This boilerplate method is used for testing an instantiated object of this class and may include any
   code the developer chooses.

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#014">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public MultiOutputStream test() throws Exception
      {
      cOut.titledPrintf
         (
         "\"HELLO WORLD!\"",
         "%s  %s  %s",
         "I'm an object of the", CLASS_NAME, "class, and I approved this message."
         );
      return this;
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Main  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    :METHOD:015:BOOKMARK:
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method allows this class file to be unit tested as a standalone application. It's the method
   that's called when the class is invoked from the command line by using the java application launcher
   - "java". Main() is not a required method, but the practice of putting one in each class and
   wrapping class test code within it allows easy unit testing of the class; and main does not need to
   be removed when testing is complete.

   <P>
      <DL>
         <DT>
            <B>
               Command line usage:
            </B>
            <DD>
               Java cosmicabyss.com.lib.MultiOutputStream
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="MultiOutputStream.java.html#015">View source</A>

   @param
      pArgs contains the command line arguments with which this class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      /*.
      ==========================================================================================
      Greetings !
      ------------------------------------------------------------------------------------------ */
      cOut.banner(CLASS_NAME);
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      try
         {
         /*.
         ==========================================================================================
         Create some file streams to send output to, one each for stdout and stderr messages.
            Set the stdout file stream to append to the end of the file instead of overwritting it.
         ------------------------------------------------------------------------------------------ */
         FileOutputStream stdoutLogFile = new FileOutputStream("stdout.log", true);
         FileOutputStream stderrLogFile = new FileOutputStream("stderr.log");
         /*.
         ==========================================================================================
         Create a MultiOutputStream that routes stdout messages to both System.out (the console)
         and the stdout file stream created above.
         ------------------------------------------------------------------------------------------ */
         MultiOutputStream multiStdout = new MultiOutputStream(System.out, stdoutLogFile);
         /*.
         ==========================================================================================
         Create a MultiOutputStream that rerres stderr messages to both System.err (the error dump)
         and the stderr file stream created above.
         ------------------------------------------------------------------------------------------ */
         MultiOutputStream multiStderr = new MultiOutputStream(System.err, stderrLogFile);
         /*.
         ==========================================================================================
         Wrap each MultiOutputStream in a PrintStream
         ------------------------------------------------------------------------------------------ */
         PrintStream stdout = new PrintStream(multiStdout);
         PrintStream stderr = new PrintStream(multiStderr);
         /*.
         ==========================================================================================
         Reassigns the "standard" output stream to be our stdout PrintStream-wrapped
         MultiOutputStream
         ------------------------------------------------------------------------------------------ */
         System.setOut(stdout);
         /*.
         ==========================================================================================
         Reassigns the "standard" error stream to be our stderr PrintStream-wrapped
         MultiOutputStream
         ------------------------------------------------------------------------------------------ */
         System.setErr(stderr);
         }
      catch (FileNotFoundException e)
         {
         /*.
         ==========================================================================================
         Just rethrow the error if not able to create or open a file.
         ------------------------------------------------------------------------------------------ */
         throw e;
         }
      /*.
      ==========================================================================================
      Send a message to the stdout PrintStream which wraps the stdout MultiOutputStream. With
      one write request, the message will be sent to both System.out (the console) and the
      stdout file stream created above.
      ------------------------------------------------------------------------------------------ */
      System.out.println(Const.EMERGENCY_TEST);
      /*.
      ==========================================================================================
      Send a message to the stderr PrintStream which wraps the stderr MultiOutputStream. With
      one write request, the message will be sent to both System.err (the console) and the
      stderr file stream created above.
      ------------------------------------------------------------------------------------------ */
      System.err.println(Const.EMERGENCY);
      }



   }  // End of Class MultiOutputStream



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Notes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */