/* XBN Java: Generically useful, non-GUI Java code. http://sourceforge.net/projects/xbnjava Copyright (C) 1997-2003, Jeff Epstein All rights reserved. Modifications: No Redistribution in binary form, with or without modifications, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * If modifications are made to source code then this license should indicate that fact in the "Modifications" section above. * Neither the author, nor the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [NOTE: This license contains NO advertising clause.] */ package xbn.output; import java.io.PrintWriter; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.FileNotFoundException; import java.io.IOException; /**

An OWriter where the destination is a file, via java.io.PrintWriter.print/println. For use in Outputter.

Source code:  OWFile.java.  Example code  See the similar example code for OWriter.

You may deactivate or activate this object at any time. When you require a OWFile object, but do not wish to output anything, then create this object as permanently inactive. Although you cannot call the write/debug functions in this condition (errors would be thrown if you try), a permanently inactive OWFile saves memory and processing, because the java.io.PrintWriter is never created.

@version 0.9b @author Jeff Epstein, http://sourceforge.net/projects/xbnjava. **/ public class OWFile extends OWriter { private String sFileName = null; private PrintWriter pWriter = null; /**

Create a "permanently inactive" OWFile object. Use this when you require a OWFile object, but do not wish to actually output anything.

When permanently inactive, any call to activate, write or writeNoln will result in an AssertException. However, this allows your write statements to remain in your code, without actually wasting the energy to create the PrintWriter.

**/ public OWFile() { super(); sFileName = null; pWriter = null; } /**

Create a OWFile.

Equal to OWFile(s_fileName, true)

**/ public OWFile(String s_fileName) { this(s_fileName, true); } /**

Create a OWFile, with the specified name, file name and append configuration.

@param s_fileName The full directory path and file name. This file must be writeable, but does not have to exist. @param b_append Passed directly to the FileWriter constructor, which is part of making the PrintWriter file pointer. If "true", then existing text remains untouched, and all text written by this object will be appended to the end. If "false", then currently existing text is deleted.

Note that this setting is only applied during the constructor. After this object has been created, if deactivated and then activated again, the newly activated PrintWriter will always append (b_append=true) to the end of any existing text. See activate.

**/ public OWFile(String s_fileName, boolean b_append) { if(s_fileName == null || s_fileName.length() < 1) { throwAX("constructor: s_fileName must be non-null, and at least one character in length."); } activate(s_fileName, b_append); } /**

Output a line of text to the file with a newline added to the end.

@exception AssertException When this object is inactive. **/ public void write(String s_message) { try { pWriter.println(s_message); pWriter.flush(); } catch(NullPointerException npx) { throwFromWrite("write", npx); } } /**

Output a line of text to the file. No newline is added to the end.

@exception AssertException When this object is inactive. **/ public void writeNoln(String s_message) { try { pWriter.print(s_message); pWriter.flush(); } catch(NullPointerException npx) { throwFromWrite("writeNoLn", npx); } } /**

Output a newline only, to the file.

@exception AssertException When this object is inactive. **/ public void newln() { try { pWriter.println(); pWriter.flush(); } catch(NullPointerException npx) { throwFromWrite("newln", npx); } } private void throwFromWrite(String s_callingFunc, NullPointerException np_x) { if(!isActive()) { throwAX(s_callingFunc + ": OWFile is not active (getOWFile().isActive() is false)."); } else { throw new NullPointerException("ERROR in OWFile.writeNoln: Unknown error: " + np_x.toString()); } } /**

Activate this OWFile. Actually creates a "pipeline" (java.io.PrintWriter) to the file--as indicated by getPath, and creates the file if it does not already exist. This is a relatively expensive operation.

Deactivate with deactivate. Get with isActive

Here's what this function actually does:

new PrintWriter(new BufferedWriter(new FileWriter(getPath(), true)))

As indicated by the "true" parameter of the FileWriter constructor, this leaves existing text alone when creating the file pointer. Subsequent text written by this class is concatenated to the end of the file.

In the constructor of this class, it is possible to set the b_append variable to true, which tells the FileWriter that existing text should be deleted before creating the file pointer. Note this is only possible during the constructor. All manual calls to this activate function will set this boolean to true.

@exception AssertException If this object is permanently inactive or already active (isActive is true). @exception AssertException If the provided file name is not legal (is not writeable, is bogus, is a directory...). Remember, even if a file is found as legal at one moment--such as when this object was first created, it is possible for the characteristics of that file to be manually changed. Therefore, it is possible for that formerly-legal file to be suddenly illegal at a later time... @exception NullPointerException If some other unknown error has occured. **/ public final void activate() { if(isPermanentlyInactive()) { throwAX("activate: Object is permanently inactive."); } activate(getPath(), true); } private void activate(String s_fileName, boolean b_append) { if(isActive()) { throwAX("activate: Already active. Must deactivate before activating again."); } try { //Create the object to actually write to the file. It should always *append* //text into the file (the "true" paramater). pWriter = new PrintWriter(new BufferedWriter(new FileWriter(s_fileName, b_append))); //The PrintWriter was successfully created. } catch(FileNotFoundException fnfx) { throwAX("constructor: Exception thrown: [" + fnfx.toString() + "]. The filename must point to a writeable file. It does not have to exist. Filename=" + s_fileName); } catch(IOException iox) { throwAX("constructor: Exception thrown: [" + iox.toString() + "]. The filename must point to a writeable file. It does not have to exist. Filename=" + s_fileName); } if(getPath() == null) { //The filename has not yet been set. Set it. sFileName = s_fileName; } } /**

Deactivate this OWFile. This actually closes and nullifies the java.io.PrintWriter. If already inactive, this does nothing.

Activate with activate. Get with isActive

Continually using deactivate and activate is a relatively expensive operation, and not recommended. Instead of creating a OWFile and then immediately deactivating it (and leaving it that way), consider creating a permanently inactive OWFile instead.

**/ public void deactivate() { if(!isActive()) { return; } pWriter.close(); pWriter = null; } /**

Is this OWFile active?

Set with activate and deactivate

If permanently inactive, or if you've explicitely called deactivate, this object is inactive.

When inactive, calls to write and writeNoln will result in an AssertException.

@return true if the object is currently active.
false if the object is currently inactive. **/ public boolean isActive() { return (pWriter != null); } /**

Is this OWFile potentially active?. "Potentially active" is the opposite of "permanently inactive".

When potentially active, this object is either currently active, or is activate-able.

If create with any constructor except for the no-parameter constructor, this OWFile is potentially active.

@return true if the object is potentially active.
false if the object is permanently inactive. **/ public final boolean isPotentiallyActive() { return (getPath() != null); } /**

Is this OWFile permanently inactive?. "Permanently inactive" is the opposite of "potentially active"

When permanently inactive, it is not possible to ever activate this OWFile.

When this object was created with the no-parameter constructor, this OWFile is considered permanently inactive. This means that any attempt to use the activate or write/writeNoln functions will result in an error. When your code requires a OWFile object, but no output is desired, a permanently inactive OWFile is what you want. It fulfills your requirements, but does not waste any energy or memory on the PrintWriter.

@return !isPotentallyActive() **/ public final boolean isPermanentlyInactive() { return !isPotentiallyActive(); } /**

When this OWFile object is destroyed, this properly deactivates the internal PrintWriter. See deactivate.

**/ protected void finalize() throws Throwable { deactivate(); super.finalize(); } /**

Get the full file name.

@return s_fileName Exactly as provided to the constructor, as long as isPotentiallyActive equals true.
null If isPotentiallyActive equals false. **/ public final String getPath() { return sFileName; } /**

Get some information about this OWFile object.

**/ public String toString() { return this.getClass().getName() + ": getPath()=" + getPath() + ", isActive()=" + isActive() + ", isPotentiallyActive()=" + isPotentiallyActive(); } }