Selaa lähdekoodia

Refactor StringFormatter to be more modifiable.

Sam Jaffe 8 vuotta sitten
vanhempi
commit
05f0a5a761
1 muutettua tiedostoa jossa 48 lisäystä ja 25 poistoa
  1. 48 25
      src/org/leumasjaffe/format/StringFormatter.java

+ 48 - 25
src/org/leumasjaffe/format/StringFormatter.java

@@ -24,38 +24,61 @@ public class StringFormatter {
 		}
 	}
 	
-	String fmt;
-	
-	public StringFormatter(String logFmtString) {
-		this.fmt = logFmtString;
-	}
-	
-	public String format(Object... args) {
+	private final class FmtStateMachine {
 		final StringBuilder str = new StringBuilder(fmt.length());
 		
+		Object[] args;
 		int currentIdx = 0;
-		final NameMap named = new NameMap(args);
+		final NameMap named;
+
+		FmtStateMachine(Object... args) {
+			this.args = args;
+			this.named = new NameMap(args);
+		}
 		
-		int lpos = 0;
-		for (int pos = fmt.indexOf('{'); pos != -1; lpos = pos+1, pos = fmt.indexOf('{', lpos)) {
-			str.append(fmt.substring(lpos, pos));
-			int epos = fmt.indexOf('}', pos);
+		FmtStateMachine formatMain() {
+			int lpos = 0;
+			for (int pos = fmt.indexOf('{'); pos != -1; lpos = pos+1, pos = fmt.indexOf('{', lpos)) {
+				str.append(fmt.substring(lpos, pos));
+				int epos = fmt.indexOf('}', pos);
 
-			if (fmt.charAt(pos+1) == '{') { 
-				str.append(fmt.substring(++pos, ++epos));
-			} else if (epos == pos+1) {
-				str.append(args[currentIdx++]);
-			} else {
-				final String token = fmt.substring(pos+1, epos);
-				if (Character.isDigit(token.charAt(0))) {
-					str.append(args[Integer.parseInt(token)]);
-				} else { // In theory, I could add a format-mode here too
-					str.append(named.get(token));
+				if (fmt.charAt(pos+1) == '{') { 
+					str.append(fmt.substring(++pos, ++epos));
+				} else if (epos == pos+1) {
+					str.append(args[currentIdx++]);
+				} else {
+					formatToken(pos, epos);
 				}
+				pos = epos;
 			}
-			pos = epos;
+			str.append(fmt.substring(lpos));
+			return this;
 		}
-		str.append(fmt.substring(lpos));
-		return str.toString();
+
+		private void formatToken(int pos, int epos) {
+			final String token = fmt.substring(pos+1, epos);
+			// If token contains a '.', use reflection?
+			// If token contains a '?', make it an if-expression
+			// If token starts with '%', make it a c-format expression
+			if (Character.isDigit(token.charAt(0))) {
+				str.append(args[Integer.parseInt(token)]);
+			} else {
+				str.append(named.get(token));
+			}
+		}
+		
+		public String toString() {
+			return str.toString();
+		}
+	}
+	
+	String fmt;
+	
+	public StringFormatter(String logFmtString) {
+		this.fmt = logFmtString;
+	}
+	
+	public String format(Object... args) {
+		return this.new FmtStateMachine(args).formatMain().toString();
 	}
 }