in src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java [1116:1183]
protected List<Block> readTemplate(final String prefix, final Reader source) {
final ArrayList<Block> blocks = new ArrayList<>();
final BufferedReader reader;
if (source instanceof BufferedReader) {
reader = (BufferedReader) source;
} else {
reader = new BufferedReader(source);
}
final StringBuilder strb = new StringBuilder();
BlockType type = null;
int prefixLen;
final Iterator<CharSequence> lines = readLines(reader);
int lineno = 1;
int start = 0;
while (lines.hasNext()) {
final CharSequence line = lines.next();
if (line == null) {
break;
}
if (type == null) {
// determine starting type if not known yet
prefixLen = startsWith(line, prefix);
if (prefixLen >= 0) {
type = BlockType.DIRECTIVE;
strb.append(line.subSequence(prefixLen, line.length()));
} else {
type = BlockType.VERBATIM;
strb.append(line.subSequence(0, line.length()));
}
start = lineno;
} else if (type == BlockType.DIRECTIVE) {
// switch to verbatim if necessary
prefixLen = startsWith(line, prefix);
if (prefixLen < 0) {
final Block directive = new Block(BlockType.DIRECTIVE, start, strb.toString());
strb.delete(0, Integer.MAX_VALUE);
blocks.add(directive);
type = BlockType.VERBATIM;
strb.append(line.subSequence(0, line.length()));
start = lineno;
} else {
// still a directive
strb.append(line.subSequence(prefixLen, line.length()));
}
} else if (type == BlockType.VERBATIM) {
// switch to directive if necessary
prefixLen = startsWith(line, prefix);
if (prefixLen >= 0) {
final Block verbatim = new Block(BlockType.VERBATIM, start, strb.toString());
strb.delete(0, Integer.MAX_VALUE);
blocks.add(verbatim);
type = BlockType.DIRECTIVE;
strb.append(line.subSequence(prefixLen, line.length()));
start = lineno;
} else {
strb.append(line.subSequence(0, line.length()));
}
}
lineno += 1;
}
// input may be null
if (type != null && strb.length() > 0) {
final Block block = new Block(type, start, strb.toString());
blocks.add(block);
}
blocks.trimToSize();
return blocks;
}