/** * Copyright (c) 2007-2009, JAGaToo Project Group all rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 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. * * Neither the name of the 'Xith3D Project Group' nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.jagatoo.util.ini; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; /** * The {@link IniWriter} writes ini files ;). * * @author Marvin Froehlich (aka Qudus) */ public class IniWriter { private final BufferedWriter writer; private boolean spaceGroup = false; private String indentString = null; private boolean putSpacesAroundEqualSign = true; private int minEqualSignPosition = -1; private int minValuePosition = -1; private int minCommentPosition = -1; private String nullValue = "N/A"; private boolean isFirstLine = true; private boolean isInGroup = false; /** * Sets the number of spaces to indent settings by. * * @param numSpaces */ public void setSettingIndentSpaces( int numSpaces ) { if ( numSpaces <= 0) { indentString = null; } else { char[] spaces = new char[ numSpaces ]; for ( int i = 0; i < numSpaces; i++ ) { spaces[i] = ' '; } this.indentString = new String( spaces ); } } /** * Gets the number of spaces to indent settings by. * * @return the number of spaces to indent settings by. */ public final int getSettingIndentSpaces() { if ( indentString == null ) return ( 0 ); return ( indentString.length() ); } /** * Configures the writer to put a spaces before and after the group name (between the brackets). * * @param b */ public void setSpaceGroup( boolean b ) { this.spaceGroup = b; } /** * Gets setting "spaceGroup". * * @return setting "spaceGroup". */ public final boolean getSpaceGroup() { return ( spaceGroup ); } /** * Configures the writer to put a spaces before and after the equal sign of a setting. * * @param b */ public void setPutSpacesAroundEqualSign( boolean b ) { this.putSpacesAroundEqualSign = b; } /** * Gets setting "putSpacesAroundEqualSign". * * @return setting "putSpacesAroundEqualSign". */ public final boolean getPutSpacesAroundEqualSign() { return ( putSpacesAroundEqualSign ); } /** * Configures the writer to put as many spaces before the equals sign, so that it is placed at least at the given column. * * @param minPos (Use negative values for no specific rule.) */ public void setMinEqualSignPosition( int minPos ) { this.minEqualSignPosition = minPos; } /** * Gets setting "minEqualSignPosition". * * @return setting "minEqualSignPosition". */ public final int getMinEqualSignPosition() { return ( minEqualSignPosition ); } /** * Configures the writer to put as many spaces before the value, so that it is placed at least at the given column. * * @param minPos (Use negative values for no specific rule.) */ public void setMinValuePosition( int minPos ) { this.minValuePosition = minPos; } /** * Gets setting "minValuePosition". * * @return setting "minValuePosition". */ public final int getMinValuePosition() { return ( minValuePosition ); } /** * Configures the writer to put as many spaces before the comment, so that it is placed at least at the given column. * * @param minPos (Use negative values for no specific rule.) */ public void setMinCommentPosition( int minPos ) { this.minCommentPosition = minPos; } /** * Gets setting "minCommentPosition". * * @return setting "minCommentPosition". */ public final int getMinCommentPosition() { return ( minCommentPosition ); } /** * Sets the String to be written for a null value. * * @param nullValue */ public void setNullValue( String nullValue ) { if ( nullValue == null ) throw new IllegalArgumentException( "nullValue must not be null." ); this.nullValue = nullValue; } /** * Gets the String to be written for a null value. * * @return the String to be written for a null value. */ public final String getNullValue() { return ( nullValue ); } /** * Gets the String to write to the ini file from the passed value. * * @param value the value to write to the ini file * @param quoteValue if <code>true</code>, the value will be enclosed by double quotes, if <code>false</code>, no quotes will be used, if <code>null</code> some default behavior will be used. * * @return the String to write to the ini file from the passed value. */ protected String getObjectValue( Object value, Boolean quoteValue ) { if ( quoteValue == Boolean.TRUE ) return ( "\"" + String.valueOf( value ) + "\"" ); if ( quoteValue == Boolean.FALSE ) return ( String.valueOf( value ) ); return ( "\"" + String.valueOf( value ) + "\"" ); } /** * Writes a new Group to the file. * * @param group * * @throws IOException */ public void writeGroup( String group ) throws IOException { if ( !isFirstLine ) writer.newLine(); writer.write( "[" ); if ( getSpaceGroup() ) writer.write( " " ); writer.write( group ); if ( getSpaceGroup() ) writer.write( " " ); writer.write( "]" ); writer.newLine(); isFirstLine = false; isInGroup = true; } /** * Writes a new setting to the next line. * * @param key * @param value if this is not a number, it is quoted in double-quotes and then written using the toString() method. * @param quoteValue * @param comment null for no comment * * @throws IOException */ public void writeSetting( String key, Object value, Boolean quoteValue, String comment ) throws IOException { int pos = 0; if ( indentString != null ) { writer.write( indentString ); pos += indentString.length(); } writer.write( key ); pos += key.length(); if ( getMinEqualSignPosition() > pos ) { for ( int i = pos; i < getMinEqualSignPosition() - 1; i++ ) { writer.write( ' ' ); pos++; } if ( getPutSpacesAroundEqualSign() ) { writer.write( "= " ); pos += 2; } else { writer.write( "=" ); pos += 1; } } else if ( getPutSpacesAroundEqualSign() ) { writer.write( " = " ); pos += 3; } else { writer.write( "=" ); pos += 1; } if ( value == null ) { value = getNullValue(); } else if ( ( value instanceof Number ) || ( value instanceof Boolean ) ) { value = String.valueOf( value ); } else if ( value instanceof Enum<?> ) { value = ( (Enum<?>)value ).name(); } else { value = getObjectValue( value, quoteValue ); } if ( getMinValuePosition() > pos ) { for ( int i = pos; i < getMinValuePosition() - 1; i++ ) { writer.write( ' ' ); pos++; } } writer.write( (String)value ); pos += ( (String)value ).length(); if ( comment != null ) { writer.write( ' ' ); if ( getMinCommentPosition() > pos ) { for ( int i = pos; i < getMinCommentPosition() - 1; i++ ) { writer.write( ' ' ); pos++; } } writer.write( "// " ); pos += 3; writer.write( comment ); pos += comment.length(); } writer.newLine(); isFirstLine = false; } /** * Writes a new setting to the next line. * * @param key * @param value if this is not a number, it is quoted in double-quotes and then written using the toString() method. * @param comment null for no comment * * @throws IOException */ public void writeSetting( String key, Object value, String comment ) throws IOException { writeSetting( key, value, null, comment ); } /** * Writes a new setting to the next line. * * @param key * @param value if this is not a number, it is quoted in double-quotes and then written using the toString() method. * * @throws IOException */ public final void writeSetting( String key, Object value ) throws IOException { writeSetting( key, value, null ); } /** * Writes a new (standalone) comment to the file. * * @param comment * * @throws IOException */ public void writeComment( String comment ) throws IOException { if ( isInGroup && ( indentString != null ) ) { writer.write( indentString ); } writer.write( "# " ); writer.write( comment ); writer.newLine(); isFirstLine = false; } /** * Writes an empty line to the file. * * @throws IOException */ public void writeEmptyLine() throws IOException { if ( isInGroup && ( indentString != null ) ) { writer.write( indentString ); } writer.newLine(); isFirstLine = false; } /** * Flushes the file. * * @throws IOException */ public void flush() throws IOException { writer.flush(); } /** * Flushes and closes the file. * * @throws IOException */ public void close() throws IOException { writer.close(); } public IniWriter( Writer writer ) { if ( writer instanceof BufferedWriter ) this.writer = (BufferedWriter)writer; else this.writer = new BufferedWriter( writer ); } public IniWriter( OutputStream out ) { this( new OutputStreamWriter( out ) ); } public IniWriter( File file ) throws IOException { this( new FileWriter( file ) ); } public IniWriter( String filename ) throws IOException { this( new FileWriter( filename ) ); } }