CallsController.java
package org.genesys.server.brapi;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.genesys.brapi.model.BrAPIPage;
import org.genesys.brapi.model.BrAPIResponse;
import org.genesys.brapi.model.Call;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
@Controller("brapiCalls")
@RequestMapping(value = { "/brapi/v1" })
@Slf4j
public class CallsController implements InitializingBean {
private static final RequestMethod[] GET_MAPPING = { RequestMethod.GET };
private static final RequestMethod[] POST_MAPPING = { RequestMethod.POST };
private static final RequestMethod[] PUT_MAPPING = { RequestMethod.PUT };
private static final RequestMethod[] DELETE_MAPPING = { RequestMethod.DELETE };
private List<Call> supportedCalls;
@Override
public void afterPropertiesSet() throws Exception {
// Scan the org.genesys.server.brapi package for @Controller annotations
supportedCalls = new ArrayList<>();
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Controller.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
for (BeanDefinition bd : scanner.findCandidateComponents("org.genesys.server.brapi")) {
registerBrAPIMethods(bd);
}
supportedCalls.forEach(call -> {
log.debug("BrAPI v1.3 call: /brapi/v1/{}", call);
});
}
private void registerBrAPIMethods(BeanDefinition bd) throws ClassNotFoundException {
Class<?> clazz = Class.forName(bd.getBeanClassName());
String apiPrefix = "";
if (clazz.isAnnotationPresent(RequestMapping.class)) {
RequestMapping mapping = clazz.getAnnotation(RequestMapping.class);
apiPrefix = mapping.value()[0];
} else if (clazz.isAnnotationPresent(RestController.class)) {
RestController mapping = clazz.getAnnotation(RestController.class);
apiPrefix = mapping.value();
}
for (Method m : clazz.getDeclaredMethods()) {
registerBrAPIMethod(apiPrefix, m);
}
}
private void registerBrAPIMethod(String apiPrefix, Method m) {
if (m.isAnnotationPresent(RequestMapping.class)) {
RequestMapping mapping = m.getAnnotation(RequestMapping.class);
supportedCalls.add(new Call(apiPrefix, mapping.value()[0], mapping.method(), mapping.produces()));
} else if (m.isAnnotationPresent(GetMapping.class)) {
GetMapping mapping = m.getAnnotation(GetMapping.class);
supportedCalls.add(new Call(apiPrefix, mapping.value()[0], GET_MAPPING, mapping.produces()));
} else if (m.isAnnotationPresent(PostMapping.class)) {
PostMapping mappng = m.getAnnotation(PostMapping.class);
supportedCalls.add(new Call(apiPrefix, mappng.value()[0], POST_MAPPING, mappng.produces()));
} else if (m.isAnnotationPresent(DeleteMapping.class)) {
DeleteMapping mappng = m.getAnnotation(DeleteMapping.class);
supportedCalls.add(new Call(apiPrefix, mappng.value()[0], DELETE_MAPPING, mappng.produces()));
} else if (m.isAnnotationPresent(DeleteMapping.class)) {
PutMapping mappng = m.getAnnotation(PutMapping.class);
supportedCalls.add(new Call(apiPrefix, mappng.value()[0], PUT_MAPPING, mappng.produces()));
}
}
@RequestMapping(value = "/calls", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody BrAPIResponse<Call> brapiCalls(final BrAPIPage page) {
Pageable pageable = page.toPageRequest();
Page<Call> callsPage = new PageImpl<>(callsPage(pageable), pageable, supportedCalls.size());
return new BrAPIResponse<>(callsPage);
}
private List<Call> callsPage(Pageable page) {
if (page.getOffset() >= supportedCalls.size()) {
return Collections.emptyList();
}
return supportedCalls.subList((int) page.getOffset(), Math.min(supportedCalls.size(), (int) page.getOffset() + page.getPageSize()));
}
}