package org.krakenapps.logdb.query.parser; import static org.krakenapps.bnf.Syntax.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; import org.krakenapps.bnf.Binding; import org.krakenapps.bnf.Syntax; import org.krakenapps.log.api.LogParserFactoryRegistry; import org.krakenapps.logdb.DataSource; import org.krakenapps.logdb.DataSourceRegistry; import org.krakenapps.logdb.LogQueryParser; import org.krakenapps.logdb.query.command.Datasource; import org.krakenapps.logdb.query.command.OptionChecker; import org.krakenapps.logstorage.LogStorage; import org.krakenapps.logstorage.LogTableRegistry; public class DatasourceParser implements LogQueryParser { private DataSourceRegistry dataSourceRegistry; private LogStorage logStorage; private LogTableRegistry tableRegistry; private LogParserFactoryRegistry parserFactoryRegistry; public DatasourceParser(DataSourceRegistry dataSourceRegistry, LogStorage logStorage, LogTableRegistry tableRegistry, LogParserFactoryRegistry parserFactoryRegistry) { this.dataSourceRegistry = dataSourceRegistry; this.logStorage = logStorage; this.tableRegistry = tableRegistry; this.parserFactoryRegistry = parserFactoryRegistry; } @Override public void addSyntax(Syntax syntax) { syntax.add("datasource", this, k("datasource "), ref("option"), ref("option_checker")); syntax.addRoot("datasource"); } @SuppressWarnings("unchecked") @Override public Object parse(Binding b) { Map<String, String> options = (Map<String, String>) b.getChildren()[1].getValue(); List<DataSource> sources = new ArrayList<DataSource>(); OptionChecker checker = (OptionChecker) b.getChildren()[2].getValue(); for (DataSource source : dataSourceRegistry.getAll()) { if (checker.eval(source.getMetadata())) sources.add(source); } Datasource datasource = null; if (options.containsKey("cache")) datasource = new Datasource(sources); else { try { datasource = new Datasource(sources, Integer.parseInt(options.get("cache"))); } catch (NumberFormatException e) { datasource = new Datasource(sources); } } datasource.setLogStorage(logStorage); datasource.setTableRegistry(tableRegistry); datasource.setParserFactoryRegistry(parserFactoryRegistry); if (options.containsKey("duration")) { String duration = options.get("duration"); int i; for (i = 0; i < duration.length(); i++) { char c = duration.charAt(i); if (!('0' <= c && c <= '9')) break; } int value = Integer.parseInt(duration.substring(0, i)); datasource.setFrom(getDuration(value, duration.substring(i))); } if (options.containsKey("from")) datasource.setFrom(getDate(options.get("from"))); if (options.containsKey("to")) datasource.setTo(getDate(options.get("to"))); if (options.containsKey("offset")) datasource.setOffset(Integer.parseInt(options.get("offset"))); if (options.containsKey("limit")) datasource.setLimit(Integer.parseInt(options.get("limit"))); return datasource; } private Date getDuration(int value, String field) { Calendar c = Calendar.getInstance(); c.setTimeInMillis(System.currentTimeMillis()); if (field.equalsIgnoreCase("s")) c.add(Calendar.SECOND, -value); else if (field.equalsIgnoreCase("m")) c.add(Calendar.MINUTE, -value); else if (field.equalsIgnoreCase("h")) c.add(Calendar.HOUR_OF_DAY, -value); else if (field.equalsIgnoreCase("d")) c.add(Calendar.DAY_OF_MONTH, -value); else if (field.equalsIgnoreCase("w")) c.add(Calendar.WEEK_OF_YEAR, -value); else if (field.equalsIgnoreCase("mon")) c.add(Calendar.MONTH, -value); return c.getTime(); } private Date getDate(String value) { String type1 = "yyyy"; String type2 = "yyyyMM"; String type3 = "yyyyMMdd"; String type4 = "yyyyMMddHH"; String type5 = "yyyyMMddHHmm"; String type6 = "yyyyMMddHHmmss"; SimpleDateFormat sdf = null; if (value.length() == 4) sdf = new SimpleDateFormat(type1); else if (value.length() == 6) sdf = new SimpleDateFormat(type2); else if (value.length() == 8) sdf = new SimpleDateFormat(type3); else if (value.length() == 10) sdf = new SimpleDateFormat(type4); else if (value.length() == 12) sdf = new SimpleDateFormat(type5); else if (value.length() == 14) sdf = new SimpleDateFormat(type6); if (sdf == null) throw new IllegalArgumentException(); try { return sdf.parse(value); } catch (ParseException e) { return null; } } }