package dmg.util; import java.util.ArrayDeque; import java.util.Deque; /** * * * @author Patrick Fuhrmann * @version 0.1, 15 Feb 1998 */ public class Formats { public static final int CENTER = 0x1 ; public static final int RIGHT = 0x4 ; public static final int LEFT = 0x2 ; public static final int CUT = 0x8 ; public static String field( String in , int field ){ return field(in,field,LEFT) ; } public static String field( String in , int field , int flags ){ if( in.length() >= field ){ if( ( flags & CUT ) > 0 ){ return in.substring( 0 , field+1 ) ; }else{ return in ; } } StringBuilder sb = new StringBuilder() ; int i ; if( ( flags & CENTER ) > 0 ){ int diff = field - in.length() ; int left = diff / 2 ; int right = diff - left ; for( i = 0 ; i < left ; i++ ) { sb.append(' '); } sb.append( in ) ; for( i = 0 ; i < right ; i++ ) { sb.append(' '); } }else if( ( flags & RIGHT ) > 0 ){ int diff = field - in.length() ; for( i = 0 ; i < diff ; i++ ) { sb.append(' '); } sb.append( in ) ; }else{ sb.append( in ) ; int diff = field - in.length() ; for( i = 0 ; i < diff ; i++ ) { sb.append(' '); } } return sb.toString() ; } public static String cutClass( String c ){ int lastDot = c.lastIndexOf( '.' ) ; if( ( lastDot < 0 ) || ( lastDot >= ( c.length() - 1 ) ) ) { return c; } return c.substring( lastDot+1 ) ; } private static final int RP_IDLE = 0 ; private static final int RP_DOLLAR = 1 ; private static final int RP_OPENED = 2 ; /** * Starting after the opening sequence of a placeholder ('$' followed by '{'), this method * scans until the end of the placeholder ('}') and pushes a replacement sourced from * {@code replaceable} to {@code out}. * * Handles both recursive, nested and incomplete placeholders. * * @param in Input sequence to scan * @param pos Position of the first character of the key * @param out Output sequence * @param replaceable Source of replacements for placeholders * @param stack Placeholders already replaced in the input sequence - prevents infinite recursion * @return Position of the first character after the end of the placeholder */ private static int replaceKey(char[] in, int pos, StringBuilder out, Replaceable replaceable, Deque<String> stack) { int mark = pos; int length = in.length; StringBuilder key = new StringBuilder(length); char c1; while (pos < length && (c1 = in[pos]) != '}') { if (c1 != '$' || pos + 1 == length) { /* Regular character */ pos++; } else { key.append(in, mark, pos - mark); char c2 = in[pos + 1]; switch (c2) { case '{': /* Nested placeholder */ pos = replaceKey(in, pos + 2, key, replaceable, stack); break; case '$': /* Escaped $ symbol */ key.append('$'); pos += 2; break; default: /* False alarm - sequence got no special meaning */ key.append(c1).append(c2); pos += 2; break; } mark = pos; } } key.append(in, mark, pos - mark); if (pos < length) { /* Complete placeholder */ pos++; /* Lookup replacement value */ String keyName = key.toString(); String keyValue = replaceable.getReplacement(keyName); /* Unless we already replaced in once in the current stack, replace any placeholders in the value */ if (keyValue == null || stack.contains(keyName)) { out.append("${").append(keyName).append('}'); } else { stack.push(keyName); replaceKeywords(keyValue.toCharArray(), out, replaceable, stack); stack.pop(); } } else { /* Incomplete placeholder - got to end of input sequence without closing curly brace */ out.append("${").append(key); } return pos; } /** * Replaces placeholders in {@code in}, writing the result to {@code out}. Replacements for * placeholders are sourced from {@code replaceable}. * * @param in Input sequence * @param out Output sequence * @param replaceable Source of replacements for placeholders * @param stack Placeholders already replaced in the input sequence - prevents infinite recursion * @return {@code out} */ private static StringBuilder replaceKeywords(char[] in, StringBuilder out, Replaceable replaceable, Deque<String> stack) { int pos = 0; int length = in.length; int mark = 0; while (pos < length) { char c1 = in[pos]; if (c1 != '$' || pos + 1 == length) { /* Regular character */ pos++; } else { out.append(in, mark, pos - mark); char c2 = in[pos + 1]; switch (c2) { case '{': /* Placeholder */ pos = replaceKey(in, pos + 2, out, replaceable, stack); break; case '$': /* Escaped $ symbol */ out.append('$'); pos += 2; break; default: /* False alarm - sequence got no special meaning */ out.append(c1).append(c2); pos += 2; break; } mark = pos; } } out.append(in, mark, pos - mark); return out; } public static String replaceKeywords(String in, Replaceable cb) { return replaceKeywords(in.toCharArray(), new StringBuilder(in.length()), cb, new ArrayDeque<>()).toString(); } /** * a useful tool which can interpret jokers (*) and wildcards (?) to filter * from a given Array of Strings the matching ones. * Written by Manfred Maschewski, DESY * * @author Manfred Maschewski, DESY Hamburg * @version 0.1 14 Jan 99 */ public static boolean match( String condition , String subject ) { // handling the joker if ( condition.startsWith("*") ) { // removing the joker condition = condition.substring( 1 ) ; int nextJoker = condition.indexOf('*') ; if ( nextJoker == -1 ) { return endsWith( subject, condition ) ; } else { String firstPart = condition.substring( 0, nextJoker ) ; int position = indexOf( subject, firstPart ) ; if ( position == -1 ) { return false; } else { condition = condition.substring( firstPart.length() ) ; subject = subject.substring( position + firstPart.length() ) ; return match( condition , subject ) ; } } } else { int nextJoker = condition.indexOf('*') ; if ( nextJoker == -1 ) { return equals( subject, condition ) ; } else { String firstPart = condition.substring( 0, nextJoker ) ; if ( ! startsWith( subject, firstPart ) ) { return false ; } else { condition = condition.substring( firstPart.length() ) ; subject = subject.substring( firstPart.length() ) ; return match( condition , subject ) ; } } } } private static boolean startsWith( String subject, String term ) { int riddle ; subject = subject.substring( 0, term.length() ) ; while (( riddle = term.indexOf('?')) != -1 ) { term = removeChar(term,riddle) ; subject = removeChar(subject,riddle) ; } return equals( subject, term ) ; } private static boolean endsWith( String subject, String term ) { int riddle ; // if term is longer than subject it doesn't matches anyway... if ( subject.length() < term.length() ) { return false ; } subject = subject.substring( subject.length() - term.length() ) ; while (( riddle = term.indexOf('?')) != -1 ) { term = removeChar(term,riddle) ; subject = removeChar(subject,riddle) ; } return equals( subject, term ) ; } private static int indexOf( String subject, String term ) { if ( subject.length() < term.length() ) { return -1 ; } // going throught the subject outer: for ( int i = 0 ; i < (subject.length() - term.length() + 1); i++ ){ for ( int j = 0; j < term.length(); j++ ) { if ( ! ((term.charAt(j) == subject.charAt(j+i))) && ! (term.charAt(j) == '?') ) { continue outer ; } } return i ; } return -1 ; } private static String removeChar( String str, int i ) { str = str.substring(0,i) + str.substring(i+1,str.length()) ; return str ; } private static boolean equals( String subject, String term ) { int riddle ; while (( riddle = term.indexOf('?')) != -1 ) { term = removeChar(term,riddle) ; subject = removeChar(subject,riddle) ; } return subject.equals(term) ; } }