/**
* MVEL 2.0
* Copyright (C) 2007 The Codehaus
* Mike Brock, Dhanji Prasanna, John Graham, Mark Proctor
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mvel2;
import org.mvel2.compiler.AbstractParser;
import org.mvel2.util.StringAppender;
import java.util.Map;
import static org.mvel2.util.ParseTools.*;
/**
* A simple, fast, macro processor. This processor works by simply replacing a matched identifier with a set of code.
*/
public class MacroProcessor extends AbstractParser implements PreProcessor {
private Map<String, Macro> macros;
public MacroProcessor() {
}
public MacroProcessor(Map<String, Macro> macros) {
this.macros = macros;
}
public char[] parse(char[] input) {
setExpression(input);
StringAppender appender = new StringAppender();
int start;
boolean macroArmed = true;
String token;
for (; cursor < length; cursor++) {
start = cursor;
while (cursor < length && isIdentifierPart(expr[cursor])) cursor++;
if (cursor > start) {
if (macros.containsKey(token = new String(expr, start, cursor - start)) && macroArmed) {
appender.append(macros.get(token).doMacro());
}
else {
appender.append(token);
}
}
if (cursor < length) {
switch (expr[cursor]) {
case '\\':
cursor++;
break;
case '/':
start = cursor;
if (cursor + 1 != length) {
switch (expr[cursor + 1]) {
case '/':
while (cursor != length && expr[cursor] != '\n') cursor++;
break;
case '*':
int len = length - 1;
while (cursor != len && !(expr[cursor] == '*' && expr[cursor + 1] == '/')) cursor++;
cursor += 2;
break;
}
}
if (cursor < length) cursor++;
appender.append(new String(expr, start, cursor - start));
if (cursor < length) cursor--;
break;
case '"':
case '\'':
appender.append(new String(expr, (start = cursor),
(cursor = captureStringLiteral(expr[cursor], expr, cursor, length)) - start));
if (cursor >= length) break;
else if (isIdentifierPart(expr[cursor])) cursor--;
default:
switch (expr[cursor]) {
case '.':
macroArmed = false;
break;
case ';':
case '{':
case '(':
macroArmed = true;
break;
}
appender.append(expr[cursor]);
}
}
}
return appender.toChars();
}
public String parse(String input) {
return new String(parse(input.toCharArray()));
}
public Map<String, Macro> getMacros() {
return macros;
}
public void setMacros(Map<String, Macro> macros) {
this.macros = macros;
}
public void captureToWhitespace() {
while (cursor < length && !isWhitespace(expr[cursor])) cursor++;
}
}