1 16 package org.apache.cocoon.components.treeprocessor.variables; 17 18 import org.apache.cocoon.sitemap.PatternException; 19 20 27 public final class VariableExpressionTokenizer { 28 29 32 public interface TokenReciever { 33 int OPEN = -2; 34 int CLOSE = -3; 35 int COLON = -4; 36 int TEXT = -5; 37 int MODULE = -6; 38 int VARIABLE = -8; 39 40 43 void addToken(int type, String value) throws PatternException; 44 } 45 46 52 public static void tokenize(String expression, TokenReciever reciever) throws PatternException { 53 54 int lastTokenType = 0; 55 56 int openCount = 0; 57 int closeCount = 0; 58 59 int pos = 0; 60 int i; 61 boolean escape = false; 62 63 for (i = 0; i < expression.length(); i++) { 64 final char c = expression.charAt(i); 65 66 if (escape) { 67 escape = false; 68 } else if (c == '\\' && i < expression.length()) { 69 char nextChar = expression.charAt(i + 1); 70 if (nextChar == '{' || nextChar == '}') { 71 expression = expression.substring(0, i) + expression.substring(i + 1); 72 escape = true; 73 i--; 74 } 75 } else if (c == '{') { 76 if (i > pos) { 77 reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i)); 78 } 79 80 openCount++; 81 reciever.addToken(lastTokenType = TokenReciever.OPEN, null); 82 83 int colonPos = indexOf(expression, ':', i); 84 int closePos = indexOf(expression, '}', i); 85 int openPos = indexOf(expression, '{', i); 86 87 if (openPos < colonPos && openPos < closePos) { 88 throw new PatternException("Invalid '{' at position " + i + 89 " in expression \"" + expression + "\""); 90 } 91 92 if (colonPos < closePos) { 93 String module = expression.substring(i + 1, colonPos); 95 reciever.addToken(lastTokenType = TokenReciever.MODULE, module); 96 i = colonPos - 1; 97 } else { 98 reciever.addToken(lastTokenType = TokenReciever.VARIABLE, expression.substring(i + 1, closePos)); 100 i = closePos - 1; 101 } 102 103 pos = i + 1; 104 } else if (c == '}') { 105 if (i > 0 && expression.charAt(i - 1) == '\\') { 106 continue; 107 } 108 if (i > pos) { 109 reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i)); 110 } 111 112 closeCount++; 113 reciever.addToken(lastTokenType = TokenReciever.CLOSE, null); 114 115 pos = i + 1; 116 } else if (c == ':') { 117 if (lastTokenType != TokenReciever.MODULE || i != pos) { 118 continue; 120 } 121 122 reciever.addToken(lastTokenType = TokenReciever.COLON, null); 123 pos = i + 1; 124 } 125 } 126 127 if (i > pos) { 128 reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i)); 129 } 130 131 if (openCount != closeCount) { 132 throw new PatternException("Mismatching braces in expression \"" + expression + "\""); 133 } 134 } 135 136 private static int indexOf(String expression, char chr, int pos) { 137 int location; 138 return (location = expression.indexOf(chr, pos + 1)) != -1? location : expression.length(); 139 } 140 } 141 | Popular Tags |