src/core/net/sf/basedb/util/jep/convert/ASTFunNodeConverter.java

Code
Comments
Other
Rev Date Author Line
3604 26 Jul 07 nicklas 1 /**
3604 26 Jul 07 nicklas 2   $Id$
3604 26 Jul 07 nicklas 3
3675 16 Aug 07 jari 4   Copyright (C) 2007 Nicklas Nordborg
3604 26 Jul 07 nicklas 5
3604 26 Jul 07 nicklas 6   This file is part of BASE - BioArray Software Environment.
3604 26 Jul 07 nicklas 7   Available at http://base.thep.lu.se/
3604 26 Jul 07 nicklas 8
3604 26 Jul 07 nicklas 9   BASE is free software; you can redistribute it and/or
3604 26 Jul 07 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
3604 26 Jul 07 nicklas 12   of the License, or (at your option) any later version.
3604 26 Jul 07 nicklas 13
3604 26 Jul 07 nicklas 14   BASE is distributed in the hope that it will be useful,
3604 26 Jul 07 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
3604 26 Jul 07 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3604 26 Jul 07 nicklas 17   GNU General Public License for more details.
3604 26 Jul 07 nicklas 18
3604 26 Jul 07 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
3604 26 Jul 07 nicklas 21 */
3604 26 Jul 07 nicklas 22 package net.sf.basedb.util.jep.convert;
3604 26 Jul 07 nicklas 23
3604 26 Jul 07 nicklas 24 import net.sf.basedb.core.BaseException;
3604 26 Jul 07 nicklas 25 import net.sf.basedb.core.query.Expression;
3604 26 Jul 07 nicklas 26 import net.sf.basedb.core.query.Restriction;
3604 26 Jul 07 nicklas 27 import net.sf.basedb.util.jep.JepExpressionFunction;
3604 26 Jul 07 nicklas 28 import net.sf.basedb.util.jep.JepRestrictionFunction;
3604 26 Jul 07 nicklas 29
3604 26 Jul 07 nicklas 30 import org.nfunk.jep.ASTFunNode;
3604 26 Jul 07 nicklas 31 import org.nfunk.jep.Operator;
3604 26 Jul 07 nicklas 32 import org.nfunk.jep.function.PostfixMathCommandI;
3604 26 Jul 07 nicklas 33
3604 26 Jul 07 nicklas 34 /**
3604 26 Jul 07 nicklas 35   Converts a function node to an expression or restriction. Function
3604 26 Jul 07 nicklas 36   nodes are used by JEP to represent both operators (+, -, *, ==, !=, etc.)
3604 26 Jul 07 nicklas 37   and built-in or extended functions (ln, exp, sqrt, etc.).
3604 26 Jul 07 nicklas 38
3604 26 Jul 07 nicklas 39   @author nicklas
3604 26 Jul 07 nicklas 40   @version 2.4
3604 26 Jul 07 nicklas 41   @base.modified $Date$
3604 26 Jul 07 nicklas 42 */
3604 26 Jul 07 nicklas 43 public class ASTFunNodeConverter
3604 26 Jul 07 nicklas 44   extends AbstractJepConversionFunction<ASTFunNode>
3604 26 Jul 07 nicklas 45 {
3604 26 Jul 07 nicklas 46   
3604 26 Jul 07 nicklas 47   public ASTFunNodeConverter()
3604 26 Jul 07 nicklas 48   {}
3604 26 Jul 07 nicklas 49   
3604 26 Jul 07 nicklas 50   /*
3604 26 Jul 07 nicklas 51     From the JepConversionFunction interface
3604 26 Jul 07 nicklas 52     -------------------------------------------
3604 26 Jul 07 nicklas 53   */
3604 26 Jul 07 nicklas 54   /**
3604 26 Jul 07 nicklas 55     Get the {@link PostfixMathCommandI} object from the function node
3604 26 Jul 07 nicklas 56     and delegate conversion to {@link JepExpressionFunction} if that interface
3604 26 Jul 07 nicklas 57     is implemented. Otherwise check the {@link ConverterFactory} for
3604 26 Jul 07 nicklas 58     a registered converter and use it.
3604 26 Jul 07 nicklas 59     @throws BaseException If the node can't be converted
3604 26 Jul 07 nicklas 60   */
6875 20 Apr 15 nicklas 61   @SuppressWarnings({ "unchecked", "rawtypes" })
3604 26 Jul 07 nicklas 62   @Override
3604 26 Jul 07 nicklas 63   public Expression toExpression(ASTFunNode node)
3604 26 Jul 07 nicklas 64   {
3604 26 Jul 07 nicklas 65     Expression e = null;
3604 26 Jul 07 nicklas 66     PostfixMathCommandI function = node.getPFMC();
3604 26 Jul 07 nicklas 67     Operator operator = node.getOperator();
3604 26 Jul 07 nicklas 68     int numAllowed = function.getNumberOfParameters();
3604 26 Jul 07 nicklas 69     if (numAllowed != -1 && numAllowed != node.jjtGetNumChildren())
3604 26 Jul 07 nicklas 70     {
3604 26 Jul 07 nicklas 71       throw new BaseException("Invalid number of expressions for '" + node.getName() + 
3604 26 Jul 07 nicklas 72         "' function: " + node.jjtGetNumChildren());
3604 26 Jul 07 nicklas 73     }
3604 26 Jul 07 nicklas 74     if (function instanceof JepExpressionFunction)
3604 26 Jul 07 nicklas 75     {
3604 26 Jul 07 nicklas 76       e = ((JepExpressionFunction)function).toExpression(node);
3604 26 Jul 07 nicklas 77     }
3604 26 Jul 07 nicklas 78     else
3604 26 Jul 07 nicklas 79     {
3604 26 Jul 07 nicklas 80       JepConversionFunction converter = getConverter(function, operator);
3604 26 Jul 07 nicklas 81       if (converter != null) 
3604 26 Jul 07 nicklas 82       {
3604 26 Jul 07 nicklas 83         e = converter.toExpression(node);
3604 26 Jul 07 nicklas 84       }
3604 26 Jul 07 nicklas 85       else
3604 26 Jul 07 nicklas 86       {
3604 26 Jul 07 nicklas 87         throw new BaseException("Unsupported JEP function: " + node);
3604 26 Jul 07 nicklas 88       }
3604 26 Jul 07 nicklas 89     }
3604 26 Jul 07 nicklas 90     return e;
3604 26 Jul 07 nicklas 91   }
3604 26 Jul 07 nicklas 92   /**
3604 26 Jul 07 nicklas 93     Get the {@link PostfixMathCommandI} object from the function node
3604 26 Jul 07 nicklas 94     and delegate conversion to {@link JepRestrictionFunction} if that interface
3604 26 Jul 07 nicklas 95     is implemented. Otherwise check the {@link ConverterFactory} for
3604 26 Jul 07 nicklas 96     a registered converter and use it.
3604 26 Jul 07 nicklas 97     
3604 26 Jul 07 nicklas 98     Get the {@link Operator} object from the function node
3604 26 Jul 07 nicklas 99     and check the {@link ConverterFactory} for
3604 26 Jul 07 nicklas 100     a registered converter and use it.
3604 26 Jul 07 nicklas 101     @throws BaseException If the node can't be converted
3604 26 Jul 07 nicklas 102   */
6875 20 Apr 15 nicklas 103   @SuppressWarnings({ "unchecked", "rawtypes" })
3604 26 Jul 07 nicklas 104   @Override
3604 26 Jul 07 nicklas 105   public Restriction toRestriction(ASTFunNode node)
3604 26 Jul 07 nicklas 106   {
3604 26 Jul 07 nicklas 107     Restriction r = null;
3604 26 Jul 07 nicklas 108     PostfixMathCommandI function = node.getPFMC();
3604 26 Jul 07 nicklas 109     Operator operator = node.getOperator();
3604 26 Jul 07 nicklas 110     int numAllowed = function.getNumberOfParameters();
3604 26 Jul 07 nicklas 111     if (numAllowed != -1 && numAllowed != node.jjtGetNumChildren())
3604 26 Jul 07 nicklas 112     {
3604 26 Jul 07 nicklas 113       throw new BaseException("Invalid number of expressions for '" + node.getName() + 
3604 26 Jul 07 nicklas 114         "' function: " + node.jjtGetNumChildren());
3604 26 Jul 07 nicklas 115     }
3604 26 Jul 07 nicklas 116     if (function instanceof JepRestrictionFunction)
3604 26 Jul 07 nicklas 117     {
3604 26 Jul 07 nicklas 118       r = ((JepRestrictionFunction)function).toRestriction(node);
3604 26 Jul 07 nicklas 119     }
3604 26 Jul 07 nicklas 120     else
3604 26 Jul 07 nicklas 121     {
3604 26 Jul 07 nicklas 122       JepConversionFunction converter = getConverter(function, operator);
3604 26 Jul 07 nicklas 123       if (converter != null) 
3604 26 Jul 07 nicklas 124       {
3604 26 Jul 07 nicklas 125         r = converter.toRestriction(node);
3604 26 Jul 07 nicklas 126       }
3604 26 Jul 07 nicklas 127       else
3604 26 Jul 07 nicklas 128       {
3604 26 Jul 07 nicklas 129         throw new BaseException("Unsupported JEP function: " + node);
3604 26 Jul 07 nicklas 130       }
3604 26 Jul 07 nicklas 131     }
3604 26 Jul 07 nicklas 132     return r;
3604 26 Jul 07 nicklas 133   }
3604 26 Jul 07 nicklas 134   // -------------------------------------------
3604 26 Jul 07 nicklas 135
3604 26 Jul 07 nicklas 136   /**
3604 26 Jul 07 nicklas 137     Get a converter by first checking the if one exists for the given function,
3604 26 Jul 07 nicklas 138     and then for the given operator symbol.
3604 26 Jul 07 nicklas 139     @return The converter or null if none is found
3604 26 Jul 07 nicklas 140   */
6875 20 Apr 15 nicklas 141   private JepConversionFunction<?> getConverter(PostfixMathCommandI function, Operator operator)
3604 26 Jul 07 nicklas 142   {
6875 20 Apr 15 nicklas 143     JepConversionFunction<?> converter = ConverterFactory.getConverterByClass(function);
5319 20 Apr 10 nicklas 144     if (converter == null && operator != null) 
5319 20 Apr 10 nicklas 145     {
5319 20 Apr 10 nicklas 146       converter = ConverterFactory.getConverter(operator.getSymbol());
5319 20 Apr 10 nicklas 147     }
3604 26 Jul 07 nicklas 148     return converter;
3604 26 Jul 07 nicklas 149   }
3604 26 Jul 07 nicklas 150   
3604 26 Jul 07 nicklas 151 }