package com.vistatec.ocelot.rules; import java.awt.Color; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RulesParser { private static Logger LOG = LoggerFactory.getLogger(RulesParser.class); // ruleLabel.dataCategory = regex private Pattern ruleFormat = Pattern.compile("([^.]+)\\.(\\w+)\\s*=(.*)"); // ruleLabel.flag.flagType = display private Pattern flagFormat = Pattern.compile("([^.]+)\\.flag\\.(\\w+)\\s*=(.*)"); // [id-match|exact-match|fuzzy-match|mt-suggestion] = hex private Pattern stateQualifierFormat = Pattern.compile("(id-match|exact-match|fuzzy-match|mt-suggestion)\\s*=\\s*(.*)"); // NO LONGER SUPPORTED: // ruleLabel.quickAdd.LQIType = value private Pattern quickAddFormat = Pattern.compile("([^.]+)\\.quickAdd\\.(\\w+)\\s*=(.*)"); public RuleConfiguration loadConfig(Reader reader) { try { if (reader != null) { return parse(new BufferedReader(reader)); } } catch (UnsupportedEncodingException ex) { LOG.error("Encoding not supported",ex); } catch (FileNotFoundException ex) { LOG.error("Rules file not found", ex); } catch (IOException ex) { LOG.error("IO error", ex); } catch (InstantiationException ex) { LOG.error("Failed to instantiate Matcher class", ex); } catch (IllegalAccessException ex) { LOG.error("Matcher class not accessible", ex); } return new RuleConfiguration(); } public RuleConfiguration parse(BufferedReader configFile) throws IOException, InstantiationException, IllegalAccessException { RuleConfiguration config = new RuleConfiguration(); String line; boolean hasDeprecatedQuickAddPatterns = false; while ((line = configFile.readLine()) != null) { Matcher rulePattern = ruleFormat.matcher(line); Matcher flagPattern = flagFormat.matcher(line); Matcher deprecatedQuickAddPattern = quickAddFormat.matcher(line); Matcher stateQualifierPattern = stateQualifierFormat.matcher(line); Matcher whitespace = Pattern.compile("\\s*").matcher(line); if (stateQualifierPattern.matches()) { String state = stateQualifierPattern.group(1); StateQualifier stateQualifier = StateQualifier.get(state); String hexColor = stateQualifierPattern.group(2).trim(); if (stateQualifier != null) { config.setStateQualifierColor(stateQualifier, new Color(Integer.decode(hexColor))); } else { LOG.debug("Ignoring state-qualifier: {}", state); } } else if (rulePattern.matches()) { String ruleLabel = rulePattern.group(1); String dataCategory = rulePattern.group(2); String regex = rulePattern.group(3).trim(); DataCategoryField dataCategoryField = DataCategoryField.byName(dataCategory); if (dataCategoryField == null) { LOG.error("Unrecognized data category: {}, line: {}", dataCategory, line); } else { DataCategoryField.Matcher dcfMatcher = dataCategoryField.getMatcherClass().newInstance(); dcfMatcher.setPattern(regex); RuleMatcher ruleMatcher = new RuleMatcher(dataCategoryField, dcfMatcher); config.addRuleConstaint(ruleLabel, ruleMatcher); } } else if (flagPattern.matches()) { String ruleLabel = flagPattern.group(1); String flagType = flagPattern.group(2); String value = flagPattern.group(3).trim(); if (flagType.equals("fill")) { config.addFill(ruleLabel, new Color(Integer.decode(value))); } else if (flagType.equals("border")) { config.addBorder(ruleLabel, new Color(Integer.decode(value))); } else if (flagType.equals("text")) { config.addText(ruleLabel, value); } else { LOG.error("Unrecognized flag: {}", line); } } else if (deprecatedQuickAddPattern.matches()) { hasDeprecatedQuickAddPatterns = true; } else if (!whitespace.matches()) { LOG.error("Unrecognized rule: "+line); } } // Validate rules and remove any that were malformed (no matchers): for (Rule r : new ArrayList<Rule>(config.getRules())) { if (r.matchers.size() == 0) { LOG.warn("Ignoring rule '{}' that has no matches.", r.getLabel()); config.removeRule(r); } } if (hasDeprecatedQuickAddPatterns) { LOG.warn("Skipping deprecated quickadd rules."); } return config; } }