⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.java

📁 JoSQL 1.5的源代码。JoSQL(SQL for Java Objects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2004-2005 Gary Bentley  *  * 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 org.josql.expressions;import java.util.List;import java.util.ArrayList;import java.util.Arrays;import java.util.Map;import java.util.TreeMap;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import com.gentlyweb.utils.Getter;import org.josql.Query;import org.josql.QueryExecutionException;import org.josql.QueryParseException;import org.josql.internal.Utilities;/** * This class represents a Function that can be "called" in JoSQL.   * <p> *  Last Modified By: $Author: barrygently $<br /> *  Last Modified On: $Date: 2005/01/07 17:08:07 $<br /> *  Current Revision: $Revision: 1.6 $<br /> */public class Function extends ValueExpression{    private String name = null;    private List params = null;    private Method function = null;    private Object handler = null;    private boolean fixedResult = true;    private Object fixedValue = null;    private String acc = null;    private Getter get = null;    public Getter getGetter ()    {	return this.get;    }    public String getAccessor ()    {	return this.acc;    }    public void setAccessor (String acc)    {	this.acc = acc;    }    /**     * Get the expected return type from the function.  The exact class returned is      * dependent upon the function (Java method) that is being called.     *      * @param q The Query object.     * @return The class of the expected return type.     */    public Class getExpectedReturnType (Query  q)    {	if (this.get != null)	{	    return this.get.getType ();	}	return this.function.getReturnType ();    }    /**     * This is a complex method that will initialise the function.     * Firstly all of the "arguments" to the function are inited and then     * their expected return types gained from calling: {@link Function#getExpectedReturnType(Query)}.     * Then the function handlers, user-defined and then built-in are searched until they     * find a match for the function name, ensure that it's a public method and that all the     * arguments match, widening the match where necessary.     *     * @param q The Query object.     * @throws QueryParseException If something goes wrong whilst initing the arguments to the      *                             function or if the function cannot be found.     */    public void init (Query  q)                      throws QueryParseException    {	// Need to init the params (if present) first because the expected type may not be	// present otherwise.	if (this.params != null)	{	    int s = this.params.size ();	    for (int i = 0; i < s; i++)	    {		Expression exp = (Expression) this.params.get (i);		exp.init (q);	    }	}	Class[] ps = null;	if (this.params != null)	{	    int s = params.size (); 	    ps = new Class[s];	    for (int i = 0; i < s; i++)	    {		// Need to get the expected return type.		Expression exp = (Expression) params.get (i);		ps[i] = exp.getExpectedReturnType (q);	    }	}	// Try and find the relevant method, first in the user-defined function handler (if present)	// or the built-in handlers.	List fhs = q.getFunctionHandlers ();	if (fhs != null)	{	    int s = fhs.size ();	    TreeMap ms = new TreeMap ();	    for (int i = 0; i < s; i++)	    {		Object fh = fhs.get (i);		this.getMethods (fh.getClass (),				 q,				 ms);			    }	    // Get the one with the highest score.	    if (ms.size () > 0)	    {		this.function = (Method) ms.get (ms.lastKey ());				Class c = this.function.getDeclaringClass ();		// What a pain!		for (int i = 0; i < fhs.size (); i++)		{		    Object o = fhs.get (i);		    if (o.getClass ().isAssignableFrom (c))		    {			this.handler = o;		    }		}			    }	}	List dfhs = q.getDefaultFunctionHandlers ();	if (this.function == null)	{	    TreeMap ms = new TreeMap ();	    for (int i = 0; i < dfhs.size (); i++)	    {	    		Object dfh = dfhs.get (i);		this.getMethods (dfh.getClass (),				 q,				 ms);	    }	    // Get the one with the highest score.	    if (ms.size () > 0)	    {		this.function = (Method) ms.get (ms.lastKey ());		Class c = this.function.getDeclaringClass ();		// What a pain!		for (int i = 0; i < dfhs.size (); i++)		{		    Object o = dfhs.get (i);		    if (o.getClass ().isAssignableFrom (c))		    {			this.handler = o;		    }		}			    } 	}	if (this.function == null)	{	    // Can't find the function.	    throw new QueryParseException ("Unable to find function (method): \"" +					   Utilities.formatSignature (this.name,								      ps) + 					   "\" in any user-defined function handlers or the default function handler");	}	// Now see if we have an accessor for the function.	if (this.acc != null)	{	    // We have an accessor, see what the functions return type is.	    Class retType = this.function.getReturnType ();	    // Ensure that the function DOES have a return type.	    if (Void.TYPE.isAssignableFrom (retType))	    {		// The return type is void, barf!		throw new QueryParseException ("Function: " + 					       this + 					       " maps to method: " +					       this.function +					       " however methods return type is \"void\" and an accessor: " +					       this.acc +					       " has been defined.");	    }	    // See if the return type is an object.  If it is then defer trying to	    // get the accessor until run-time.  Have to do it this way since	    // type comparisons are a little pointless.	    if (!retType.getName ().equals (Object.class.getName ()))	    {		// The return type is NOT java.lang.Object, so now try and get the 		// accessor.		try		{		    this.get = new Getter (this.acc,					   retType);		    		} catch (Exception e) {		    throw new QueryParseException ("Function: " +						   this +						   " maps to method: " +						   this.function +						   " and has accessor: " +						   this.acc +						   " however no valid accessor has been found in return type: " +						   retType.getName (),						   e);		}	    }	}	// A function has/can have a fixed result if all it's arguments	// also have a fixed result, if there aren't any args then assume	// it won't have a fixed result.	if (this.params != null)	{	    for (int i = 0; i < this.params.size (); i++)	    {		Expression exp = (Expression) this.params.get (i);		if (!exp.hasFixedResult (q))		{		    this.fixedResult = false;		    break;		}	    }	} else {	    this.fixedResult = false;	}    }    /**     * Return the List of {@link Expression} objects that constitute the arguments     * to the function, no guarantee is made here as to whether they have been inited.     *     * @return The List of {@link Expression} objects.     */    public List getParameters ()    {	return this.params;    }    public void setParameters (List ps)    {	this.params = ps;    }    public void setName (String name)    {	this.name = name;    }    public String getName ()    {	return this.name;    }    /**     * Evaluate this function on the current object.  It should be noted that not     * all functions will use the current object in their execution, functions from the     * {@link org.josql.functions.GroupingFunctions} class are notable exceptions.     *     * @param o The current object.     * @param q The Query object.     * @return The result of evaluating the function.     * @throws QueryExecutionException If something goes wrong during execution of the     *                                 function or gaining the values to be used as arguments.     */    public Object evaluate (Object o,			    Query  q)	                    throws QueryExecutionException    {	// See if we have a fixed result.	if (this.fixedResult)	{	    // Evaluated once...	    if (this.fixedValue != null)	    {		return this.fixedValue;	    }	}	// Get the values for the parameters... if any...	Object[] ps = null;	if (this.params != null)	{	    int s = this.params.size ();	    ps = new Object[s];	    for (int i = 0; i < s; i++)	    {		Expression exp = (Expression) this.params.get (i);	        if (Expression.class.isAssignableFrom (this.function.getParameterTypes ()[i]))		{		    // Leave this one alone.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -