package api;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.LinkRelationProvider;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.ImmutableList;
import resources.IndexResource;
import util.SuppressFBWarnings;
@RestController
@RequestMapping(value = ApiRestController.API_MAPPING)
public class ApiRestController {
protected final Logger logger = LoggerFactory.getLogger(getClass());
public static final String API_MAPPING = "/api";
private static final Pattern ADMIN_REL_PREFIX_PATTERN = Pattern.compile("admin:", Pattern.LITERAL);
private static final Pattern ADMIN_REL_QUERY_BUILDER_FORM_PATTERN = Pattern.compile("query-builder-form", Pattern.LITERAL);
protected static final Comparator ADMIN_LINK_REL_COMPARATOR = Comparator.comparing(link -> link.getRel().value(), (rel1, rel2) -> {
rel1 = ADMIN_REL_PREFIX_PATTERN.matcher(rel1).replaceFirst("");
rel1 = ADMIN_REL_QUERY_BUILDER_FORM_PATTERN.matcher(rel1).replaceFirst("");
rel2 = ADMIN_REL_PREFIX_PATTERN.matcher(rel2).replaceFirst("");
rel2 = ADMIN_REL_QUERY_BUILDER_FORM_PATTERN.matcher(rel2).replaceFirst("");
return rel1.compareTo(rel2);
});
private final WebInvocationPrivilegeEvaluator webPrivilegeEvaluator;
private final List adminRestControllers;
@Autowired
public ApiRestController(LinkRelationProvider rels,
WebInvocationPrivilegeEvaluator webPrivilegeEvaluator,
List adminRestControllers) {
this.webPrivilegeEvaluator = webPrivilegeEvaluator;
this.adminRestControllers = adminRestControllers;
}
@RequestMapping(value = "", method = RequestMethod.GET, produces = {"application/hal+json", "application/json"})
public ResponseEntity api() {
IndexResource resource = new IndexResource("index", null);
resource.add(linkTo(ApiRestController.class).withSelfRel());
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
ImmutableList.Builder adminResourceLinks = ImmutableList.builder();
for (ApiRootAdminRestController adminRestController : adminRestControllers) {
if (webPrivilegeEvaluator.isAllowed(adminRestController.apiRootMapping(), authentication)) {
adminRestController.queryBuilderFormLink().ifPresent(link -> adminResourceLinks.add(link));
adminRestController.templatedLinkToItemPermalink().ifPresent(link -> adminResourceLinks.add(link));
adminResourceLinks.addAll(adminRestController.miscRootLinks());
}
}
adminResourceLinks.add(linkToTranslations());
resource.add(ImmutableList.sortedCopyOf(
ADMIN_LINK_REL_COMPARATOR,
adminResourceLinks.build())
);
return new ResponseEntity<>(resource, HttpStatus.OK);
}
@SuppressWarnings("null")
@SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "Not a real method call")
private Link linkToTranslations() {
return linkTo(methodOn(JsonTranslationController.class).get(null, null, null)).withRel(LinkRelation.of("translate"));
}
}