Bindings.java :  » Rule-Engine » take » nz » org » take » compiler » reference » Java Open Source

Java Open Source » Rule Engine » take 
take » nz » org » take » compiler » reference » Bindings.java
/**
 * Copyright 2007 Jens Dietrich Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 * Unless required by applicable law or agreed to in writing, software distributed under the 
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language governing permissions 
 * and limitations under the License.
 */

package nz.org.take.compiler.reference;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import nz.org.take.AggregationFunction;
import nz.org.take.BinaryArithmeticFunction;
import nz.org.take.ComplexTerm;
import nz.org.take.JFunction;
import nz.org.take.Term;
import nz.org.take.UnaryArithmeticFunction;
import nz.org.take.compiler.CompilerException;
import nz.org.take.compiler.NameGenerator;

/**
 * Utility class to keep track of term to expression mappings when generating code for rules.
 * @author <a href="http://www-ist.massey.ac.nz/JBDietrich/">Jens Dietrich</a>
 */
public class Bindings  {
  private Collection<Term> terms = null;
  private List<Term> agenda = new ArrayList<Term>();
  private HashMap<Term,String> delegate = new HashMap<Term,String>();
  private NameGenerator naming = null; // needed to look up class name for generated functions
  
  public Bindings(Collection<Term> terms,NameGenerator naming) {
    super();
    this.terms = terms;
    this.naming = naming; 
  }
  
  public void put(Term t,String ref) throws CompilerException {
    delegate.put(t,ref) ;
    this.agenda.add(t);
    // recursion !!
    resolveOwners(t);

  }

  private void resolveOwners(Term t) throws CompilerException {
    ComplexTerm p = null;
    for (Term v:terms) {
      if ((p=isChild(v,t))!=null) {
        boolean result = checkComplexTerm(p);
        if (result) {
          delegate.put(p,createRef(p));
        }
      }
      p = null;
    }
  }
  private String createRef(ComplexTerm t) throws CompilerException {
    StringBuffer buf = new StringBuffer();
    Term[] terms = t.getTerms();
    if (t.getFunction() instanceof JFunction) {
      JFunction f = (JFunction)t.getFunction();
      buf.append(this.getRef(terms[0]));
      buf.append('.');
      buf.append(f.getName());
      buf.append('(');
      for (int i=1;i<terms.length;i++) {
        if (i>1)
          buf.append(',');
        buf.append(this.getRef(terms[i]));
      }      
      buf.append(')');
    }
    else if (t.getFunction() instanceof AggregationFunction) {
      AggregationFunction f = (AggregationFunction)t.getFunction();
      buf.append(this.naming.getAggregationFunctionsRegistryClassName());
      buf.append('.');
      buf.append(naming.getMethodName(f));
      buf.append('(');
      for (int i=0;i<terms.length;i++) {
        if (i>0)
          buf.append(',');
        buf.append(this.getRef(terms[i]));
      }      
      buf.append(')');
    }
    else if (t.getFunction() instanceof BinaryArithmeticFunction) {
      BinaryArithmeticFunction f = (BinaryArithmeticFunction)t.getFunction();
      buf.append(this.getRef(terms[0]));
      buf.append(f.getName());
      buf.append(this.getRef(terms[1]));
    }
    else if (t.getFunction() instanceof UnaryArithmeticFunction) {
      UnaryArithmeticFunction f = (UnaryArithmeticFunction)t.getFunction();
      buf.append(f.getName());
      buf.append(this.getRef(terms[0]));
    }
    else 
      throw new CompilerException("ComplexTerms are only supported if the function is a JFunction or an AggregationFunction");
    return buf.toString();
  }

  /**
   * Check whether all parts of a complex term are already resolved.
   * @param term
   * @return
   */
  private boolean checkComplexTerm(ComplexTerm term) {
    boolean result = true;
    for (Term t:term.getTerms()) {
      result = result && this.delegate.get(t)!=null;
      if (t instanceof ComplexTerm)
        result = result && checkComplexTerm((ComplexTerm)t);
    }
    return result;
  }

  private ComplexTerm  isChild(Term parent,Term child) {
    if (parent instanceof ComplexTerm) {
      Term[] children = ((ComplexTerm)parent).getTerms();
      for (Term t:children) {
        if (t.equals(child))
          return (ComplexTerm)parent;
      }
    }
    return null;
  }
  /**
   * Get the terms currently on the agenda. This will rteset the agenda.
   * @return a list of terms 
   */
  public List<Term> getAndResetAgenda() {
    List<Term> terms = new ArrayList<Term>(this.agenda.size());
    terms.addAll(this.agenda);
    this.agenda.clear();
    return agenda;
  }
  /**
   * Get the reference string for a term.
   * @param t a term
   * @return a string
   */
  public String getRef(Term t) {
    return this.delegate.get(t);
  }
  /**
   * Check whether the term has a binding
   * @param t a term
   * @return a boolean
   */
  public boolean hasBinding(Term t) {
    return this.delegate.containsKey(t);
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.