
io.lightlink.servlet.debug.DebugFacadesProxyServlet Maven / Gradle / Ivy
package io.lightlink.servlet.debug;
/*
* #%L
* lightlink-core
* %%
* Copyright (C) 2015 Vitaliy Shevchuk
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import io.lightlink.output.JSONHttpResponseStream;
import io.lightlink.output.ResponseStream;
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class DebugFacadesProxyServlet extends HttpServlet {
public static final Logger LOG = LoggerFactory.getLogger(DebugFacadesProxyServlet.class);
public DebugFacadesProxyServlet() {
int x = 0;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Map params = getJsonParamsMap(request);
ResponseStream json = new JSONHttpResponseStream(response);
dispatch(request, params, json);
} catch (Exception e) {
sendError(response, e);
}
}
void dispatch(HttpServletRequest request, Map params, ResponseStream json) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
if ("create".equals(params.get("action"))) {
create(params, json);
} else if ("createClass".equals(params.get("action"))) {
createClass(params, json);
} else if ("invoke".equals(params.get("action"))) {
invoke(request, params, json);
}
}
private void sendError(HttpServletResponse response, Exception e) throws IOException {
LOG.error(e.toString(), e);
ResponseStream json = new JSONHttpResponseStream(response);
json.writeProperty("exception", e.getClass().getName());
json.writeProperty("message", e.toString());
StringWriter traceWriter = new StringWriter(1024);
PrintWriter pw = new PrintWriter(traceWriter);
e.printStackTrace(pw);
pw.close();
json.writeProperty("stackTrace", traceWriter.toString());
json.end();
}
private void invoke(HttpServletRequest request, Map params, ResponseStream json) throws IllegalAccessException, InvocationTargetException, IOException {
String methodName = (String) params.get("methodName");
Integer objectId = ((Number) params.get("objectId")).intValue();
List args = (List) params.get("args");
replaceStubsByObjects(args);
ObjectPoolElement element = pool.get(objectId);
Object instance = element.getObject();
if (instance instanceof HttpServletRequest)
instance = request;
Class cls = (instance instanceof Class) ? (Class) instance : instance.getClass();
Method[] allMethods = cls.getMethods();
List sameName = new ArrayList();
for (Method method : allMethods) {
if (methodName.equals(method.getName()))
sameName.add(method);
}
Method[] methods = sameName.toArray(new Method[sameName.size()]);
MethodOrConstructorWrapper method = findMethod(args, MethodOrConstructorWrapper.getArray(methods));
if (method == null)
throw new RuntimeException("Cannot find method:" + methodName + " for class:" + cls + " wiht parameters: " + args);
Object resp = invokeMethod(args, instance, method.getMethod());
returnObject(resp, element.getGeneration(), json);
}
private Object invokeMethod(List args, Object instance, Method method) throws IllegalAccessException, InvocationTargetException {
Object[] argsArray = args.toArray();
Class>[] pTypes = method.getParameterTypes();
for (int i = 0; i < argsArray.length; i++) {
Object arg = argsArray[i];
if (arg instanceof Object[] && pTypes[i].equals(byte[].class)) {
Object[] argObjArray = (Object[]) arg;
byte[] bytes = new byte[argObjArray.length];
for (int j = 0; j < argObjArray.length; j++) {
bytes[j] = ((Number) argObjArray[j]).byteValue();
}
argsArray[i] = bytes;
}
if (arg instanceof Object[] && pTypes[i].equals(Iterable.class)) {
argsArray[i] = Arrays.asList((Object[]) arg);
}
}
return method.invoke(instance, argsArray);
}
private void createClass(Map params, ResponseStream json) throws ClassNotFoundException, IOException {
purgeGenerations();
String className = (String) params.get("className");
Long generation = new Long("" + params.get("generation"));
Class aClass = Class.forName(className);
returnObject(aClass, generation, json);
}
private void create(Map params, ResponseStream json) throws ClassNotFoundException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException, IOException {
String className = (String) params.get("className");
Long generation = new Long("" + params.get("generation"));
List args = (List) params.get("args");
replaceStubsByObjects(args);
Constructor[] candidates = Class.forName(className).getConstructors();
MethodOrConstructorWrapper constructor = findMethod(args, MethodOrConstructorWrapper.getArray(candidates));
if (constructor == null)
throw new RuntimeException("Cannot find constructor for class:" + className + " wiht parameters: " + args);
Object instance = constructor.getConstructor().newInstance(args.toArray());
returnObject(instance, generation, json);
}
private Map getJsonParamsMap(HttpServletRequest request) throws IOException {
ServletInputStream inputStream = request.getInputStream();
Map params;
try {
params = (Map) new JSONParser().parse(new InputStreamReader(inputStream, "UTF-8"));
} catch (ParseException e) {
throw new IllegalArgumentException(e.toString(), e);
}
inputStream.close();
return params;
}
// todo : send and receive Collections/Maps
private void returnObject(Object instance, Long generation, ResponseStream json) throws IOException {
writeGenericInstance(instance, generation, json);
json.end();
}
private void writeGenericInstance(Object instance, Long generation, ResponseStream json) throws IOException {
if (instance == null
|| instance instanceof String
|| instance instanceof Number
|| (
instance.getClass().isArray() &&
(instance.getClass().getComponentType().isPrimitive() ||
instance.getClass().getComponentType().isInstance(Number.class) ||
instance.getClass().getComponentType().isInstance(String.class)
))
) {
writeSimpleType(instance, json);
} else if (instance instanceof Map) {
writeArray((Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy