package org.araqne.logdb.query.command;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.araqne.log.api.V1LogParser;
public class ParseWithAnchor extends V1LogParser {
private List<String> anchors;
private List<String> aliases;
private Pattern ptrn;
private String field;
private Matcher mchr;
public ParseWithAnchor(String field, List<String> anchors, List<String> aliases) {
this.field = field == null ? "line" : field;
this.anchors = anchors;
this.aliases = aliases;
this.ptrn = buildPattern(anchors);
this.mchr = this.ptrn.matcher("");
}
private static Pattern buildPattern(List<String> anchors) {
StringBuffer pStr = new StringBuffer();
pStr.append("(?:");
int itemCnt = 0;
for (int i = 0; i < anchors.size(); ++i) {
String s = anchors.get(i);
String[] split = s.split("\\*");
if (split.length > 2)
continue;
String prefix = split[0];
String postfix = split.length == 2 ? split[1] : "";
postfix = postfix.length() == 0 ? "$" : Pattern.quote(postfix.substring(0, 1));
// System.out.println(s);
if (split[0].isEmpty())
continue;
if (itemCnt != 0)
pStr.append("|");
pStr.append(Pattern.quote(prefix));
pStr.append("(.*?)");
if (postfix != null)
pStr.append(postfix);
itemCnt += 1;
}
pStr.append(")");
return Pattern.compile(pStr.toString());
}
private String[] findField(Matcher m) {
for (int i = 1; i <= m.groupCount(); ++i) {
if (m.start(i) != -1)
return new String[] { aliases.get(i - 1), m.group(i) };
}
return null;
}
public String toQueryCommandString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < anchors.size(); ++i) {
String anchor = anchors.get(i);
String alias = aliases.get(i);
if (i != 0)
sb.append(", ");
sb.append("\"");
sb.append(anchor);
sb.append("\"");
sb.append(" as ");
sb.append(alias);
}
return "parse " + sb.toString();
}
public String toString() {
return toQueryCommandString();
}
@Override
public Map<String, Object> parse(Map<String, Object> params) {
String line = (String) params.get(field);
if (line == null)
return params;
HashMap<String, Object> m = new HashMap<String, Object>(anchors.size());
mchr.reset(line);
int start = 0;
while (mchr.find(start)) {
String[] field = findField(mchr);
m.put(field[0], field[1]);
start = mchr.end() - 1;
}
return m;
}
}