package org.cyclopsgroup.jmxterm.io;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
import javax.management.openmbean.CompositeData;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
/**
* A utility to print out object values in particular format.
*
* @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
*/
public class ValueOutputFormat
{
private final int indentSize;
private final boolean showDescription;
private final boolean showQuotationMarks;
/**
* Default constructor with indentiation = 2, showDescription and showQuotationMarks are both true
*/
public ValueOutputFormat()
{
this( 2, true, true );
}
/**
* @param indentSize Size of indentation
* @param showDescription True if value description is printed
* @param showQuotationMarks True if quotation mark is printed
*/
public ValueOutputFormat( int indentSize, boolean showDescription, boolean showQuotationMarks )
{
Validate.isTrue( indentSize >= 0, "Invalid indent size value " + indentSize );
this.indentSize = indentSize;
this.showDescription = showDescription;
this.showQuotationMarks = showQuotationMarks;
}
/**
* Print out equal expression of an variable with description
*
* @param output Output to print to
* @param name Name of variable
* @param value Value of variable
* @param description Description of variable
*/
public void printExpression( CommandOutput output, Object name, Object value, String description )
{
printExpression( output, name, value, description, 0 );
}
/**
* Print out equal expression of an variable with description
*
* @param output Output to print to
* @param name Name of variable
* @param value Value of variable
* @param description Description of variable
* @param indent Starting indent position
*/
private void printExpression( CommandOutput output, Object name, Object value, String description, int indent )
{
output.print( StringUtils.repeat( " ", indent ) );
printValue( output, name, indent );
output.print( " = " );
printValue( output, value, indent );
output.print( ";" );
if ( showDescription && description != null )
{
output.print( " (" + description + ")" );
}
output.println( "" );
}
/**
* @param output Output writer where value is printed to
* @param value Value to print
*/
public void printValue( CommandOutput output, Object value )
{
printValue( output, value, 0 );
}
/**
* Print out expression of given value considering various possible types of value
*
* @param output Output writer where value is printed
* @param value Object value which can be anything
* @param indent Starting indentation length
*/
private void printValue( CommandOutput output, Object value, int indent )
{
if ( value == null )
{
output.print( "null" );
}
else if ( value.getClass().isArray() )
{
int length = Array.getLength( value );
output.print( "[ " );
for ( int i = 0; i < length; i++ )
{
if ( i != 0 )
{
output.print( ", " );
}
printValue( output, Array.get( value, i ), indent );
}
output.print( " ]" );
}
else if ( Collection.class.isAssignableFrom( value.getClass() ) )
{
boolean start = true;
output.print( "( " );
for ( Object obj : ( (Collection<?>) value ) )
{
if ( !start )
{
output.print( ", " );
}
start = false;
printValue( output, obj, indent );
}
output.print( " )" );
}
else if ( Map.class.isAssignableFrom( value.getClass() ) )
{
output.println( "{ " );
for ( Map.Entry<?, ?> entry : ( (Map<?, ?>) value ).entrySet() )
{
printExpression( output, entry.getKey(), entry.getValue(), null, indent + indentSize );
}
output.print( StringUtils.repeat( " ", indent ) + " }" );
}
else if ( CompositeData.class.isAssignableFrom( value.getClass() ) )
{
output.println( "{ " );
CompositeData data = (CompositeData) value;
for ( Object key : data.getCompositeType().keySet() )
{
Object v = data.get( (String) key );
printExpression( output, key, v, data.getCompositeType().getDescription( (String) key ), indent
+ indentSize );
}
output.print( StringUtils.repeat( " ", indent ) + " }" );
}
else if ( value instanceof String && showQuotationMarks )
{
output.print( "\"" + value + "\"" );
}
else
{
output.print( value.toString() );
}
}
}