1 /* |
|
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.script.util; |
|
27 |
|
28 import javax.script.*; |
|
29 import java.lang.reflect.*; |
|
30 import java.security.*; |
|
31 |
|
32 /* |
|
33 * java.lang.reflect.Proxy based interface implementor. This is meant |
|
34 * to be used to implement Invocable.getInterface. |
|
35 * |
|
36 * @author Mike Grogan |
|
37 * @since 1.6 |
|
38 */ |
|
39 public class InterfaceImplementor { |
|
40 |
|
41 private Invocable engine; |
|
42 |
|
43 /** Creates a new instance of Invocable */ |
|
44 public InterfaceImplementor(Invocable engine) { |
|
45 this.engine = engine; |
|
46 } |
|
47 |
|
48 private final class InterfaceImplementorInvocationHandler |
|
49 implements InvocationHandler { |
|
50 private Object thiz; |
|
51 private AccessControlContext accCtxt; |
|
52 |
|
53 public InterfaceImplementorInvocationHandler(Object thiz, |
|
54 AccessControlContext accCtxt) { |
|
55 this.thiz = thiz; |
|
56 this.accCtxt = accCtxt; |
|
57 } |
|
58 |
|
59 public Object invoke(Object proxy , Method method, Object[] args) |
|
60 throws java.lang.Throwable { |
|
61 // give chance to convert input args |
|
62 args = convertArguments(method, args); |
|
63 Object result; |
|
64 final Method m = method; |
|
65 final Object[] a = args; |
|
66 result = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { |
|
67 public Object run() throws Exception { |
|
68 if (thiz == null) { |
|
69 return engine.invokeFunction(m.getName(), a); |
|
70 } else { |
|
71 return engine.invokeMethod(thiz, m.getName(), a); |
|
72 } |
|
73 } |
|
74 }, accCtxt); |
|
75 // give chance to convert the method result |
|
76 return convertResult(method, result); |
|
77 } |
|
78 } |
|
79 |
|
80 public <T> T getInterface(Object thiz, Class<T> iface) |
|
81 throws ScriptException { |
|
82 if (iface == null || !iface.isInterface()) { |
|
83 throw new IllegalArgumentException("interface Class expected"); |
|
84 } |
|
85 if (! isImplemented(thiz, iface)) { |
|
86 return null; |
|
87 } |
|
88 AccessControlContext accCtxt = AccessController.getContext(); |
|
89 return iface.cast(Proxy.newProxyInstance(iface.getClassLoader(), |
|
90 new Class[]{iface}, |
|
91 new InterfaceImplementorInvocationHandler(thiz, accCtxt))); |
|
92 } |
|
93 |
|
94 protected boolean isImplemented(Object thiz, Class<?> iface) { |
|
95 return true; |
|
96 } |
|
97 |
|
98 // called to convert method result after invoke |
|
99 protected Object convertResult(Method method, Object res) |
|
100 throws ScriptException { |
|
101 // default is identity conversion |
|
102 return res; |
|
103 } |
|
104 |
|
105 // called to convert method arguments before invoke |
|
106 protected Object[] convertArguments(Method method, Object[] args) |
|
107 throws ScriptException { |
|
108 // default is identity conversion |
|
109 return args; |
|
110 } |
|
111 } |
|