refactor the DFA

refactor the DFA
This commit is contained in:
coderfengyun 2014-04-14 21:14:03 +08:00
parent 8271bb8478
commit 161d0af167
2 changed files with 101 additions and 97 deletions

View File

@ -7,108 +7,100 @@ import org.bench4q.agent.scenario.dfa.ParamPart.ParamPartType;
import org.bench4q.agent.utils.ParameterParser;
public class DFA {
/**
*
* @param paramOriginValue
* @return If the @param is in the supported format then return the well
* resolved parts; But if not, it'll return only one ParamPart with
* ParamPartType.STRING as type and paramOriginValu as content
*
*/
public static List<ParamPart> resolveMaltipleParamPart(
String paramOriginValue) {
List<ParamPart> result;
StringBuilder buf1;
StringBuilder buf2;
int state;
ParamPart part;
char c;
result = new LinkedList<ParamPart>();
buf1 = new StringBuilder();
buf2 = new StringBuilder();
state = 0;
loop: for (int i = 0, len = paramOriginValue.length(); i < len; i++) {
c = paramOriginValue.charAt(i);
switch (state) {
case 0: /* Literal string */
switch (c) {
case '$':
if (buf1.length() > 0) {
part = new ParamPart();
part.setType(ParamPartType.STRING);
part.setContentForStringType(buf1.toString());
result.add(part);
buf1.setLength(0);
}
state = 2;
continue;
default:
buf1.append(c);
continue;
}
// no more state == 1 (irrelevantly used for "escape sequence")
case 2: /* Context call */
switch (c) {
case '#':
part = new ParamPart();
part.setType(ParamPartType.SESSION_ID);
result.add(part);
state = 0;
continue;
case '{':
state = 3;
continue;
case '$': /* $$ is the escape sequence for $ */
buf1.append(c);
state = 0;
continue;
default: /* Syntax error */
break loop;
}
case 3: /* plugInId */
switch (c) {
case ':':
state = 4;
continue;
case '{':
break loop;
case '}': /* no ':' means system property */
part = new ParamPart();
part.setType(ParamPartType.PROPERTY);
part.setPluginIdForContextCallType(null);
part.setVariableForContextCallAndProperty(ParameterParser
.unescape(buf1.toString()));
result.add(part);
buf1.setLength(0);
state = 0;
continue;
default:
buf1.append(c);
continue;
}
case 4: /* Variable */
switch (c) {
case '}':
part = new ParamPart();
part.setType(ParamPartType.CONTEXT_CALL);
part.setPluginIdForContextCallType(ParameterParser
.unescape(buf1.toString()));
part.setVariableForContextCallAndProperty(ParameterParser
.unescape(buf2.toString()));
result.add(part);
buf1.setLength(0);
buf2.setLength(0);
state = 0;
continue;
case '{': /* Syntax error */
break loop;
default:
buf2.append(c);
continue;
}
List<ParamPart> result = new LinkedList<ParamPart>();
StringBuilder buf1 = new StringBuilder(), bufForVaribleOfContextCall = new StringBuilder();
int state = 0;
try {
for (int i = 0, len = paramOriginValue.length(); i < len; i++) {
state = dfaInside(paramOriginValue, result, buf1,
bufForVaribleOfContextCall, state,
paramOriginValue.charAt(i));
}
if (state == 0 && buf1.length() > 0) {
result.add(new ParamPart(ParamPartType.STRING, buf1.toString(),
null, null));
}
} catch (Exception e) {
result.clear();
result.add(new ParamPart(ParamPartType.STRING, paramOriginValue,
null, null));
}
if (state == 0 && buf1.length() > 0) {
part = new ParamPart();
part.setType(ParamPartType.STRING);
part.setContentForStringType(buf1.toString());
result.add(part);
}
return result;
}
private static int dfaInside(String paramOriginValue,
List<ParamPart> result, StringBuilder buf1, StringBuilder buf2,
int state, char c) {
switch (state) {
case 0: /* Literal string */
switch (c) {
case '$':
if (buf1.length() > 0) {
result.add(new ParamPart(ParamPartType.STRING, buf1
.toString(), null, null));
buf1.setLength(0);
}
return 2;
default:
buf1.append(c);
return state;
}
case 2: /* Context call */
switch (c) {
case '#':
result.add(new ParamPart(ParamPartType.SESSION_ID, null, null,
null));
return 0;
case '{':
return 3;
case '$': /* $$ is the escape sequence for $ */
buf1.append(c);
return 0;
default: /* Syntax error */
throw new RuntimeException("can't digest this tocken");
}
case 3: /* plugInId */
switch (c) {
case ':':
return 4;
case '{':
throw new RuntimeException("can't digest this tocken");
case '}': /* no ':' means system property */
result.add(new ParamPart(ParamPartType.PROPERTY, null, null,
ParameterParser.unescape(buf1.toString())));
buf1.setLength(0);
return 0;
default:
buf1.append(c);
return state;
}
case 4: /* Variable */
switch (c) {
case '}':
result.add(new ParamPart(ParamPartType.CONTEXT_CALL, null,
ParameterParser.unescape(buf1.toString()),
ParameterParser.unescape(buf2.toString())));
buf1.setLength(0);
buf2.setLength(0);
return 0;
case '{': /* Syntax error */
throw new RuntimeException("can't digest this tocken");
default:
buf2.append(c);
return state;
}
}
return state;
}
}

View File

@ -43,6 +43,18 @@ public class ParamPart {
this.variableForContextCallAndProperty = variableForContextCallAndProperty;
}
public ParamPart() {
}
public ParamPart(ParamPartType type, String contentForStringType,
String pluginIdForContextCallType,
String variableForContextCallAndProperty) {
this.setType(type);
this.setContentForStringType(contentForStringType);
this.setPluginIdForContextCallType(pluginIdForContextCallType);
this.setVariableForContextCallAndProperty(variableForContextCallAndProperty);
}
@Override
public String toString() {
switch (type) {