package de.axone.tools; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.nio.ByteBuffer; import java.util.Formatter; import java.util.Map; public abstract class Text { /** * Makes a one line Banner * * Like label(...) but prints the given width * * @param c char to use for banner border * @param width of banner * @param label label to print in banner * @return the banner as string */ public static String banner( char c, int width, String label ){ if( label == null ) label = "-null-"; StringBuilder result = new StringBuilder(); result.append( '\n' ); lineNlBB( result, c, width ); int labelLength = label.length() + 2; int leftLength = ( width - labelLength )/2; int rightLength = width - ( leftLength + labelLength ); lineBB( result, c, leftLength ); result.append( ' ' ).append( label ).append( ' ' ); lineBB( result, c, rightLength ); result.append( '\n' ); lineNlBB( result, c, width ); return result.toString(); } public static String banner( String label ){ return banner( '#', 79, label ); } public static String banner( char c, String label ){ return banner( c, 79, label ); } /** * Create a text label which will look like that: * * ################## * ### label text ### * ################## * * @param c char to use for border * @param label to display in center of label * @return the label as string */ public static String label( char c, String label ){ return banner( c, label.length()+8, label ); } public static String window( int width, int height, CharSequence output ){ StringBuilder msg = new StringBuilder(); String text = output.toString(); int start, end=-1; int tHeight=0; while( true ){ start = end+1; end = text.indexOf( '\n', start ); String line; if( end > 0 ){ line = text.substring( start, end ); } else { line = text.substring( start ); } tHeight++; int spaces = width - line.length() - 2; int left = spaces/2; int right = spaces-left; msg.append( '|' ); lineBB( msg, ' ', left ); msg.append( line ); lineBB( msg, ' ', right ); msg.append( '|' ); msg.append( '\n' ); if( end < 0 ) break; } int whiteLines = height-tHeight; int topSpaces = whiteLines/2; int bottomSpaces = whiteLines - topSpaces; StringBuilder result = new StringBuilder(); result.append( '\n' ); lineBB( result, '+', '-', width ); result.append( '\n' ); for( int i=0; i<topSpaces-1; i++ ){ lineBB( result, '|', ' ', width ); result.append( '\n' ); } result.append( msg ); for( int i=0; i<bottomSpaces-1; i++ ){ lineBB( result, '|', ' ', width ); result.append( '\n' ); } lineBB( result, '+', '-', width ); result.append( '\n' ); return result.toString(); } /** * Makes a big multiline banner / posters * * The width is calculated by the widest line * * @param c char to use for border * @param text to display in center of poster * @return the poster as string */ public static String poster( char c, String text ){ StringBuilder result = new StringBuilder(); result.append( '\n' ); if( text == null ) text = ""; text = text.trim(); try { int width = 0; BufferedReader r = new BufferedReader( new StringReader( text ) ); String line; while( ( line = r.readLine() ) != null ){ if( line.length() > width ) width = line.length(); } width += 4; // borders lineNlBB( result, c, width ); // Reset to 0. mart/reset seems strange r = new BufferedReader( new StringReader( text ) ); while( ( line = r.readLine() ) != null ){ Text.limitedFixedLineBB( result, c, width, line, false ); result.append( '\n' ); } lineBB( result, c, width ); } catch( IOException e ) { e.printStackTrace(); } return result.toString(); } public static String poster( String text ){ return poster( '#', text ); } public static String poster( char c, Iterable<?> collection ){ return poster( c, Str.join( "\n", collection ) ); } public static String poster( Iterable<?> collection ){ return poster( '#', collection ); } public static String poster( char c, Map<?,?> map ){ return poster( c, Str.join( "\n", Mapper.mapToList( ": ", map ) ) ); } public static String poster( Map<?,?> map ){ return poster( '#', map ); } public static StringBuilder lineNlBB( StringBuilder buffer, char outer, char inner, int width ){ lineBB( buffer, outer, inner, width ); buffer.append( '\n' ); return buffer; } public static StringBuilder lineBB( StringBuilder buffer, char outer, char inner, int width ){ buffer.append( outer ); for( int i = 0; i < width-2; i++ ){ buffer.append( inner ); } buffer.append( outer ); return buffer; } public static StringBuilder lineNlBB( StringBuilder buffer, char c, int width ){ lineBB( buffer, c, width ); buffer.append( '\n' ); return buffer; } public static StringBuilder lineBB( StringBuilder buffer, char c, int width ){ for( int i = 0; i < width; i++ ){ buffer.append( c ); } return buffer; } public static StringBuilder lineB( char c, int width ){ StringBuilder buffer = new StringBuilder( width ); return lineBB( buffer, c, width ); } public static String line( char c, int width ){ return lineB( c, width).toString(); } public static String line( int width ){ return lineB( '-', width).toString(); } public static StringBuilder lineBB( StringBuilder buffer, char c, int width, String text, boolean alignRight ){ if( text.length() > width-4 ) text = text.substring( 0, width-4 ); int left = 1; int right = width - 3 - text.length(); if( alignRight ){ // swap with xor. left ^= right; right ^= left; left ^= right; } lineBB( buffer, c, left ); buffer.append( ' ' ); buffer.append( text ); buffer.append( ' ' ); lineBB( buffer, c, right ); return buffer; } public static StringBuilder lineB( char c, int width, String text, boolean alignRight ){ return lineBB( new StringBuilder(), c, width, text, alignRight ); } public static String line( char c, int width, String text, boolean alignRight ){ return lineB( c, width, text, alignRight ).toString(); } public static String line( char c, int width, String text ){ return line( c, width, text, false ); } public static StringBuilder xBB( StringBuilder buffer, String text, int repeat ){ for( ; repeat>=0; repeat-- ) buffer.append( text ); return buffer; } public static StringBuilder xB( String text, int repeat ){ return xBB( new StringBuilder(), text, repeat ); } public static String x( String text, int repeat ){ return xB( text, repeat ).toString(); } /** * Returns the text surrounded by the given char. * * E.g.: <tt>limitText( '#', "Test" )</tt> will return "<tt># Test #</tt>" * * @param buffer to print into * @param c char to use for border * @param text to display at center * @return the limited text as passed thru string builder */ public static StringBuilder limitedTextBB( StringBuilder buffer, char c, String text ){ buffer .append( c ) .append( ' ' ) .append( text ) .append( ' ' ) .append( c ); return buffer; } public static StringBuilder limitedTextB( char c, String text ){ StringBuilder buffer = new StringBuilder(); return limitedTextBB( buffer, c, text ); } public static String limitedText( char c, String text ){ return limitedTextB( c, text ).toString(); } /** * Returns a text with fixed width. * Too short strings are filled with spaces. * Too long strings are cut according to parameter <tt>limit</tt> * * @param builder to print into * @param width of text returned * @param text to print * @param limit <tt>true</tt> will cut off the end of the text. * * @return the line with the passed thru string builder */ public static StringBuilder fixedWidthLineBB( StringBuilder builder, int width, String text, boolean limit ){ int length = text.length(); int dif = width - length; if( dif < 0 && limit ){ text = text.substring( 0, width ); } builder.append( text ); if( dif > 0 ){ lineBB( builder, ' ', dif ); } return builder; } public static StringBuilder fixedWidthLineB( int width, String text, boolean limit ){ StringBuilder builder = new StringBuilder(); return fixedWidthLineBB( builder, width, text, limit ); } public static String fixedWidthLine( int width, String text, boolean limit ){ return fixedWidthLineB( width, text, limit ).toString(); } /** * Combination of the two named methods * * @param builder to print into * @param c char to use for border * @param width of text returned * @param text to print * @param limit <tt>true</tt> will cut off the end of the text. * @return the line with the passed thru string builder */ public static StringBuilder limitedFixedLineBB( StringBuilder builder, char c, int width, String text, boolean limit ){ return limitedTextBB( builder, c, fixedWidthLine( width-4, text, limit ) ); } public static StringBuilder limitedFixedLineB( char c, int width, String text, boolean limit ){ StringBuilder builder = new StringBuilder(); return limitedFixedLineBB( builder, c, width, text, limit ); } public static String limitedFixedLine( char c, int width, String text, boolean limit ){ return limitedFixedLineB( c, width, text, limit ).toString(); } /** * Prints values in format ....Name: Value with * configurable indention * * @param builder to print into * @param indent number of spaces to prepend * @param label to print * @param valueO value to print. objects are converted to string * @return the value with the passed thru string builder */ public static StringBuilder valueBB( StringBuilder builder, int indent, String label, Object valueO ){ String value = valueO != null ? valueO.toString() : S._NULL_; for( int i = 0; i < indent; i++ ) builder.append( ' ' ); builder .append( label ) .append( ": " ) .append( value ) .append( '\n' ) ; return builder; } public static StringBuilder valueB( int indent, String label, Object valueO ){ String value = valueO != null ? valueO.toString() : S._NULL_; StringBuilder result = new StringBuilder( indent + label.length() + value.length() + 3 ); return valueBB( result, indent, label, valueO ); } public static String value( int indent, String label, Object valueO ){ return valueB( indent, label, valueO ).toString(); } /** * Generate indention * * @param builder to print into * @param indent number of spaces to prepend * @return the indended line with the passed thru string builder */ public static StringBuilder indentBB( StringBuilder builder, int indent ){ return indentBB( builder, indent, ' ' ); } public static StringBuilder indentBB( StringBuilder builder, int indent, char c ){ lineBB( builder, c, indent ); return builder; } public static StringBuilder indentB( int indent ){ return indentB( indent, ' ' ); } public static StringBuilder indentB( int indent, char c ){ StringBuilder result = new StringBuilder( indent ); return indentBB( result, indent, c ); } public static String indent( int indent ){ return indent( indent, ' ' ); } public static String indent( int indent, char c ){ return indentB( indent, c ).toString(); } public static String arrayHex( byte[] data ){ return arrayHexB( data ).toString(); } public static StringBuilder arrayHexB( byte[] data ){ return arrayHexBB( new StringBuilder(), data ); } public static StringBuilder arrayHexBB( StringBuilder builder, byte[] data ){ return arrayHexBB( builder, data, 32, -1 ); } public static String arrayHex( byte[] data, int widht ){ return arrayHexB( data, widht ).toString(); } public static StringBuilder arrayHexB( byte[] data, int widht ){ return arrayHexBB( new StringBuilder(), data, widht ); } public static StringBuilder arrayHexBB( StringBuilder builder, byte[] data, int width ){ return arrayHexBB( builder, data, width, -1 ); } public static String arrayHex( byte[] data, int widht, int indent ){ return arrayHexB( data, widht, indent ).toString(); } public static StringBuilder arrayHexB( byte[] data, int widht, int indent ){ return arrayHexBB( new StringBuilder(), data, widht, indent ); } public static StringBuilder arrayHexBB( StringBuilder builder, byte[] data, int width, int indent ){ @SuppressWarnings( "resource" ) Formatter f = new Formatter( builder ); if( indent > 0 ) indentBB( builder, indent ); for( int i=0; i<data.length; i++ ){ f.format( "%02x", data[i] ); if( i < data.length-1 ){ if( i%width == width-1 ){ builder.append( '\n' ); if( indent > 0 ) indentBB( builder, indent ); } else { builder.append( ' ' ); } } } return builder; } public static String arrayHex( ByteBuffer data, int widht ){ return arrayHex( data, widht, 0 ); } public static String arrayHex( ByteBuffer data, int widht, int indent ){ return arrayHexB( data, widht, indent ).toString(); } public static StringBuilder arrayHexB( ByteBuffer data, int widht, int indent ){ return arrayHexBB( new StringBuilder(), data, widht, indent ); } public static StringBuilder arrayHexBB( StringBuilder builder, ByteBuffer data, int width, int indent ){ @SuppressWarnings( "resource" ) Formatter f = new Formatter( builder ); if( indent > 0 ) indentBB( builder, indent ); for( int i=data.position(); i<data.limit(); i++ ){ f.format( "%02x", data.get(i) ); if( i < data.limit()-1 ){ if( i%width == width-1 ){ builder.append( '\n' ); if( indent > 0 ) indentBB( builder, indent ); } else { builder.append( ' ' ); } } } return builder; } /** * Trim text to a certain length. * Append timmedMark if text is longer than expected. * * If a trimmedMark is supplied this method makes sure that the trimmed text with * mark appended is not longer than 'width'. * * @param text to trim * @param width to trim to * @param trimmedMark mark to output when trimmed * @return the trimmed value */ public static String trimTo( String text, int width, String trimmedMark ){ if( text.length() <= width ) return text; if( trimmedMark != null ) width = width - trimmedMark.length(); if( width < 0 ) throw new IllegalArgumentException( "width is less than trimmedMark length" ); return text.substring( 0, width ) + trimmedMark; } public enum Align { LEFT, RIGHT; } public static String left( String text, int width ){ if( text != null && text.length() > 0 ) text = text + " "; return align( Align.LEFT, text, width, '.' ); } public static String right( String text, int width ){ if( text != null && text.length() > 0 ) text = " " + text; return align( Align.RIGHT, text, width, '.' ); } public static String align( Align align, String text, int width, char fillChar ){ return alignB( align, text, width, fillChar ).toString(); } public static StringBuilder alignB( Align align, String text, int width, char fillChar ){ return alignBB( new StringBuilder(), align, text, width, fillChar ); } public static StringBuilder alignBB( StringBuilder builder, Align align, String text, int width, char fillChar ){ if( text == null ) text = ""; if( text.length() >= width ) return builder.append( text ); if( align == Align.LEFT ){ builder.append( text ); lineBB( builder, fillChar, width-text.length() ); return builder; } else if( align == Align.RIGHT ){ lineBB( builder, fillChar, width-text.length() ); builder.append( text ); return builder; } else { throw new IllegalArgumentException( "Not supported Alignment: " + align ); } } public static String diff( String s1, String s2 ){ return diff( s1, s2, -1 ); } public static String diff( String s1, String s2, int truncate ){ if( s1 == s2 ) return "[SAME]"; if( s1 == null ) return "[s1 IS NULL]"; if( s2 == null ) return "[s2 IS NULL]"; if( s1.equals( s2 ) ) return "[EQUAL]"; String min; if( s1.length() < s2.length() ){ min = s1; //max = s2; } else { min = s2; //max = s1; } StringBuilder leftB = new StringBuilder(); int i; for( i=0; i<min.length(); i++ ){ char c1 = s1.charAt( i ); char c2 = s2.charAt( i ); if( c1!=c2 ){ leftB.append( "--->[:" ); break; } leftB.append( c1 ); } StringBuilder rightB = new StringBuilder(); int j; for( j=0; j<min.length(); j++ ){ char c1 = s1.charAt( s1.length()-1 -j ); char c2 = s2.charAt( s2.length()-1 -j ); if( c1!=c2 ){ rightB.insert( 0, ":]<---" ); break; } rightB.insert( 0, c1 ); } String left = leftB.toString(); String right = rightB.toString(); StringBuilder result = new StringBuilder(); if( truncate >= 0 ){ truncate += 6; // --->[ / ]<--- if( left.length() > truncate ){ left = left.substring( left.length() - truncate ); } if( right.length() > truncate ){ right = right.substring( 0, truncate ); } } result.append( left ); result.append( s1.subSequence( i, s1.length() -j ) ); result.append( ":|:" ); result.append( s2.subSequence( i, s2.length() -j ) ); result.append( right ); return result.toString(); } public static StringBuilder reverseB( CharSequence s ){ StringBuilder result = new StringBuilder(); for( int i=0; i<s.length(); i++ ){ result.append( s.charAt( s.length()-1-i ) ); } return result; } // Various toString methods for conversion of 'any object' to string }