📄 function.java
字号:
ps[i] = exp; } else { // Eval this expression. try { ps[i] = exp.getValue (o, q); } catch (Exception e) { throw new QueryExecutionException ("Unable to get parameter: " + i + " (\"" + exp.toString () + "\") for function: " + this.name, e); } } } } Object v = null; try { v = this.function.invoke (this.handler, ps); } catch (Exception e) { throw new QueryExecutionException ("Unable to execute function: " + this.name + " (\"" + this.toString () + "\") with values: " + Arrays.asList (ps), e); } if (v != null) { // See if we have an accessor. if (this.acc != null) { // See if we have a Getter. if (this.get == null) { // No getter, so now try and init it. This assumes that the return // type won't ever change! try { this.get = new Getter (this.acc, v.getClass ()); } catch (Exception e) { throw new QueryExecutionException ("Unable to create accessor for: " + this.acc + " from return type: " + v.getClass ().getName () + " after execution of function: " + this, e); } } try { v = this.get.getValue (v); } catch (Exception e) { throw new QueryExecutionException ("Unable to get value for accessor: " + this.acc + " from return type: " + v.getClass ().getName () + " after execution of function: " + this, e); } } } if (this.fixedResult) { this.fixedValue = v; } return v; } /** * Return whether the evaluation of this function (see: {@link #evaluate(Object,Query)}) * will result in a <code>true</code> value. * See: {@link ArithmeticExpression#isTrue(Object,Query)} for details of how this is * determined. * * @param o The current object. * @param q The Query object. * @return <code>true</code> if the function return value evaluates to <code>true</code>. * @throws QueryExecutionException If something goes wrong with evaluating the function. */ public boolean isTrue (Object o, Query q) throws QueryExecutionException { o = this.evaluate (o, q); if (o == null) { return false; } if (Utilities.isNumber (o)) { return Utilities.getDouble (o) > 0; } if (o instanceof Boolean) { return ((Boolean) o).booleanValue (); } // Not null so return true... return true; } /** * Return a string representation of the function. * In the form: Name ( {@link Expression} [ , {@link Expression} ] ) * * @return A string representation of the function. */ public String toString () { StringBuffer buf = new StringBuffer (); buf.append (this.name); buf.append ("("); if (this.params != null) { for (int i = 0; i < this.params.size (); i++) { Expression p = (Expression) this.params.get (i); buf.append (p); if (i < (this.params.size () - 1)) { buf.append (","); } } } buf.append (")"); if (this.acc != null) { buf.append ("."); buf.append (this.acc); } if (this.isBracketed ()) { buf.insert (0, "("); buf.append (")"); } return buf.toString (); } /** * Return whether the function will return a fixed result, this only * occurs iff all the arguments to the function also return a fixed result. * * @param q The Query object. */ public boolean hasFixedResult (Query q) { return this.fixedResult; } private int matchMethodArgs (Class[] methArgs, Query q) throws QueryParseException { // The score here helps in argument resolution, a more specific argument // match (that is NOT expression in the method args) will score higher and // thus is a better match. int score = 0; for (int i = 0; i < methArgs.length; i++) { Class c = methArgs[i]; Expression exp = (Expression) this.params.get (i); // See if the arg is object, which means "I can accept any type". if (c.getClass ().getName ().equals (Object.class.getName ())) { score += 1; continue; } // Now try and get the expected return type... Class expC = exp.getExpectedReturnType (q); if (expC == null) { // Can't match this arg. continue; } else { if (c.isAssignableFrom (expC)) { score += 2; continue; } } if (Expression.class.isAssignableFrom (c)) { score += 1; // This is a match... i.e. the arg is an expression and thus supported // in a "special" way. continue; } if ((Utilities.isNumber (expC)) && ((Utilities.isNumber (c)) || (c.getName ().equals (Object.class.getName ())) ) ) { score += 1; // This matches... continue; } if ((Utilities.isPrimitiveClass (c)) && (Utilities.isPrimitiveClass (expC)) ) { // It is a primitive class as well, so now see if they are compatible. if (Utilities.getPrimitiveClass (c).isAssignableFrom (Utilities.getPrimitiveClass (expC))) { score += 1; // They are assignable... continue; } } // See if the expression return type is an object... this "may" mean // that we can match and it may not, it will be determined at runtime. if (expC.getName ().equals (Object.class.getName ())) { score += 1; continue; } // If we are here then we can't match this arg type... // No point checking any further... return 0; } // All args can be matched. return score; } private void getMethods (Class c, Query q, Map matches) throws QueryParseException { Method[] meths = c.getMethods (); for (int i = 0; i < meths.length; i++) { Method m = meths[i]; if (!m.getName ().equals (this.name)) { continue; } // Make sure it's public... if (!Modifier.isPublic (m.getModifiers ())) { continue; } // Now check the args... sigh... Class[] mpt = m.getParameterTypes (); int ps = 0; int fps = 0; if (mpt != null) { ps = mpt.length; } if (this.params != null) { fps = this.params.size (); } if (ps != fps) { continue; } int score = this.matchMethodArgs (mpt, q); if (score > 0) { matches.put (new Integer (score), m); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -