
net.sf.jstuff.integration.json.SMDServiceExporter Maven / Gradle / Ivy
/*
* Copyright 2010-2022 by Sebastian Thomschke and contributors.
* SPDX-License-Identifier: EPL-2.0
*/
package net.sf.jstuff.integration.json;
import static net.sf.jstuff.core.collection.CollectionUtils.*;
import static net.sf.jstuff.core.validation.NullAnalysisHelper.*;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.remoting.support.RemoteExporter;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.util.NestedServletException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import net.sf.jstuff.core.logging.Logger;
import net.sf.jstuff.core.reflection.Methods;
import net.sf.jstuff.integration.spring.SpringBeanParanamer;
/**
* JSON-RPC Standard Method Definition
*
* https://dojotoolkit.org/reference-guide/1.10/dojox/rpc/smd.html
* https://dojotoolkit.org/reference-guide/1.10/dojox/rpc/SMDLibrary.html
*
* @author Sebastian Thomschke
*/
public class SMDServiceExporter extends RemoteExporter implements HttpRequestHandler, InitializingBean {
private static final Logger LOG = Logger.create();
private static final ObjectMapper JSON = new ObjectMapper();
private static final ObjectWriter JSON_PRETTY_WRITER = JSON.writerWithDefaultPrettyPrinter();
public static Map buildExportedMethodsByName(final Class> serviceInterface) {
final var methodsByMethodName = new TreeMap();
final var parameterTypesByMethodName = new HashMap[]>();
// loop through the service interface and all super interfaces to collect the public methods
Class> clazz = serviceInterface;
while (clazz != null) {
// retrieve the public methods
final Method[] publicMethods = serviceInterface.getMethods();
for (final Method method : publicMethods) {
final String name = method.getName();
if (methodsByMethodName.containsKey(name)) {
final Class>[] currentMethodParamTypes = method.getParameterTypes();
final Class>[] registeredMethodParamTypes = parameterTypesByMethodName.get(name);
if (!Arrays.equals(currentMethodParamTypes, registeredMethodParamTypes))
throw new IllegalStateException("Method overloading is not supported");
} else {
methodsByMethodName.put(name, method);
parameterTypesByMethodName.put(name, method.getParameterTypes());
}
}
clazz = clazz.getSuperclass();
}
return methodsByMethodName;
}
/**
* JSON RPC1 Simple Method Description builder
*
* see http://dojo.jot.com/SMD
* see http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book9
*/
@SuppressWarnings("deprecation")
public static String buildSMDTemplate(final Class> serviceInterface, final Object service,
final Map exportedMethodsByName, final boolean pretty) throws JsonProcessingException {
// build the method descriptors
final var methodDescriptions = new LinkedHashMap();
for (final Method method : exportedMethodsByName.values()) {
final var methodDescriptor = new LinkedHashMap();
if (method.getParameterTypes().length > 0) {
// for some reason parameter names are not preserved in interfaces, therefore we look them up in the service implementing class instead
final String[] names = SpringBeanParanamer.getParameterNames(method, service);
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy