summaryrefslogtreecommitdiffstats
path: root/jrt/src/com/yahoo/jrt/Method.java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /jrt/src/com/yahoo/jrt/Method.java
Publish
Diffstat (limited to 'jrt/src/com/yahoo/jrt/Method.java')
-rw-r--r--jrt/src/com/yahoo/jrt/Method.java290
1 files changed, 290 insertions, 0 deletions
diff --git a/jrt/src/com/yahoo/jrt/Method.java b/jrt/src/com/yahoo/jrt/Method.java
new file mode 100644
index 00000000000..d752e33b0d8
--- /dev/null
+++ b/jrt/src/com/yahoo/jrt/Method.java
@@ -0,0 +1,290 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jrt;
+
+
+/**
+ * <p>A Method encapsulates the reflective information about a single RPC
+ * method.</p>
+ *
+ * <p>Method parameters and return values are declared with type
+ * strings. A <i>type string</i> denotes the concatenation of type
+ * identifiers where a string is used to represent a sequence of
+ * types. For example 'ii' is the type string for two 32-bit integers,
+ * while 'iss' is the type string for a single 32-bit integer followed
+ * by two strings. The complete list of type identifiers can be found
+ * in the {@link Value} class.</p>
+ *
+ * <p>The type strings associated with actual method parameters and
+ * return values may only contain valid type identifiers. However,
+ * when you specify the parameters accepted by- or returned from a RPC
+ * method via the Method constructor, '*' may be used as the last
+ * character in the type string. Ending a type string specification
+ * with '*' means that additional values are optional and may have any
+ * type. This feature can also be used with the {@link
+ * Request#checkReturnTypes Request.checkReturnTypes} method when
+ * verifying return types.</p>
+ *
+ * @see Supervisor#addMethod
+ **/
+public class Method {
+
+ private MethodHandler handler; // option 1: interface
+ private Object object; // option 2: reflection
+ private java.lang.reflect.Method method; // option 2: reflection
+
+ private String name;
+ private String paramTypes;
+ private String returnTypes;
+
+ private String desc;
+ private String[] paramName;
+ private String[] paramDesc;
+ private String[] returnName;
+ private String[] returnDesc;
+
+ private static final String undocumented = "???";
+ private static final Class<?>[] handlerParams = { Request.class };
+
+
+ private void init(String name, String paramTypes, String returnTypes) {
+ this.name = name;
+ this.paramTypes = paramTypes;
+ this.returnTypes = returnTypes;
+ desc = undocumented;
+ paramName = new String[this.paramTypes.length()];
+ paramDesc = new String[this.paramTypes.length()];
+ for (int i = 0; i < this.paramTypes.length(); i++) {
+ paramName[i] = undocumented;
+ paramDesc[i] = undocumented;
+ }
+ returnName = new String[this.returnTypes.length()];
+ returnDesc = new String[this.returnTypes.length()];
+ for (int i = 0; i < this.returnTypes.length(); i++) {
+ returnName[i] = undocumented;
+ returnDesc[i] = undocumented;
+ }
+ }
+
+ /**
+ * Create a new Method. The parameters define the name of the
+ * method, the parameter types, the return value types and also
+ * what method in which object should be invoked to perform the
+ * method. Please refer to the {@link Method} class description
+ * for an explanation of type strings.
+ *
+ * @param name method name
+ * @param paramTypes a type string defining the parameter types
+ * @param returnTypes a type string defining the return value types
+ * @param handler the object handling this RPC method
+ * @param handlerMethod the name of the method in the handler that
+ * should be used to handle invocations of this RPC method. This
+ * method must be public, return void and take a {@link Request}
+ * as its only parameter.
+ *
+ * @throws MethodCreateException if the handler method cannot be
+ * resolved.
+ **/
+ public Method(String name, String paramTypes, String returnTypes,
+ Object handler, String handlerMethod) {
+
+ this.handler = null;
+ this.object = handler;
+ try {
+ this.method = this.object.getClass().getMethod(handlerMethod,
+ handlerParams);
+ } catch (Exception e) {
+ throw new MethodCreateException("Method lookup failed", e);
+ }
+ init(name, paramTypes, returnTypes);
+ }
+
+ /**
+ * Create a new Method. The parameters define the name of the
+ * method, the parameter types, the return value types and also
+ * the handler for the method. Please refer to the {@link Method}
+ * class description for an explanation of type strings.
+ *
+ * @param name method name
+ * @param paramTypes a type string defining the parameter types
+ * @param returnTypes a type string defining the return value types
+ * @param handler the handler for this RPC method
+ *
+ * @throws MethodCreateException if the handler is <i>null</i>.
+ **/
+ public Method(String name, String paramTypes, String returnTypes,
+ MethodHandler handler) {
+
+ this.handler = handler;
+ this.object = null;
+ this.method = null;
+ if (this.handler == null) {
+ throw new MethodCreateException("Handler is null");
+ }
+ init(name, paramTypes, returnTypes);
+ }
+
+ /**
+ * Obtain the name of this method
+ *
+ * @return method name
+ **/
+ String name() {
+ return name;
+ }
+
+ /**
+ * Obtain the parameter types of this method
+ *
+ * @return parameter types
+ **/
+ String paramTypes() {
+ return paramTypes;
+ }
+
+ /**
+ * Obtain the return value types of this method
+ *
+ * @return return value types
+ **/
+ String returnTypes() {
+ return returnTypes;
+ }
+
+ /**
+ * Describe this method. This adds documentation that can be
+ * obtained through remote reflection.
+ *
+ * @return this Method, to allow chaining
+ **/
+ public Method methodDesc(String desc) {
+ this.desc = desc;
+ return this;
+ }
+
+ /**
+ * Obtain the method description
+ *
+ * @return method description
+ **/
+ String methodDesc() {
+ return desc;
+ }
+
+ /**
+ * Describe a parameter of this method. This adds documentation
+ * that can be obtained through remote reflection.
+ *
+ * @return this Method, to allow chaining
+ * @param index the parameter index
+ * @param name the parameter name
+ * @param desc the parameter description
+ **/
+ public Method paramDesc(int index, String name, String desc) {
+ paramName[index] = name;
+ paramDesc[index] = desc;
+ return this;
+ }
+
+ /**
+ * Obtain the name of a parameter
+ *
+ * @return parameter name
+ * @param index parameter index
+ **/
+ String paramName(int index) {
+ return paramName[index];
+ }
+
+ /**
+ * Obtain the description of a parameter
+ *
+ * @return parameter description
+ * @param index parameter index
+ **/
+ String paramDesc(int index) {
+ return paramDesc[index];
+ }
+
+ /**
+ * Describe a return value of this method. This adds documentation
+ * that can be obtained through remote reflection.
+ *
+ * @return this Method, to allow chaining
+ * @param index the return value index
+ * @param name the return value name
+ * @param desc the return value description
+ **/
+ public Method returnDesc(int index, String name, String desc) {
+ returnName[index] = name;
+ returnDesc[index] = desc;
+ return this;
+ }
+
+ /**
+ * Obtain the name of a return value
+ *
+ * @return return value name
+ * @param index return value index
+ **/
+ String returnName(int index) {
+ return returnName[index];
+ }
+
+ /**
+ * Obtain the description of a return value
+ *
+ * @return return value description
+ * @param index return value index
+ **/
+ String returnDesc(int index) {
+ return returnDesc[index];
+ }
+
+ /**
+ * Check whether the parameters of the given request satisfies the
+ * parameters of this method.
+ *
+ * @return true if the parameters of the given request satisfies
+ * the parameters of this method
+ * @param req a request
+ **/
+ boolean checkParameters(Request req) {
+ return req.parameters().satisfies(paramTypes);
+ }
+
+ /**
+ * Check whether the return values of the given request satisfies
+ * the return values of this method.
+ *
+ * @return true if the return values of the given request satisfies
+ * the return values of this method
+ * @param req a request
+ **/
+ boolean checkReturnValues(Request req) {
+ return req.returnValues().satisfies(returnTypes);
+ }
+
+ /**
+ * Invoke this method. The given request holds the parameters and
+ * will be given as parameter to the handler method.
+ *
+ * @param req the request causing this invocation
+ **/
+ void invoke(Request req) {
+ try {
+ if (handler != null) {
+ handler.invoke(req);
+ } else {
+ Object[] args = { req };
+ method.invoke(object, args);
+ }
+ } catch (Exception e) {
+ req.setError(ErrorCode.METHOD_FAILED, e.toString());
+ }
+ }
+
+ public @Override String toString() {
+ return "method " + name + "(" + paramTypes + ")" + ( returnTypes.length()>0 ? ": " + returnTypes : "");
+ }
+
+}