KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > engine > FunctionAlias


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.engine;
6
7 import java.lang.reflect.Method JavaDoc;
8 import java.lang.reflect.Modifier JavaDoc;
9 import java.sql.Connection JavaDoc;
10 import java.sql.SQLException JavaDoc;
11
12 import org.h2.command.Parser;
13 import org.h2.expression.Expression;
14 import org.h2.message.Message;
15 import org.h2.message.Trace;
16 import org.h2.table.Table;
17 import org.h2.value.DataType;
18 import org.h2.value.Value;
19 import org.h2.value.ValueNull;
20
21 public class FunctionAlias extends DbObject {
22
23     private String JavaDoc className;
24     private String JavaDoc methodName;
25     private Method JavaDoc javaMethod;
26     private int paramCount;
27     private boolean hasConnectionParam;
28     private int dataType;
29
30     public FunctionAlias(Database db, int id, String JavaDoc name, String JavaDoc javaClassMethod) throws SQLException JavaDoc {
31         super(db, id, name, Trace.FUNCTION);
32         int paren = javaClassMethod.indexOf('(');
33         int lastDot = javaClassMethod.lastIndexOf('.', paren < 0 ? javaClassMethod.length() : paren);
34         if(lastDot < 0) {
35             throw Message.getSQLException(Message.SYNTAX_ERROR_1, javaClassMethod);
36         }
37         className = javaClassMethod.substring(0, lastDot);
38         methodName = javaClassMethod.substring(lastDot + 1);
39         Class JavaDoc javaClass;
40         try {
41             javaClass = database.loadClass(className);
42         } catch (ClassNotFoundException JavaDoc e) {
43             throw Message.getSQLException(Message.CLASS_NOT_FOUND_1, new String JavaDoc[]{className + " (" + methodName + ")"}, e);
44         }
45         Method JavaDoc[] methods = javaClass.getMethods();
46         for(int i=0; i<methods.length; i++) {
47             Method JavaDoc m = methods[i];
48             if(!Modifier.isStatic(m.getModifiers())) {
49                 continue;
50             }
51             if(m.getName().equals(methodName)) {
52                 javaMethod = m;
53                 break;
54             } else if(getMethodSignature(m).equals(methodName)) {
55                 javaMethod = m;
56                 break;
57             }
58         }
59         if(javaMethod == null) {
60             throw Message.getSQLException(Message.METHOD_NOT_FOUND_1, methodName + " (" + className + ")");
61         }
62         Class JavaDoc[] paramClasses = javaMethod.getParameterTypes();
63         paramCount = paramClasses.length;
64         if(paramCount > 0) {
65             Class JavaDoc paramClass = paramClasses[0];
66             if(Connection JavaDoc.class.isAssignableFrom(paramClass)) {
67                 hasConnectionParam = true;
68                 paramCount--;
69             }
70         }
71         Class JavaDoc returnClass = javaMethod.getReturnType();
72         dataType = DataType.getTypeFromClass(returnClass);
73     }
74
75     private String JavaDoc getMethodSignature(Method JavaDoc m) {
76         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
77         buff.append(m.getName());
78         buff.append('(');
79         Class JavaDoc[] params = m.getParameterTypes();
80         for(int i=0; i<params.length; i++) {
81             if(i>0) {
82                 buff.append(", ");
83             }
84             Class JavaDoc p = params[i];
85             if(p.isArray()) {
86                 buff.append(p.getComponentType().getName());
87                 buff.append("[]");
88             } else {
89                 buff.append(p.getName());
90             }
91         }
92         buff.append(')');
93         return buff.toString();
94     }
95
96     public Class JavaDoc[] getColumnClasses() {
97         return javaMethod.getParameterTypes();
98     }
99
100     public int getDataType() {
101         return dataType;
102     }
103
104     public String JavaDoc getCreateSQLForCopy(Table table, String JavaDoc quotedName) {
105         throw Message.getInternalError();
106     }
107
108     public String JavaDoc getCreateSQL() {
109         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
110         buff.append("CREATE ALIAS ");
111         buff.append(getSQL());
112         buff.append(" FOR ");
113         buff.append(Parser.quoteIdentifier(className + "." + methodName));
114         return buff.toString();
115     }
116
117     public int getType() {
118         return DbObject.FUNCTION_ALIAS;
119     }
120
121     public void removeChildrenAndResources(Session session) throws SQLException JavaDoc {
122         className = methodName = null;
123         javaMethod = null;
124         invalidate();
125     }
126
127     public void checkRename() throws SQLException JavaDoc {
128         throw Message.getUnsupportedException();
129     }
130
131     public Value getValue(Session session, Expression[] args) throws SQLException JavaDoc {
132         return getValue(session, args, false);
133     }
134
135     public Value getValue(Session session, Expression[] args, boolean columnList) throws SQLException JavaDoc {
136         synchronized(this) {
137             Class JavaDoc[] paramClasses = javaMethod.getParameterTypes();
138             Object JavaDoc[] params = new Object JavaDoc[paramClasses.length];
139             int p = 0;
140             if(hasConnectionParam && params.length > 0) {
141                 params[p++] = session.createConnection(columnList);
142             }
143             for(int a=0; a<args.length && p<params.length; a++, p++) {
144                 Class JavaDoc paramClass = paramClasses[p];
145                 int type = DataType.getTypeFromClass(paramClass);
146                 Value v = args[a].getValue(session);
147                 v = v.convertTo(type);
148                 Object JavaDoc o = v.getObject();
149                 if(o == null) {
150                     if(paramClass.isPrimitive()) {
151                         if(columnList) {
152                             // if the column list is requested, the parameters may be null
153
// need to set to default value otherwise the function can't be called at all
154
o = DataType.getDefaultForPrimitiveType(paramClass);
155                         } else {
156                             // NULL value for a java primitive: return NULL
157
return ValueNull.INSTANCE;
158                         }
159                     }
160                 } else {
161                     if(!paramClass.isAssignableFrom(o.getClass()) && !paramClass.isPrimitive()) {
162                         o = DataType.convertTo(session, session.createConnection(false), v, paramClass);
163                     }
164                 }
165                 params[p] = o;
166             }
167             boolean old = session.getAutoCommit();
168             try {
169                 session.setAutoCommit(false);
170                 try {
171                     Object JavaDoc returnValue;
172                     returnValue = javaMethod.invoke(null, params);
173                     if(returnValue == null) {
174                         return ValueNull.INSTANCE;
175                     }
176                     Value ret = DataType.convertToValue(session, returnValue, dataType);
177                     return ret.convertTo(dataType);
178                 } catch (Exception JavaDoc e) {
179                     throw Message.convert(e);
180                 }
181             } finally {
182                 session.setAutoCommit(old);
183             }
184         }
185     }
186
187     public int getParameterCount() {
188         return paramCount;
189     }
190
191     public String JavaDoc getJavaClassName() {
192         return this.className;
193     }
194
195     public String JavaDoc getJavaMethodName() {
196         return this.methodName;
197     }
198     
199     public boolean hasConnectionParam() {
200         return this.hasConnectionParam;
201     }
202
203 }
204
Popular Tags