01: /*
02: * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
03: *
04: * This file is part of Resin(R) Open Source
05: *
06: * Each copy or derived work must preserve the copyright notice and this
07: * notice unmodified.
08: *
09: * Resin Open Source is free software; you can redistribute it and/or modify
10: * it under the terms of the GNU General Public License as published by
11: * the Free Software Foundation; either version 2 of the License, or
12: * (at your option) any later version.
13: *
14: * Resin Open Source is distributed in the hope that it will be useful,
15: * but WITHOUT ANY WARRANTY; without even the implied warranty of
16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17: * of NON-INFRINGEMENT. See the GNU General Public License for more
18: * details.
19: *
20: * You should have received a copy of the GNU General Public License
21: * along with Resin Open Source; if not, write to the
22: * Free SoftwareFoundation, Inc.
23: * 59 Temple Place, Suite 330
24: * Boston, MA 02111-1307 USA
25: *
26: * @author Scott Ferguson
27: */
28:
29: package com.caucho.es.wrapper;
30:
31: import com.caucho.es.Call;
32: import com.caucho.es.ESBase;
33: import com.caucho.es.ESNull;
34:
35: /**
36: * Dynamic selection of overloaded methods. This is really a last
37: * resort.
38: */
39: public class MethodDispatcher {
40: private Class[][] parameterTypes;
41:
42: public MethodDispatcher(Class[][] parameterTypes) {
43: this .parameterTypes = parameterTypes;
44: }
45:
46: /**
47: * Selects the best method among the list.
48: */
49: public int select(Call call, int length) throws Exception {
50: int bestCost = Integer.MAX_VALUE;
51: int bestMethod = -1;
52:
53: for (int i = 0; i < parameterTypes.length; i++) {
54: Class[] parameters = parameterTypes[i];
55:
56: int cost = 0;
57: for (int j = 0; j < parameters.length; j++) {
58: ESBase obj = call.getArg(j, length);
59: Class cl = obj.getJavaType();
60: Class param = parameters[j];
61:
62: if (cl.equals(param))
63: continue;
64:
65: // cl is the actual class, so don't need to worry about casting
66: else if (param.isAssignableFrom(cl))
67: cost += 10;
68:
69: else if (obj instanceof ESNull)
70: cost += 50;
71:
72: else if (cl.equals(void.class))
73: cost += 50;
74:
75: else if (cl.isPrimitive() && param.isPrimitive())
76: cost += 100;
77:
78: else {
79: cost = Integer.MAX_VALUE;
80: break;
81: }
82: }
83:
84: if (cost < bestCost) {
85: bestMethod = i;
86: bestCost = cost;
87: }
88: }
89:
90: return bestMethod;
91: }
92: }
|