1581 |
09 Nov 05 |
nicklas |
1 |
/* |
1581 |
09 Nov 05 |
nicklas |
$Id$ |
1581 |
09 Nov 05 |
nicklas |
3 |
|
3675 |
16 Aug 07 |
jari |
Copyright (C) 2005 Nicklas Nordborg |
4889 |
06 Apr 09 |
nicklas |
Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg |
3675 |
16 Aug 07 |
jari |
Copyright (C) 2007 Nicklas Nordborg |
1581 |
09 Nov 05 |
nicklas |
7 |
|
2304 |
22 May 06 |
jari |
This file is part of BASE - BioArray Software Environment. |
2304 |
22 May 06 |
jari |
Available at http://base.thep.lu.se/ |
1581 |
09 Nov 05 |
nicklas |
10 |
|
1581 |
09 Nov 05 |
nicklas |
BASE is free software; you can redistribute it and/or |
1581 |
09 Nov 05 |
nicklas |
modify it under the terms of the GNU General Public License |
4479 |
05 Sep 08 |
jari |
as published by the Free Software Foundation; either version 3 |
1581 |
09 Nov 05 |
nicklas |
of the License, or (at your option) any later version. |
1581 |
09 Nov 05 |
nicklas |
15 |
|
1581 |
09 Nov 05 |
nicklas |
BASE is distributed in the hope that it will be useful, |
1581 |
09 Nov 05 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
1581 |
09 Nov 05 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1581 |
09 Nov 05 |
nicklas |
GNU General Public License for more details. |
1581 |
09 Nov 05 |
nicklas |
20 |
|
1581 |
09 Nov 05 |
nicklas |
You should have received a copy of the GNU General Public License |
4515 |
11 Sep 08 |
jari |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
1581 |
09 Nov 05 |
nicklas |
23 |
*/ |
1581 |
09 Nov 05 |
nicklas |
24 |
package net.sf.basedb.util.jep; |
1581 |
09 Nov 05 |
nicklas |
25 |
|
3604 |
26 Jul 07 |
nicklas |
26 |
import java.util.Collection; |
2655 |
22 Sep 06 |
nicklas |
27 |
import java.util.Vector; |
2655 |
22 Sep 06 |
nicklas |
28 |
|
1581 |
09 Nov 05 |
nicklas |
29 |
import net.sf.basedb.core.BaseException; |
2086 |
17 Mar 06 |
nicklas |
30 |
import net.sf.basedb.core.VirtualColumn; |
1581 |
09 Nov 05 |
nicklas |
31 |
import net.sf.basedb.core.query.Expressions; |
1581 |
09 Nov 05 |
nicklas |
32 |
import net.sf.basedb.core.query.Expression; |
1581 |
09 Nov 05 |
nicklas |
33 |
import net.sf.basedb.core.query.Dynamic; |
1581 |
09 Nov 05 |
nicklas |
34 |
import net.sf.basedb.core.query.Restrictions; |
1581 |
09 Nov 05 |
nicklas |
35 |
import net.sf.basedb.core.query.Restriction; |
2292 |
19 May 06 |
nicklas |
36 |
import net.sf.basedb.util.Enumeration; |
3604 |
26 Jul 07 |
nicklas |
37 |
import net.sf.basedb.util.jep.convert.ConverterFactory; |
3604 |
26 Jul 07 |
nicklas |
38 |
import net.sf.basedb.util.jep.convert.JepConversionFunction; |
1581 |
09 Nov 05 |
nicklas |
39 |
|
1581 |
09 Nov 05 |
nicklas |
40 |
import org.nfunk.jep.JEP; |
1581 |
09 Nov 05 |
nicklas |
41 |
import org.nfunk.jep.Node; |
1581 |
09 Nov 05 |
nicklas |
42 |
import org.nfunk.jep.ASTVarNode; |
1581 |
09 Nov 05 |
nicklas |
43 |
import org.nfunk.jep.ASTConstant; |
1581 |
09 Nov 05 |
nicklas |
44 |
|
1581 |
09 Nov 05 |
nicklas |
45 |
/** |
1581 |
09 Nov 05 |
nicklas |
Utility class for parsing mathematical expressions. This class uses |
1581 |
09 Nov 05 |
nicklas |
the Java Mathematical Expression Parser package from Singular Systems to |
1581 |
09 Nov 05 |
nicklas |
parse mathematical expressions. |
1581 |
09 Nov 05 |
nicklas |
<p> |
1581 |
09 Nov 05 |
nicklas |
Create a new {@link JEP} expression with the {@link #newJep(String, JepFunction[])} |
1581 |
09 Nov 05 |
nicklas |
method. If the expression contains variables set values for those with the |
1581 |
09 Nov 05 |
nicklas |
{@link JEP#setVarValue(String, Object)} method. Then, evaluate the expression |
1581 |
09 Nov 05 |
nicklas |
using the {@link JEP#getValue()} method. |
1581 |
09 Nov 05 |
nicklas |
<p> |
1581 |
09 Nov 05 |
nicklas |
You can also convert the expression to a Query API {@link Expression} |
1581 |
09 Nov 05 |
nicklas |
object with the {@link #jepToExpression(JEP)} method. The conversion |
1581 |
09 Nov 05 |
nicklas |
doesn't support all methods since the Query API doesn't have support for |
1581 |
09 Nov 05 |
nicklas |
them. |
1581 |
09 Nov 05 |
nicklas |
<p> |
1581 |
09 Nov 05 |
nicklas |
See the <a href="http://www.singularsys.com/jep/">JEP homepage</a> for more |
1581 |
09 Nov 05 |
nicklas |
information about JEP and all supported functions/operators. |
1581 |
09 Nov 05 |
nicklas |
See {@link #jepToExpression(JEP)} and {@link #jepToRestriction(JEP)} |
1581 |
09 Nov 05 |
nicklas |
for functions/operators supported by the conversion methods. |
1581 |
09 Nov 05 |
nicklas |
64 |
|
1581 |
09 Nov 05 |
nicklas |
@author Nicklas |
1581 |
09 Nov 05 |
nicklas |
@version 2.0 |
1581 |
09 Nov 05 |
nicklas |
@base.modified $Date$ |
1581 |
09 Nov 05 |
nicklas |
@see <a href="http://www.singularsys.com/jep/">Java Mathematical Expression Parser package</a> |
1581 |
09 Nov 05 |
nicklas |
69 |
*/ |
1581 |
09 Nov 05 |
nicklas |
70 |
public class Jep |
1581 |
09 Nov 05 |
nicklas |
71 |
{ |
1581 |
09 Nov 05 |
nicklas |
72 |
|
5384 |
13 Aug 10 |
nicklas |
73 |
private static volatile Enumeration<String, String> functions; |
5384 |
13 Aug 10 |
nicklas |
74 |
private static volatile Enumeration<String, String> operators; |
2292 |
19 May 06 |
nicklas |
75 |
|
1581 |
09 Nov 05 |
nicklas |
76 |
/** |
1581 |
09 Nov 05 |
nicklas |
Create a new JEP expression. Evaluate the expression using |
1581 |
09 Nov 05 |
nicklas |
the {@link JEP#getValue()} method. Set values for variables |
1581 |
09 Nov 05 |
nicklas |
with the {@link JEP#setVarValue(String, Object)}. |
1581 |
09 Nov 05 |
nicklas |
80 |
|
1581 |
09 Nov 05 |
nicklas |
@param formula The expression to parse |
1581 |
09 Nov 05 |
nicklas |
@param functions Extra functions that are required to parse the |
1581 |
09 Nov 05 |
nicklas |
expression |
1581 |
09 Nov 05 |
nicklas |
@return A <code>JEP</code> object |
1581 |
09 Nov 05 |
nicklas |
@throws BaseException If the expression couldn't be parsed |
1581 |
09 Nov 05 |
nicklas |
86 |
*/ |
1581 |
09 Nov 05 |
nicklas |
87 |
public static JEP newJep(String formula, JepFunction... functions) |
1581 |
09 Nov 05 |
nicklas |
88 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
89 |
{ |
1581 |
09 Nov 05 |
nicklas |
90 |
formula = formula.replace("'", "\""); |
5319 |
20 Apr 10 |
nicklas |
91 |
JEP jep = new FunctionSafeJep(); |
1581 |
09 Nov 05 |
nicklas |
92 |
jep.setAllowUndeclared(true); |
1581 |
09 Nov 05 |
nicklas |
93 |
jep.addStandardFunctions(); |
2086 |
17 Mar 06 |
nicklas |
94 |
addFunctions(jep, Log2Function.getInstance()); |
2086 |
17 Mar 06 |
nicklas |
95 |
if (functions != null) addFunctions(jep, functions); |
1581 |
09 Nov 05 |
nicklas |
96 |
jep.parseExpression(formula); |
1581 |
09 Nov 05 |
nicklas |
97 |
if (jep.hasError()) |
1581 |
09 Nov 05 |
nicklas |
98 |
{ |
5319 |
20 Apr 10 |
nicklas |
99 |
throw new BaseException(jep.getErrorInfo().replace("\n", " ") + "in formula " + formula); |
1581 |
09 Nov 05 |
nicklas |
100 |
} |
1581 |
09 Nov 05 |
nicklas |
101 |
return jep; |
1581 |
09 Nov 05 |
nicklas |
102 |
} |
1581 |
09 Nov 05 |
nicklas |
103 |
|
2086 |
17 Mar 06 |
nicklas |
104 |
private static void addFunctions(JEP jep, JepFunction... functions) |
2086 |
17 Mar 06 |
nicklas |
105 |
{ |
2086 |
17 Mar 06 |
nicklas |
106 |
for (JepFunction function : functions) |
2086 |
17 Mar 06 |
nicklas |
107 |
{ |
2086 |
17 Mar 06 |
nicklas |
108 |
if (function != null) jep.addFunction(function.getFunctionName(), function); |
2086 |
17 Mar 06 |
nicklas |
109 |
} |
2086 |
17 Mar 06 |
nicklas |
110 |
} |
2086 |
17 Mar 06 |
nicklas |
111 |
|
1581 |
09 Nov 05 |
nicklas |
112 |
/** |
3604 |
26 Jul 07 |
nicklas |
Get a list of built-in functions supported by the {@link #jepToExpression(JEP)} |
3604 |
26 Jul 07 |
nicklas |
converter. More functions can be registered when creating the JEP |
3604 |
26 Jul 07 |
nicklas |
expression (see {@link #newJep(String, JepFunction[])}). |
3604 |
26 Jul 07 |
nicklas |
116 |
|
2292 |
19 May 06 |
nicklas |
@return An enumeration with the name of the function in the key |
2292 |
19 May 06 |
nicklas |
and a description in the value part |
2292 |
19 May 06 |
nicklas |
119 |
*/ |
2292 |
19 May 06 |
nicklas |
120 |
public static Enumeration<String, String> getFunctions() |
2292 |
19 May 06 |
nicklas |
121 |
{ |
2292 |
19 May 06 |
nicklas |
122 |
if (functions == null) |
2292 |
19 May 06 |
nicklas |
123 |
{ |
5384 |
13 Aug 10 |
nicklas |
124 |
synchronized (Jep.class) |
3604 |
26 Jul 07 |
nicklas |
125 |
{ |
5384 |
13 Aug 10 |
nicklas |
126 |
if (functions == null) |
3604 |
26 Jul 07 |
nicklas |
127 |
{ |
5384 |
13 Aug 10 |
nicklas |
128 |
functions = new Enumeration<String, String>(); |
5384 |
13 Aug 10 |
nicklas |
// Built-in converters |
5384 |
13 Aug 10 |
nicklas |
130 |
Collection<JepConversionFunction<?>> converters = ConverterFactory.getConverters(); |
6875 |
20 Apr 15 |
nicklas |
131 |
for (JepConversionFunction<?> converter : converters) |
5384 |
13 Aug 10 |
nicklas |
132 |
{ |
5384 |
13 Aug 10 |
nicklas |
133 |
if (converter.isFunction()) |
5384 |
13 Aug 10 |
nicklas |
134 |
{ |
5384 |
13 Aug 10 |
nicklas |
135 |
functions.add(converter.getName(), converter.getDescription()); |
5384 |
13 Aug 10 |
nicklas |
136 |
} |
5384 |
13 Aug 10 |
nicklas |
137 |
} |
5689 |
11 Aug 11 |
nicklas |
// Other standard functions that we always add. See newJep() method |
5384 |
13 Aug 10 |
nicklas |
139 |
functions.add("log2", "2-based logarithm"); |
5384 |
13 Aug 10 |
nicklas |
140 |
functions.sortKeys(); |
5384 |
13 Aug 10 |
nicklas |
141 |
functions.lock(); |
3604 |
26 Jul 07 |
nicklas |
142 |
} |
3604 |
26 Jul 07 |
nicklas |
143 |
} |
2292 |
19 May 06 |
nicklas |
144 |
} |
2292 |
19 May 06 |
nicklas |
145 |
return functions; |
2292 |
19 May 06 |
nicklas |
146 |
} |
2292 |
19 May 06 |
nicklas |
147 |
|
2292 |
19 May 06 |
nicklas |
148 |
/** |
3604 |
26 Jul 07 |
nicklas |
Get a list of built-in operators supported by the {@link #jepToExpression(JEP)} |
3604 |
26 Jul 07 |
nicklas |
and {@link #jepToRestriction(JEP)} converter. It is not possible to |
3604 |
26 Jul 07 |
nicklas |
register more operators. |
3604 |
26 Jul 07 |
nicklas |
152 |
|
3604 |
26 Jul 07 |
nicklas |
@return An enumeration with the symbol of the operator in the key |
3604 |
26 Jul 07 |
nicklas |
and a description in the value part |
3604 |
26 Jul 07 |
nicklas |
@since 2.4 |
3604 |
26 Jul 07 |
nicklas |
156 |
*/ |
3604 |
26 Jul 07 |
nicklas |
157 |
public static Enumeration<String, String> getOperators() |
3604 |
26 Jul 07 |
nicklas |
158 |
{ |
3604 |
26 Jul 07 |
nicklas |
159 |
if (operators == null) |
3604 |
26 Jul 07 |
nicklas |
160 |
{ |
5384 |
13 Aug 10 |
nicklas |
161 |
synchronized (Jep.class) |
3604 |
26 Jul 07 |
nicklas |
162 |
{ |
5384 |
13 Aug 10 |
nicklas |
163 |
if (operators == null) |
3604 |
26 Jul 07 |
nicklas |
164 |
{ |
5384 |
13 Aug 10 |
nicklas |
165 |
operators = new Enumeration<String, String>(); |
5384 |
13 Aug 10 |
nicklas |
// Built-in converters |
5384 |
13 Aug 10 |
nicklas |
167 |
Collection<JepConversionFunction<?>> converters = ConverterFactory.getConverters(); |
6875 |
20 Apr 15 |
nicklas |
168 |
for (JepConversionFunction<?> converter : converters) |
5384 |
13 Aug 10 |
nicklas |
169 |
{ |
5384 |
13 Aug 10 |
nicklas |
170 |
if (converter.isOperator()) |
5384 |
13 Aug 10 |
nicklas |
171 |
{ |
5384 |
13 Aug 10 |
nicklas |
172 |
operators.add(converter.getName(), converter.getDescription()); |
5384 |
13 Aug 10 |
nicklas |
173 |
} |
5384 |
13 Aug 10 |
nicklas |
174 |
} |
5384 |
13 Aug 10 |
nicklas |
175 |
operators.sortKeys(); |
5384 |
13 Aug 10 |
nicklas |
176 |
operators.lock(); |
3604 |
26 Jul 07 |
nicklas |
177 |
} |
3604 |
26 Jul 07 |
nicklas |
178 |
} |
3604 |
26 Jul 07 |
nicklas |
179 |
} |
3604 |
26 Jul 07 |
nicklas |
180 |
return operators; |
3604 |
26 Jul 07 |
nicklas |
181 |
} |
3604 |
26 Jul 07 |
nicklas |
182 |
|
3604 |
26 Jul 07 |
nicklas |
183 |
|
3604 |
26 Jul 07 |
nicklas |
184 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert a JEP expression to a Query API {@link Expression}. The Query API |
1581 |
09 Nov 05 |
nicklas |
only supports a subset of the functions/operators that JEP supports. |
2292 |
19 May 06 |
nicklas |
Supported operators are: |
1581 |
09 Nov 05 |
nicklas |
188 |
|
1581 |
09 Nov 05 |
nicklas |
<pre class="code"> |
1581 |
09 Nov 05 |
nicklas |
+ {@link Expressions#add(Expression, Expression)} |
1581 |
09 Nov 05 |
nicklas |
- {@link Expressions#subtract(Expression, Expression)} |
1581 |
09 Nov 05 |
nicklas |
* {@link Expressions#multiply(Expression, Expression)} |
1581 |
09 Nov 05 |
nicklas |
/ {@link Expressions#divide(Expression, Expression)} |
1581 |
09 Nov 05 |
nicklas |
- {@link Expressions#negate(Expression)} |
2292 |
19 May 06 |
nicklas |
log {@link Expressions#log10(Expression)} |
2086 |
17 Mar 06 |
nicklas |
log2 {@link Expressions#log2(Expression)} |
1581 |
09 Nov 05 |
nicklas |
ln {@link Expressions#ln(Expression)} |
2302 |
22 May 06 |
nicklas |
sqrt {@link Expressions#sqrt(Expression)} |
2292 |
19 May 06 |
nicklas |
abs {@link Expressions#abs(Expression)} |
2292 |
19 May 06 |
nicklas |
exp {@link Expressions#exp(Expression)} |
1581 |
09 Nov 05 |
nicklas |
raw {@link Dynamic#rawData(String)} * |
2086 |
17 Mar 06 |
nicklas |
ch {@link Dynamic#column(VirtualColumn)} * |
4912 |
29 Apr 09 |
nicklas |
rawCh {@link Dynamic#column(VirtualColumn)} * |
1581 |
09 Nov 05 |
nicklas |
<i>number</i> {@link Expressions#integer(int)} or |
1581 |
09 Nov 05 |
nicklas |
{@link Expressions#aFloat(float)} |
1581 |
09 Nov 05 |
nicklas |
<i>string</i> {@link Expressions#parameter(String, Object)} |
3456 |
06 Jun 07 |
nicklas |
<i>variable</i> {@link Expressions#parameter(String)} ** |
1581 |
09 Nov 05 |
nicklas |
</pre> |
3456 |
06 Jun 07 |
nicklas |
* = This is a optional function that must be registered when creating the |
3456 |
06 Jun 07 |
nicklas |
JEP object. |
3456 |
06 Jun 07 |
nicklas |
<br> |
3456 |
06 Jun 07 |
nicklas |
** = The NULL string is converted to a NULL value |
1581 |
09 Nov 05 |
nicklas |
213 |
|
1581 |
09 Nov 05 |
nicklas |
@param jep The JEP object |
1581 |
09 Nov 05 |
nicklas |
@return An <code>Expression</code> object |
1581 |
09 Nov 05 |
nicklas |
@throws BaseException If the JEP expression can't be converted |
1584 |
10 Nov 05 |
nicklas |
@see #newJep(String, JepFunction[]) |
2292 |
19 May 06 |
nicklas |
@see #getFunctions() |
1581 |
09 Nov 05 |
nicklas |
219 |
*/ |
1581 |
09 Nov 05 |
nicklas |
220 |
public static Expression jepToExpression(JEP jep) |
1581 |
09 Nov 05 |
nicklas |
221 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
222 |
{ |
1581 |
09 Nov 05 |
nicklas |
223 |
return nodeToExpression(jep.getTopNode()); |
1581 |
09 Nov 05 |
nicklas |
224 |
} |
1581 |
09 Nov 05 |
nicklas |
225 |
|
1581 |
09 Nov 05 |
nicklas |
226 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert JEP expression to a Query API {@link Expression}. This method |
1581 |
09 Nov 05 |
nicklas |
is equivalent to: <code>jepToExpression(newJep(formula, functions))</code>. |
1581 |
09 Nov 05 |
nicklas |
@see #jepToExpression(JEP) |
1581 |
09 Nov 05 |
nicklas |
230 |
*/ |
1581 |
09 Nov 05 |
nicklas |
231 |
public static Expression formulaToExpression(String formula, JepFunction... functions) |
1581 |
09 Nov 05 |
nicklas |
232 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
233 |
{ |
1581 |
09 Nov 05 |
nicklas |
234 |
return jepToExpression(newJep(formula, functions)); |
1581 |
09 Nov 05 |
nicklas |
235 |
} |
1581 |
09 Nov 05 |
nicklas |
236 |
|
1581 |
09 Nov 05 |
nicklas |
237 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert a JEP expression to a Query API {@link Restriction}. The |
1581 |
09 Nov 05 |
nicklas |
Query API only supports a subset of the functions/operators that |
1581 |
09 Nov 05 |
nicklas |
JEP supports. |
1581 |
09 Nov 05 |
nicklas |
Supported functions/operators are: |
1581 |
09 Nov 05 |
nicklas |
<pre class="code"> |
1584 |
10 Nov 05 |
nicklas |
== {@link Restrictions#eq(Expression, Expression)} |
1584 |
10 Nov 05 |
nicklas |
!= {@link Restrictions#neq(Expression, Expression)} |
1584 |
10 Nov 05 |
nicklas |
> {@link Restrictions#gt(Expression, Expression)} |
1584 |
10 Nov 05 |
nicklas |
>= {@link Restrictions#gteq(Expression, Expression)} |
1584 |
10 Nov 05 |
nicklas |
< {@link Restrictions#lt(Expression, Expression)} |
1584 |
10 Nov 05 |
nicklas |
<= {@link Restrictions#lteq(Expression, Expression)} |
6898 |
12 May 15 |
nicklas |
> {@link Restrictions#gt(Expression, Expression)} |
6898 |
12 May 15 |
nicklas |
&& {@link Restrictions#and(Restriction[])} |
1584 |
10 Nov 05 |
nicklas |
|| {@link Restrictions#or(Restriction[])} |
1584 |
10 Nov 05 |
nicklas |
! {@link Restrictions#not(Restriction)} |
1581 |
09 Nov 05 |
nicklas |
</pre> |
1581 |
09 Nov 05 |
nicklas |
* = This is a optional function that must be registered when creating the JEP object. |
1581 |
09 Nov 05 |
nicklas |
<p> |
1581 |
09 Nov 05 |
nicklas |
All operators supported by the {@link #jepToExpression(JEP)} are of |
1581 |
09 Nov 05 |
nicklas |
course also supported in the appropriate places. |
1581 |
09 Nov 05 |
nicklas |
258 |
|
1581 |
09 Nov 05 |
nicklas |
@param jep The JEP object |
1581 |
09 Nov 05 |
nicklas |
@return A <code>Restriction</code> object |
1581 |
09 Nov 05 |
nicklas |
@throws BaseException If the JEP expression can't be converted |
1584 |
10 Nov 05 |
nicklas |
@see #newJep(String, JepFunction[]) |
1581 |
09 Nov 05 |
nicklas |
263 |
*/ |
1581 |
09 Nov 05 |
nicklas |
264 |
public static Restriction jepToRestriction(JEP jep) |
1581 |
09 Nov 05 |
nicklas |
265 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
266 |
{ |
3604 |
26 Jul 07 |
nicklas |
267 |
return nodeToRestriction(jep.getTopNode()); |
1581 |
09 Nov 05 |
nicklas |
268 |
} |
1581 |
09 Nov 05 |
nicklas |
269 |
|
1581 |
09 Nov 05 |
nicklas |
270 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert JEP expression to a Query API {@link Restriction}. This method |
1581 |
09 Nov 05 |
nicklas |
is equivalent to: <code>jepToRestriction(newJep(formula, functions))</code>. |
1581 |
09 Nov 05 |
nicklas |
@see #jepToRestriction(JEP) |
1581 |
09 Nov 05 |
nicklas |
274 |
*/ |
1581 |
09 Nov 05 |
nicklas |
275 |
public static Restriction formulaToRestriction(String formula, JepFunction... functions) |
1581 |
09 Nov 05 |
nicklas |
276 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
277 |
{ |
1581 |
09 Nov 05 |
nicklas |
278 |
return jepToRestriction(newJep(formula, functions)); |
1581 |
09 Nov 05 |
nicklas |
279 |
} |
1581 |
09 Nov 05 |
nicklas |
280 |
|
1581 |
09 Nov 05 |
nicklas |
281 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert a node with it's children to an expression. |
4020 |
29 Nov 07 |
martin |
@param node Node to convert to an expression |
4020 |
29 Nov 07 |
martin |
@return A {@link net.sf.basedb.core.query.Expression} object |
4020 |
29 Nov 07 |
martin |
@throws BaseException If the JEP function in node not is supported. |
1581 |
09 Nov 05 |
nicklas |
286 |
*/ |
6875 |
20 Apr 15 |
nicklas |
287 |
@SuppressWarnings({ "unchecked", "rawtypes" }) |
2086 |
17 Mar 06 |
nicklas |
288 |
public static Expression nodeToExpression(Node node) |
1581 |
09 Nov 05 |
nicklas |
289 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
290 |
{ |
3604 |
26 Jul 07 |
nicklas |
291 |
JepConversionFunction converter = ConverterFactory.getConverterByClass(node); |
3604 |
26 Jul 07 |
nicklas |
292 |
Expression e = null; |
3604 |
26 Jul 07 |
nicklas |
293 |
if (converter != null) |
1581 |
09 Nov 05 |
nicklas |
294 |
{ |
3604 |
26 Jul 07 |
nicklas |
295 |
e = converter.toExpression(node); |
1581 |
09 Nov 05 |
nicklas |
296 |
} |
1581 |
09 Nov 05 |
nicklas |
297 |
else |
1581 |
09 Nov 05 |
nicklas |
298 |
{ |
3604 |
26 Jul 07 |
nicklas |
299 |
throw new BaseException("Unsupported JEP function: " + node); |
1581 |
09 Nov 05 |
nicklas |
300 |
} |
3604 |
26 Jul 07 |
nicklas |
301 |
return e; |
1581 |
09 Nov 05 |
nicklas |
302 |
} |
1581 |
09 Nov 05 |
nicklas |
303 |
|
3604 |
26 Jul 07 |
nicklas |
304 |
/** |
3604 |
26 Jul 07 |
nicklas |
Convert a node with it's children to a restriction. |
4020 |
29 Nov 07 |
martin |
@param node JEP node to convert. |
4020 |
29 Nov 07 |
martin |
@return A {@link net.sf.basedb.core.query.Restriction} object |
4020 |
29 Nov 07 |
martin |
@throws BaseException If the JEP function in node is not supported by the converter. |
3604 |
26 Jul 07 |
nicklas |
@since 2.4 |
3604 |
26 Jul 07 |
nicklas |
310 |
*/ |
6875 |
20 Apr 15 |
nicklas |
311 |
@SuppressWarnings({ "unchecked", "rawtypes" }) |
3604 |
26 Jul 07 |
nicklas |
312 |
public static Restriction nodeToRestriction(Node node) |
1581 |
09 Nov 05 |
nicklas |
313 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
314 |
{ |
3604 |
26 Jul 07 |
nicklas |
315 |
JepConversionFunction converter = ConverterFactory.getConverterByClass(node); |
3604 |
26 Jul 07 |
nicklas |
316 |
Restriction r = null; |
3604 |
26 Jul 07 |
nicklas |
317 |
if (converter != null) |
1581 |
09 Nov 05 |
nicklas |
318 |
{ |
3604 |
26 Jul 07 |
nicklas |
319 |
r = converter.toRestriction(node); |
1581 |
09 Nov 05 |
nicklas |
320 |
} |
1581 |
09 Nov 05 |
nicklas |
321 |
else |
1581 |
09 Nov 05 |
nicklas |
322 |
{ |
3604 |
26 Jul 07 |
nicklas |
323 |
throw new BaseException("Unsupported JEP function: " + node); |
1581 |
09 Nov 05 |
nicklas |
324 |
} |
3604 |
26 Jul 07 |
nicklas |
325 |
return r; |
1581 |
09 Nov 05 |
nicklas |
326 |
} |
1581 |
09 Nov 05 |
nicklas |
327 |
|
1581 |
09 Nov 05 |
nicklas |
328 |
/** |
1581 |
09 Nov 05 |
nicklas |
Convert a node to a string value. Supported node types are |
2669 |
27 Sep 06 |
nicklas |
constants or variables. Constants will be converted to strings with the |
2669 |
27 Sep 06 |
nicklas |
toString() method. For variables the name is returned as the string. |
3456 |
06 Jun 07 |
nicklas |
This allows for unquoted strings in expressions. The NULL string |
3456 |
06 Jun 07 |
nicklas |
is converted to a NULL value. |
4020 |
29 Nov 07 |
martin |
@param node JEP node to convert. |
4020 |
29 Nov 07 |
martin |
@return A String object or null if the node does not have any value. |
4020 |
29 Nov 07 |
martin |
@throws BaseException If the node could not be converted in some way. |
1581 |
09 Nov 05 |
nicklas |
337 |
*/ |
2086 |
17 Mar 06 |
nicklas |
338 |
public static String nodeToString(Node node) |
1581 |
09 Nov 05 |
nicklas |
339 |
throws BaseException |
1581 |
09 Nov 05 |
nicklas |
340 |
{ |
1581 |
09 Nov 05 |
nicklas |
341 |
if (node instanceof ASTConstant) |
1581 |
09 Nov 05 |
nicklas |
342 |
{ |
1581 |
09 Nov 05 |
nicklas |
343 |
ASTConstant constNode = (ASTConstant)node; |
1581 |
09 Nov 05 |
nicklas |
344 |
Object value = constNode.getValue(); |
2669 |
27 Sep 06 |
nicklas |
345 |
return value == null ? null : value.toString(); |
1581 |
09 Nov 05 |
nicklas |
346 |
} |
1581 |
09 Nov 05 |
nicklas |
347 |
else if (node instanceof ASTVarNode) |
1581 |
09 Nov 05 |
nicklas |
348 |
{ |
1581 |
09 Nov 05 |
nicklas |
349 |
ASTVarNode varNode = (ASTVarNode)node; |
3456 |
06 Jun 07 |
nicklas |
350 |
String name = varNode.getName(); |
3456 |
06 Jun 07 |
nicklas |
351 |
if ("NULL".equalsIgnoreCase(name)) name = null; |
3456 |
06 Jun 07 |
nicklas |
352 |
return name; |
1581 |
09 Nov 05 |
nicklas |
353 |
} |
1581 |
09 Nov 05 |
nicklas |
354 |
throw new BaseException("Expected string expression: " + node); |
1581 |
09 Nov 05 |
nicklas |
355 |
} |
2086 |
17 Mar 06 |
nicklas |
356 |
|
2086 |
17 Mar 06 |
nicklas |
357 |
/** |
2086 |
17 Mar 06 |
nicklas |
Convert a node to an integer value. Supported node types are |
2086 |
17 Mar 06 |
nicklas |
constants. |
4020 |
29 Nov 07 |
martin |
@param node JEP node to convert. |
4020 |
29 Nov 07 |
martin |
@return an int object |
4020 |
29 Nov 07 |
martin |
@throws BaseException If the node could not be converted. |
2086 |
17 Mar 06 |
nicklas |
363 |
*/ |
2086 |
17 Mar 06 |
nicklas |
364 |
public static int nodeToInt(Node node) |
2086 |
17 Mar 06 |
nicklas |
365 |
throws BaseException |
2086 |
17 Mar 06 |
nicklas |
366 |
{ |
2086 |
17 Mar 06 |
nicklas |
367 |
if (node instanceof ASTConstant) |
2086 |
17 Mar 06 |
nicklas |
368 |
{ |
2086 |
17 Mar 06 |
nicklas |
369 |
ASTConstant constNode = (ASTConstant)node; |
2086 |
17 Mar 06 |
nicklas |
370 |
Object value = constNode.getValue(); |
2086 |
17 Mar 06 |
nicklas |
371 |
if (value instanceof Number) |
2086 |
17 Mar 06 |
nicklas |
372 |
{ |
2086 |
17 Mar 06 |
nicklas |
373 |
return ((Number)value).intValue(); |
2086 |
17 Mar 06 |
nicklas |
374 |
} |
2086 |
17 Mar 06 |
nicklas |
375 |
} |
2086 |
17 Mar 06 |
nicklas |
376 |
throw new BaseException("Expected integer expression: " + node); |
2086 |
17 Mar 06 |
nicklas |
377 |
} |
2655 |
22 Sep 06 |
nicklas |
378 |
|
2655 |
22 Sep 06 |
nicklas |
379 |
private static java.lang.reflect.Field jepErrorList = null; |
2655 |
22 Sep 06 |
nicklas |
380 |
static |
2655 |
22 Sep 06 |
nicklas |
381 |
{ |
2655 |
22 Sep 06 |
nicklas |
382 |
try |
2655 |
22 Sep 06 |
nicklas |
383 |
{ |
2655 |
22 Sep 06 |
nicklas |
384 |
jepErrorList = JEP.class.getDeclaredField("errorList"); |
2655 |
22 Sep 06 |
nicklas |
385 |
jepErrorList.setAccessible(true); |
2655 |
22 Sep 06 |
nicklas |
386 |
} |
2655 |
22 Sep 06 |
nicklas |
387 |
catch (Throwable t) |
2655 |
22 Sep 06 |
nicklas |
388 |
{} |
2655 |
22 Sep 06 |
nicklas |
389 |
} |
2655 |
22 Sep 06 |
nicklas |
390 |
|
2655 |
22 Sep 06 |
nicklas |
391 |
/** |
2655 |
22 Sep 06 |
nicklas |
This is a workaround for a bug in the JEP error handling. Before calling |
2655 |
22 Sep 06 |
nicklas |
{@link JEP#getValueAsObject()} the error list should be cleared. |
2655 |
22 Sep 06 |
nicklas |
394 |
*/ |
6875 |
20 Apr 15 |
nicklas |
395 |
@SuppressWarnings("rawtypes") |
2655 |
22 Sep 06 |
nicklas |
396 |
public static void clearErrorList(JEP jep) |
2655 |
22 Sep 06 |
nicklas |
397 |
{ |
2655 |
22 Sep 06 |
nicklas |
398 |
try |
2655 |
22 Sep 06 |
nicklas |
399 |
{ |
2655 |
22 Sep 06 |
nicklas |
400 |
Vector v = (Vector)jepErrorList.get(jep); |
2655 |
22 Sep 06 |
nicklas |
401 |
v.clear(); |
2655 |
22 Sep 06 |
nicklas |
402 |
} |
2655 |
22 Sep 06 |
nicklas |
403 |
catch (Throwable t) |
2655 |
22 Sep 06 |
nicklas |
404 |
{} |
2655 |
22 Sep 06 |
nicklas |
405 |
} |
2655 |
22 Sep 06 |
nicklas |
406 |
|
1581 |
09 Nov 05 |
nicklas |
407 |
|
1581 |
09 Nov 05 |
nicklas |
408 |
} |