/* * Copyright (C) 2008 Steve Ratcliffe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * * Author: Steve Ratcliffe * Create date: 07-Nov-2008 */ package uk.me.parabola.mkgmap.osmstyle; import uk.me.parabola.log.Logger; import uk.me.parabola.mkgmap.osmstyle.eval.Op; import uk.me.parabola.mkgmap.reader.osm.Element; import uk.me.parabola.mkgmap.reader.osm.GType; import uk.me.parabola.mkgmap.reader.osm.Rule; import uk.me.parabola.mkgmap.reader.osm.TypeResult; /** * A rule that contains a condition. If the condition is matched by the * element then the finalize rule is executed and the held gtype is returned. * * @author Steve Ratcliffe */ public class ExpressionRule implements Rule { private static final Logger statsLog = Logger.getLogger(ExpressionRule.class.getPackage().getName()+".stats"); private Op expression; private final GType gtype; private Rule finalizeRule; private long numEval; // count how often the expression was evaluated private long numTrue; // count how often the evaluation returned true /** Finalize rules must not have an element type definition so the add method must never be called. */ private final static TypeResult finalizeTypeResult = new TypeResult() { public void add(Element el, GType type) { throw new UnsupportedOperationException("Finalize rules must not contain an action block."); } }; public ExpressionRule(Op expression, GType gtype) { this.expression = expression; this.gtype = gtype; } public void resolveType(Element el, TypeResult result) { numEval++; if (expression.eval(el)) { numTrue++; // expression matches if (finalizeRule != null) { if (gtype.isContinueSearch()) { el = el.copy(); } // run the finalize rules if (gtype.getDefaultName() != null) el.addTag("mkgmap:default_name", gtype.getDefaultName()); finalizeRule.resolveType(el, finalizeTypeResult); } result.add(el, gtype); } } public int resolveType(int cacheId, Element el, TypeResult result) { numEval++; if (expression.eval(cacheId, el)){ numTrue++; if (finalizeRule != null) { if (gtype.isContinueSearch()) { el = el.copy(); } // run the finalize rules if (gtype.getDefaultName() != null) el.addTag("mkgmap:default_name", gtype.getDefaultName()); cacheId = finalizeRule.resolveType(cacheId, el, finalizeTypeResult); } result.add(el, gtype); } return cacheId; } public String toString() { return expression.toString() + ' ' + gtype; } public void setFinalizeRule(Rule finalizeRule) { this.finalizeRule = finalizeRule; } @Override public Rule getFinalizeRule() { return finalizeRule; } public Op getOp(){ return expression; } public void setOp(Op expression){ this.expression = expression; } @Override public void printStats(String header) { if (statsLog.isInfoEnabled()) statsLog.info(header,"stats (rule/evals/true)", this.toString() + "/" + numEval + "/" + numTrue); } @Override public boolean containsExpression(String exp) { return expression.toString().contains(exp); } }