001package co.codewizards.cloudstore.ls.core.invoke; 002 003import java.beans.PropertyChangeListener; 004import java.io.Serializable; 005import java.lang.reflect.Proxy; 006 007import co.codewizards.cloudstore.core.Uid; 008 009public interface Invoker { 010 011 /** 012 * Invoke a static method from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 013 * <p> 014 * Convenience method delegating to {@link #invokeStatic(String, String, String[], Object...)}. 015 * <p> 016 * See {@link #invoke(Object, String, String[], Object...)} for further details. 017 * @param clazz the class owning the static method to be invoked. Must not be <code>null</code>. 018 * @param methodName the name of the static method to be invoked. Must not be <code>null</code>. 019 * @param arguments the arguments passed to the static method. May be <code>null</code> (if the method does not take any parameters). 020 * @return the result of the method invocation. May be <code>null</code>. 021 * @see #invokeStatic(String, String, String[], Object...) 022 * @see #invoke(Object, String, String[], Object...) 023 */ 024 <T> T invokeStatic(Class<?> clazz, String methodName, Object... arguments); 025 026 /** 027 * Invoke a static method from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 028 * <p> 029 * Convenience method delegating to {@link #invokeStatic(String, String, String[], Object...)}. 030 * <p> 031 * See {@link #invoke(Object, String, String[], Object...)} for further details. 032 * @param className the fully qualified name of the class owning the static method to be invoked. Must not be <code>null</code>. 033 * @param methodName the name of the static method to be invoked. Must not be <code>null</code>. 034 * @param arguments the arguments passed to the static method. May be <code>null</code> (if the method does not take any parameters). 035 * @return the result of the method invocation. May be <code>null</code>. 036 * @see #invokeStatic(String, String, String[], Object...) 037 * @see #invoke(Object, String, String[], Object...) 038 */ 039 <T> T invokeStatic(String className, String methodName, Object... arguments); 040 041 /** 042 * Invoke a static method from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 043 * <p> 044 * Convenience method delegating to {@link #invokeStatic(String, String, String[], Object...)}. 045 * <p> 046 * See {@link #invoke(Object, String, String[], Object...)} for further details. 047 * @param clazz the class owning the static method to be invoked. Must not be <code>null</code>. 048 * @param methodName the name of the static method to be invoked. Must not be <code>null</code>. 049 * @param argumentTypes the argument-types. May be <code>null</code>; then a matching method 050 * will be searched. If there are multiple matching methods, an exception is thrown, though (and the argument-types must be 051 * specified). If {@code argumentTypes} is not <code>null</code>, its {@code length} must match the one of {@code arguments}. 052 * @param arguments the arguments passed to the static method. May be <code>null</code> (if the method does not take any parameters). 053 * @return the result of the method invocation. May be <code>null</code>. 054 * @see #invokeStatic(String, String, String[], Object...) 055 * @see #invoke(Object, String, String[], Object...) 056 */ 057 <T> T invokeStatic(Class<?> clazz, String methodName, Class<?>[] argumentTypes, Object... arguments); 058 059 /** 060 * Invoke a static method from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 061 * <p> 062 * See {@link #invoke(Object, String, String[], Object...)} for further details. 063 * @param className the fully qualified name of the class owning the static method to be invoked. Must not be <code>null</code>. 064 * @param methodName the name of the static method to be invoked. Must not be <code>null</code>. 065 * @param argumentTypeNames the fully qualified names of the argument-types. May be <code>null</code>; then a matching method 066 * will be searched. If there are multiple matching methods, an exception is thrown, though (and the argument-types must be 067 * specified). If {@code argumentTypeNames} is not <code>null</code>, its {@code length} must match the one of {@code arguments}. 068 * @param arguments the arguments passed to the static method. May be <code>null</code> (if the method does not take any parameters). 069 * @return the result of the method invocation. May be <code>null</code>. 070 * @see #invoke(Object, String, String[], Object...) 071 */ 072 <T> T invokeStatic(String className, String methodName, String[] argumentTypeNames, Object... arguments); 073 074 075 /** 076 * Invoke a constructor from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 077 * <p> 078 * Convenience method delegating to {@link #invokeConstructor(String, String[], Object...)}. 079 * <p> 080 * See {@link #invoke(Object, String, String[], Object...)} for further details. 081 * @param clazz the class to be instantiated. Must not be <code>null</code>. 082 * @param arguments the arguments passed to the constructor. May be <code>null</code> (if the constructor does not take any parameters). 083 * @return the newly created objectRef. Never <code>null</code>. 084 * @see #invokeConstructor(String, String[], Object...) 085 * @see #invoke(Object, String, String[], Object...) 086 */ 087 <T> T invokeConstructor(Class<T> clazz, Object... arguments); 088 089 /** 090 * Invoke a constructor from the {@code LocalServerClient} in the {@code LocalServer} or vice-versa. 091 * <p> 092 * See {@link #invoke(Object, String, String[], Object...)} for further details. 093 * @param className the fully qualified name of the class to be instantiated. Must not be <code>null</code>. 094 * @param arguments the arguments passed to the constructor. May be <code>null</code> (if the constructor does not take any parameters). 095 * @return the newly created objectRef. Never <code>null</code>. 096 * @see #invokeConstructor(String, String[], Object...) 097 * @see #invoke(Object, String, String[], Object...) 098 */ 099 <T> T invokeConstructor(String className, Object... arguments); 100 101 <T> T invokeConstructor(Class<T> clazz, Class<?>[] argumentTypes, Object... arguments); 102 103 <T> T invokeConstructor(String className, String[] argumentTypeNames, Object... arguments); 104 105 106 <T> T invoke(Object objectRef, String methodName, Object... arguments); 107 108 <T> T invoke(Object objectRef, String methodName, Class<?>[] argumentTypes, Object... arguments); 109 110 /** 111 * Invoke a method on the given {@code objectRef} (which is a proxy) in the {@code LocalServer} or in its client 112 * (from the respective other side). 113 * <p> 114 * The {@code LocalServer} might reside in the same JVM or in a separate JVM (on the same computer, hence "local"). 115 * <p> 116 * When invoking a method, the {@code arguments} must be passed to the real objectRef on the other side (in the other 117 * JVM). Therefore, all primitives ({@code byte}, {@code long} etc.) as well as all objects implementing 118 * {@link Serializable} are serialized (via Java native serialisation), transmitted via a REST call and deserialized. 119 * <p> 120 * If, however, an objectRef passed as an argument is a proxy of a real objectRef in the server (no matter, if it 121 * implements {@code Serializable} or not), it is converted into an {@link Object} instead - and this reference 122 * is transmitted via REST. The server then resolves the {@link Object} to the real objectRef. 123 * <p> 124 * If an objectRef in the {@code arguments} is neither a proxy of a {@code LocalServer}-objectRef (it may be a proxy of 125 * sth. else) nor implements {@code Serializable}, instead a reverse-proxy is created on the server-side. Therefore, an 126 * {@link Object} in the local JVM is created and passed via REST. The server then determines all interfaces of 127 * the real objectRef and instantiates a proxy (or re-uses an already existing one). This reverse-proxy-mechanism allows 128 * for passing a listener, e.g. a {@link PropertyChangeListener}: If the server invokes a method on the reverse-proxy, 129 * the {@code InverseInvoker} is used to invoke the corresponding method on the real objectRef in the client-JVM. 130 * <p> 131 * <b>Important:</b> For the proxies (both the ones on the client-side and the reverse-ones on the server-side), the 132 * standard Java {@link Proxy} is used. Therefore, only interfaces can be proxied - no classes. We cannot use cglib 133 * or any other more advanced proxy-lib, because these libs cannot be used with Android. 134 * <p> 135 * However, if a method declared by a class and not an interface should be invoked, this can still be done via this 136 * method - it's just less convenient. Additionally, reverse-proxies (on the server-side) obviously can only be passed 137 * to the real objectRef's method, if the method-signature uses an interface (or {@code Object}) for the argument in question. 138 * 139 * @param objectRef the proxy on which to invoke a method. Must not be <code>null</code>. This proxy 140 * was returned by a previous invocation of one of the <i>invoke*</i> methods (which might have happened 141 * indirectly via an invocation of a proxy's method). 142 * @param methodName the name of the method to be invoked. Must not be <code>null</code>. 143 * @param argumentTypeNames the fully qualified names of the argument-types. May be <code>null</code>; then a matching method 144 * will be searched. If there are multiple matching methods, an exception is thrown, though (and the argument-types must be 145 * specified). If {@code argumentTypeNames} is not <code>null</code>, its {@code length} must match the one of {@code arguments}. 146 * @param arguments the arguments passed to the method. May be <code>null</code> (if the method does not take any parameters). 147 * @return the result of the method invocation. This is either a serialized and deserialized "simple" objectRef or a 148 * proxy for a more complex objectRef on the server-side. 149 */ 150 <T> T invoke(Object objectRef, String methodName, String[] argumentTypeNames, Object... arguments); 151 152 void incRefCount(ObjectRef objectRef, Uid refId); 153 154 void decRefCount(ObjectRef objectRef, Uid refId); 155 156 ObjectManager getObjectManager(); 157 158 ClassInfoMap getClassInfoMap(); 159}