org.json.other.server.Base64JsonRpcExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsonrpc Show documentation
Show all versions of jsonrpc Show documentation
jsonrpc is a lightweight Rpc Framework
/*
* Copyright (C) 2011 ritwik.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.json.other.server;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.openyelp.cache.RpcCache;
import com.openyelp.commons.AllowAllTypeChecker;
import com.openyelp.commons.JsonRpcErrorCodes;
import com.openyelp.commons.JsonRpcException;
import com.openyelp.commons.JsonRpcRemoteException;
import com.openyelp.commons.RpcIntroSpection;
import com.openyelp.commons.TypeChecker;
import com.openyelp.server.HandleEntry;
import com.openyelp.server.JsonRpcServerTransport;
public final class Base64JsonRpcExecutor implements RpcIntroSpection {
private static final Pattern METHOD_PATTERN = Pattern
.compile("([_a-zA-Z][_a-zA-Z0-9]*)\\.([_a-zA-Z][_a-zA-Z0-9]*)");
private final Map> handlers;
private final TypeChecker typeChecker;
private volatile boolean locked;
public Base64JsonRpcExecutor() {
this(new AllowAllTypeChecker());
}
@SuppressWarnings("unchecked")
public Base64JsonRpcExecutor(TypeChecker typeChecker) {
this.typeChecker = typeChecker;
this.handlers = new HashMap>();
addHandler("system", this, RpcIntroSpection.class);
}
public boolean isLocked() {
return locked;
}
public void addHandler(String name, T handler, Class... classes) {
if (locked) {
throw new JsonRpcException("executor has been locked, can't add more handlers");
}
synchronized (handlers) {
HandleEntry handleEntry = new HandleEntry(typeChecker, handler, classes);
if (this.handlers.containsKey(name)) {
throw new IllegalArgumentException("handler already exists");
}
this.handlers.put(name, handleEntry);
}
}
public void execute(JsonRpcServerTransport transport) {
if (!locked) {
synchronized (handlers) {
locked = true;
}
}
String methodName = null;
JsonArray params = null;
JsonObject resp = new JsonObject();
resp.addProperty("jsonrpc", "2.0");
String errorMessage = null;
Integer errorCode = null;
String errorData = null;
JsonObject req = null;
try {
String requestData = transport.readRequest();
JsonParser parser = new JsonParser();
req = (JsonObject) parser.parse(new StringReader(requestData));
} catch (Throwable t) {
errorCode = JsonRpcErrorCodes.PARSE_ERROR_CODE;
errorMessage = "unable to parse json-rpc request";
errorData = getStackTrace(t);
sendError(transport, resp, errorCode, errorMessage, errorData);
return;
}
try {
assert req != null;
resp.add("id", req.get("id"));
methodName = req.getAsJsonPrimitive("method").getAsString();
params = (JsonArray) req.get("params");
if (params == null) {
params = new JsonArray();
}
} catch (Throwable t) {
errorCode = JsonRpcErrorCodes.INVALID_REQUEST_ERROR_CODE;
errorMessage = "unable to read request";
errorData = getStackTrace(t);
sendError(transport, resp, errorCode, errorMessage, errorData);
return;
}
try {
JsonElement result = executeMethod(methodName, params);
resp.add("result", result);
} catch (Throwable t) {
if (t instanceof JsonRpcRemoteException) {
sendError(transport, resp, (JsonRpcRemoteException) t);
return;
}
errorCode = JsonRpcErrorCodes.getServerError(1);
errorMessage = t.getMessage();
errorData = getStackTrace(t);
sendError(transport, resp, errorCode, errorMessage, errorData);
return;
}
try {
String responseData = resp.toString();
transport.writeResponse(responseData);
} catch (Exception e) {
}
}
private void sendError(JsonRpcServerTransport transport, JsonObject resp, JsonRpcRemoteException e) {
sendError(transport, resp, e.getCode(), e.getMessage(), e.getData());
}
private void sendError(JsonRpcServerTransport transport, JsonObject resp, Integer code, String message, String data) {
JsonObject error = new JsonObject();
if (code != null) {
error.addProperty("code", code);
}
if (message != null) {
error.addProperty("message", message);
}
if (data != null) {
error.addProperty("data", data);
}
resp.add("error", error);
resp.remove("result");
String responseData = resp.toString();
try {
transport.writeResponse(responseData);
} catch (Exception e) {
e.printStackTrace();
}
}
private String getStackTrace(Throwable t) {
StringWriter str = new StringWriter();
PrintWriter w = new PrintWriter(str);
t.printStackTrace(w);
w.close();
return str.toString();
}
private JsonElement executeMethod(String methodName, JsonArray params) throws Throwable {
try {
Matcher mat = METHOD_PATTERN.matcher(methodName);
if (!mat.find()) {
throw new JsonRpcRemoteException(JsonRpcErrorCodes.INVALID_REQUEST_ERROR_CODE, "invalid method name", null);
}
String handleName = mat.group(1);
methodName = mat.group(2);
HandleEntry> handleEntry = handlers.get(handleName);
if (handleEntry == null) {
throw new JsonRpcRemoteException(JsonRpcErrorCodes.METHOD_NOT_FOUND_ERROR_CODE, "no such method exists", null);
}
Method executableMethod = null;
for (Method m : handleEntry.getMethods()) {
if (!m.getName().equals(methodName)) {
continue;
}
if (canExecute(m, params)) {
executableMethod = m;
break;
}
}
if (executableMethod == null) {
throw new JsonRpcRemoteException(JsonRpcErrorCodes.METHOD_NOT_FOUND_ERROR_CODE, "no such method exists", null);
}
Object result = executableMethod.invoke(
handleEntry.getHandler(), getParameters(executableMethod, params));
return new Gson().toJsonTree(result);
} catch (Throwable t) {
if (t instanceof InvocationTargetException) {
t = ((InvocationTargetException) t).getTargetException();
}
if (t instanceof JsonRpcRemoteException) {
throw (JsonRpcRemoteException) t;
}
throw new JsonRpcRemoteException(JsonRpcErrorCodes.getServerError(0), t.getMessage(), getStackTrace(t));
}
}
public boolean canExecute(Method method, JsonArray params) {
if (method.getParameterTypes().length != params.size()) {
return false;
}
return true;
}
public Object[] getParameters(Method method, JsonArray params) {
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy