001: /*
002: * $Id: Interpreter.java 911 2007-02-20 13:53:49Z hengels $
003: * (c) Copyright 2004 con:cern development team.
004: *
005: * This file is part of con:cern (http://concern.sf.net).
006: *
007: * con:cern is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU Lesser General Public License
009: * as published by the Free Software Foundation; either version 2.1
010: * of the License, or (at your option) any later version.
011: *
012: * Please see COPYING for the complete licence.
013: */
014: package org.concern.controller;
015:
016: import org.concern.model.parser.ast.AbstractNode;
017: import org.concern.model.parser.ast.*;
018: import org.concern.model.parser.ParseException;
019: import org.concern.model.parser.ExpressionParser;
020: import org.concern.ControllerException;
021:
022: import java.io.StringReader;
023: import java.util.*;
024:
025: /**
026: * @author hengels[at]mercatis[dot]de
027: * @version $Revision: 911 $
028: */
029: class Interpreter extends NodeVisitor {
030: Map evaluations;
031:
032: public Interpreter(Map evaluations) {
033: this .evaluations = evaluations;
034: }
035:
036: public boolean eval(String condition) {
037: if (condition == null || condition.length() == 0)
038: return true;
039:
040: try {
041: ExpressionParser p = new ExpressionParser(new StringReader(
042: condition));
043: Boolean result = ((Boolean) visit(p.or()));
044: return result != null ? result.booleanValue() : false;
045: } catch (ParseException e) {
046: throw new ControllerException(e);
047: }
048: }
049:
050: public Object visit(AndOperator a) {
051: boolean undefined = false;
052: for (Iterator iterator = a.getChildren().iterator(); iterator
053: .hasNext();) {
054: AbstractNode node = (AbstractNode) iterator.next();
055:
056: Boolean result = ((Boolean) node.accept(this ));
057: if (result == null)
058: undefined = true;
059: else if (!result.booleanValue())
060: return Boolean.FALSE;
061: }
062: return undefined ? null : Boolean.TRUE;
063: }
064:
065: // true, if at least one term is true
066: // undefined, if at leats one term is null
067: // false only, if all terms are false
068: public Object visit(OrOperator o) {
069: boolean undefined = false;
070: for (Iterator iterator = o.getChildren().iterator(); iterator
071: .hasNext();) {
072: AbstractNode node = (AbstractNode) iterator.next();
073:
074: Boolean result = (Boolean) node.accept(this );
075: if (result == null)
076: undefined = true;
077: else if (result.booleanValue())
078: return Boolean.TRUE;
079: }
080: return undefined ? null : Boolean.FALSE;
081: }
082:
083: // true -> false
084: // false -> true
085: // null -> null
086: public Object visit(NotOperator n) {
087: Boolean result = (Boolean) ((AbstractNode) n.getChildren()
088: .iterator().next()).accept(this );
089: if (result == null)
090: return null;
091: return Boolean.valueOf(!result.booleanValue());
092: }
093:
094: public Object visit(Name n) {
095: String name = n.getContent();
096: if (!evaluations.containsKey(name))
097: throw new RuntimeException("unknown condition " + name);
098: return (Boolean) evaluations.get(name);
099: }
100: }
|