All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jexxa.drivingadapter.rest.RESTfulRPCConvention Maven / Gradle / Ivy

The newest version!
package io.jexxa.drivingadapter.rest;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;


/**
 * This class generates uniform IDs (URIs) for resources to be offered via REST
 * using a convention over configuration approach:
 * 
* Used conventions for URI: *
* {@code URI: http://://} *
* Example URI: http://localhost:7500/MyApplicationService/myMethod *
* This implies the following conventions: *
    *
  • Simple name of a class must be unique within a single application
  • *
  • Each class must have unique method names. Any method overloading is not supported
  • *
  • Methods from base class `Object` are ignored
  • *
* GET - mapping: *
*
    *
  • If a method returns a type != 'void' and has no arguments then it is mapped to a GET method
  • *
*
* POST - mapping: *
    *
  • In all other cases
  • *
*/ class RESTfulRPCConvention { private final Object object; RESTfulRPCConvention(Object object) { this.object = object; validateUniqueURI(); } record RESTfulRPCMethod(RESTfulRPCConvention.RESTfulRPCMethod.HTTPCommand httpCommand, String resourcePath, Method method) { enum HTTPCommand {GET, POST} HTTPCommand getHTTPCommand() { return httpCommand; } } List getGETCommands() { return getPublicMethods(object.getClass()) .stream() .filter(element -> !Modifier.isStatic(element.getModifiers())) //Convention for all exposed methods .filter(element -> !(element.getReturnType().equals(void.class)) && element.getParameterCount() == 0) // Convention for GET method .map(element -> new RESTfulRPCMethod( RESTfulRPCMethod.HTTPCommand.GET, generateURI(element), element)) .toList(); } List getPOSTCommands() { return getPublicMethods(object.getClass()) .stream() .filter(element -> !Modifier.isStatic(element.getModifiers())) //Convention for all exposed methods .filter(element -> (element.getReturnType().equals(void.class) || element.getParameterCount() > 0)) // Convention for POST method .map(element -> new RESTfulRPCMethod( RESTfulRPCMethod.HTTPCommand.POST, generateURI(element), element)) .toList(); } private String generateURI(Method method) { return "/" + method.getDeclaringClass().getSimpleName() + "/" + method.getName(); } private List getPublicMethods(Class clazz) { List result = new ArrayList<>(Arrays.asList(clazz.getMethods())); result.removeAll(Arrays.asList(Object.class.getMethods())); return result; } private void validateUniqueURI() { List publicMethods = getPublicMethods(object.getClass()); List methodNames = new ArrayList<>(); publicMethods.forEach(element -> methodNames.add(generateURI(element))); // Make a unique list (by converting it into a HashSet) and compare its size with size of publicMethods. // If it is not equal, URIs are not unique List uniqueNames = new ArrayList<>( new HashSet<>(methodNames) ); if (uniqueNames.size() != methodNames.size() ) { throw new IllegalArgumentException("Method names are not unique of Object " + object.getClass().getSimpleName()); } } public static RESTfulRPCConvention createRPCConvention(Object object) { return new RESTfulRPCConvention(object); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy