📄 template.java
字号:
*/
private String getActualVarString(Map hash, String initVar)
throws IOException {
int ind = 0;
char c, c1;
int size = initVar.length();
StringBuffer sb = new StringBuffer(64);
while (ind < size) {
c = initVar.charAt(ind);
++ind;
if (c == '$') {
c1 = initVar.charAt(ind);
ind++;
// not a variable
if (c1 != '{') {
sb.append(c);
sb.append(c1);
continue;
}
// variable and/or keyword
String var = getBlock(initVar, ind);
ind += var.length() + 1;
Object obj = getVarObject(hash, var);
if (obj != null)
sb.append(obj);
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Process IF block. Returns the index of the next char.
*/
private int processIfBlock(OutputStream out, Map hash, int start)
throws IOException {
// condition block starts - evaluate condition
int index = ignoreWhitespace(start);
if (mbyContent[index] != '{')
throw new IOException("IF condition block not found.");
Block block = getBlock(index + 1);
boolean bTrue = isTrueCondition(hash, block);
// get IF action block
index = block.nextIndex();
index = ignoreWhitespace(index);
if (mbyContent[index] != '{')
throw new IOException("Invalid char after IF");
block = getBlock(index + 1);
if (bTrue)
processNormalBlock(out, hash, block);
// ignore ELSE block if available and condition is TRUE.
index = block.nextIndex();
char c = (char)mbyContent[index];
if (bTrue) {
if (c == '{') {
block = getBlock(index + 1);
return block.nextIndex();
}
}
// else block starts
if (!bTrue) {
// check ELSE block
if (c == '{') {
block = getBlock(index + 1);
processNormalBlock(out, hash, block);
return block.nextIndex();
}
}
return index;
}
/**
* Evaluate condition block in IF statement.
*/
private boolean isTrueCondition(Map hash, Block block)
throws IOException {
String sb = block.toString();
StringTokenizer st = new StringTokenizer(sb, mstWhitespaces);
// get left side
if (!st.hasMoreTokens())
throw new IOException("First token not found in IF");
Object leftObj = getCondVarObject(hash, st.nextToken());
// get condition operator
if (!st.hasMoreTokens())
throw new IOException("IF condition operator not found");
String condition = st.nextToken();
// get rightside
if (!st.hasMoreTokens())
throw new IOException("Last token not found in IF");
Object rightObj = getCondVarObject(hash, st.nextToken());
// now evaluate
if (leftObj == null && rightObj == null) return condition.equals(EQ);
if (leftObj == null || rightObj == null) return condition.equals(NE);
if (condition.equals(EQ)) return rightObj.toString().equals(leftObj.toString());
if (condition.equals(NE)) return !rightObj.toString().equals(leftObj.toString());
if (condition.equals(IN)) return ifObjExists(leftObj, rightObj);
throw new IOException("Invalid IF condition operator: " + condition);
}
/**
* Check object existance. If any vector element is null,
* that element is ignored.
*/
private boolean ifObjExists(Object left, Object right) {
// vector
if (right instanceof java.util.List) {
int sz = ((List)right).size();
for (int i=0; i<sz; i++) {
Object obj = ((List)right).get(i);
if (obj == null)
continue;
if (obj.toString().equals(left.toString()))
return true;
}
return false;
}
// not a vector
return right.toString().equals(left.toString());
}
/**
* Process iterator block. Here <code>index</code> is the
* starting index of the iterator initialization block.
*/
private int processItrBlock(OutputStream out, Map hash, int index)
throws IOException {
int ind = ignoreWhitespace(index);
if (mbyContent[ind] != '{')
throw new IOException("ITR initialization block not found.");
// get ITR init block
Block sb = getBlock(ind + 1);
String str = sb.toString();
StringTokenizer st = new StringTokenizer(str, mstWhitespaces);
// get ITR main block
ind = ignoreWhitespace(sb.nextIndex());
if (mbyContent[ind] != '{')
throw new IOException("ITR main block not found.");
sb = getBlock(ind + 1);
int retValue = sb.nextIndex();
// get init variable name
if (!st.hasMoreTokens())
throw new IOException("Variable name not found in ITR block");
String var = st.nextToken();
// get start point
int start = getIntegerValue(hash, st);
if (start == -1)
return retValue;
// strip "THRU"
if (!st.hasMoreTokens())
throw new IOException("Invalid ITR block - string THRU not found");
if (!st.nextToken().equals(THRU))
throw new IOException("Expecting THRU in ITR block");
// get length
int len = getIntegerValue(hash, st);
if (len == -1)
return retValue;
// process ITR main loop
for (int i=0; i<len; i++) {
hash.put(var, new Integer(i+start));
processNormalBlock(out, hash, sb);
}
return retValue;
}
/**
* Get the integer value from <code>StringTokenizer</code>.
* This function is used to get the start index and iteration
* count in ITR block. It returns -1 in case of error
* (<code>NumberFormatException</code>).
*/
private int getIntegerValue(Map hash, StringTokenizer st)
throws IOException {
// no tokens available
if (!st.hasMoreTokens())
throw new IOException("Start index not found in ITR block");
String initVar = st.nextToken();
// Get string representation of the number
String initVal = getActualVarString(hash, initVar);
try {
return Integer.parseInt(initVal);
} catch (NumberFormatException ex) {
return -1;
}
}
/**
* Process FOR block. Here <code>index</code> is the
* start index of the FOR initialization block.
*/
private int processForBlock(OutputStream out, Map hash, int index)
throws IOException {
// read initialization block
int ind = ignoreWhitespace(index);
char c = (char)mbyContent[ind];
if (c != '{')
throw new IOException("FOR initialization block not found.");
Block sb = getBlock(ind + 1);
StringBuffer varNameSb = new StringBuffer();
List vec = getForList(hash, varNameSb, sb);
String varName = varNameSb.toString();
// read for main loop
ind = ignoreWhitespace(sb.nextIndex());
c = (char)mbyContent[ind];
if (c != '{')
throw new IOException("FOR main loop not found.");
sb = getBlock(ind + 1);
int sz = vec.size();
for (int i=0; i<sz; i++) {
Object ob = vec.get(i);
hash.put(varName, ob);
processNormalBlock(out, hash, sb);
}
return sb.nextIndex();
}
/**
* Get for vector and init variable name. It passes the
* name of the FOR temporary variable name in
* <code>StringBuffer sb</code>
*/
private List getForList(Map hash,
StringBuffer sb,
Block block) throws IOException {
String initBlock = block.toString();
StringTokenizer st = new StringTokenizer(initBlock, mstWhitespaces);
// get init variable
if (!st.hasMoreTokens())
throw new IOException("Invalid FOR block");
String initVar = st.nextToken();
sb.append(initVar);
// ignore string "IN"
if (!st.hasMoreTokens())
throw new IOException("Invalid FOR block - string IN not found");
initVar = st.nextToken();
if (!initVar.equals(IN))
throw new IOException("Expecting IN, found " + initVar);
// get vector variable
if (!st.hasMoreTokens())
throw new IOException("Invalid FOR block - vector not found");
initVar = st.nextToken();
// get object form Map if variable
Object obj = getCondVarObject(hash, initVar);
if (obj instanceof java.util.List)
return(List)obj;
List vec = new Vector(1);
if (obj != null)
vec.add(obj);
return vec;
}
/**
* Get block from index <code>start</code>.
* It starts just after the '{' character.
* It reads till it reaches the corresponding '}'.
*/
private Block getBlock(int start) {
char c;
int braceCount = 0;
int index = start;
while (braceCount != 1) {
c = (char)mbyContent[index++];
if (c == '{')
--braceCount;
else if (c == '}')
++braceCount;
}
return new Block(mbyContent, start, index - start - 1);
}
/**
* Get block - this function is used to form the
* variable name dynamically.
*/
private String getBlock(String str, int start) {
char c;
int braceCount = 0;
int index = start;
while (braceCount != 1) {
c = str.charAt(index++);
if (c == '{')
--braceCount;
else if (c == '}')
++braceCount;
}
return str.substring(start, index-1);
}
/**
* Ignore whitespace. Returns the first
* non-whitespace char index.
*/
private int ignoreWhitespace(int start) {
char c;
while (true) {
c = (char)mbyContent[start];
if (mstWhitespaces.indexOf(c) != -1) {
++start;
continue;
} else
break;
}
return start;
}
/**
* Load file - it reads the file and process the block as
* normal block.
*/
public void loadFile(OutputStream out, Map hash)
throws IOException {
try {
readFile();
Block block = new Block(mbyContent);
processNormalBlock(out, hash, block);
} catch (ArrayIndexOutOfBoundsException ex) {
throw new IOException("Unexpected end of file - bracket mismatch.");
} catch (Throwable th) {
throw new IOException(th.getLocalizedMessage());
}
}
/**
* Get template file name
*/
public String toString() {
return mFile.getAbsolutePath();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -