org.opentestsystem.authoring.testspecbank.rest.TestSpecificationController.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.authoring.testspecbank.rest.TestSpecificationController.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System
 * Copyright (c) 2013 American Institutes for Research
 *
 * Distributed under the AIR Open Source License, Version 1.0
 * See accompanying file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 ******************************************************************************/
package org.opentestsystem.authoring.testspecbank.rest;

import org.opentestsystem.authoring.testspecbank.client.tib.ValidationErrorCode;
import org.opentestsystem.authoring.testspecbank.domain.ExportPackageStatus;
import org.opentestsystem.authoring.testspecbank.domain.Purpose;
import org.opentestsystem.authoring.testspecbank.domain.TestSpecification;
import org.opentestsystem.authoring.testspecbank.service.TestSpecificationService;
import org.opentestsystem.authoring.testspectbank.security.TenantEnforcementService;
import org.opentestsystem.shared.search.domain.SearchResponse;
import org.opentestsystem.shared.web.AbstractRestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import tds.common.ValidationError;
import tds.common.web.resources.NoContentResponseResource;

/**
 * process test specifications
 */
@Controller
@RequestMapping("/testSpecification")
public class TestSpecificationController extends AbstractRestController {

    @Autowired
    private TestSpecificationService testSpecificationService;

    @Autowired
    private TenantEnforcementService tenantEnforcementService;

    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Test Spec Admin" })
    @ResponseBody
    public TestSpecification saveTestSpecification(@RequestBody final TestSpecification testSpecification,
            final HttpServletResponse response) {
        tenantEnforcementService.enforceTenancyForObject(testSpecification,
                new String[] { "ROLE_Test Spec Admin" });
        return this.testSpecificationService.saveTestSpecification(testSpecification);
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{testSpecificationId}/updateTenantSet", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Test Spec Admin" })
    @ResponseBody
    public TestSpecification updateTenantSet(@PathVariable final String testSpecificationId,
            @RequestBody final Set<String> tenantSet, final HttpServletResponse response) {
        checkWriteAccessForTenant(testSpecificationId);
        return this.testSpecificationService.updateTenantSet(testSpecificationId, tenantSet);
    }

    @RequestMapping(value = "/{testSpecificationId}", method = RequestMethod.GET, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public TestSpecification getTestSpecification(@PathVariable final String testSpecificationId,
            @RequestParam(value = "excludeXml", required = false) final boolean excludeXml) {
        TestSpecification spec = this.testSpecificationService.getTestSpecification(testSpecificationId,
                excludeXml);
        tenantEnforcementService.verifyUserIsConfiguredToReadObjects(spec, "ROLE_Test Spec Read");
        return spec;
    }

    @RequestMapping(value = "/{testSpecificationId}/specXml", method = RequestMethod.GET)
    @Secured({ "ROLE_Test Spec Read" })
    public ResponseEntity<byte[]> getSpecificationXml(@PathVariable final String testSpecificationId,
            final HttpServletResponse response) {
        final TestSpecification spec = getTestSpecification(testSpecificationId, false);
        tenantEnforcementService.verifyUserIsConfiguredToReadObjects(spec, "ROLE_Test Spec Read");
        final HttpHeaders responseHeaders = buildResponseHeaders(spec.getSpecificationXml().length,
                "test_specification.xml");
        return new ResponseEntity<byte[]>(spec.getSpecificationXml(), responseHeaders, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public SearchResponse<TestSpecification> searchTestSpecification(
            @RequestParam(value = "includeXml", required = false) final boolean includeXml,
            final HttpServletRequest request, final HttpServletResponse response) {
        SearchResponse<TestSpecification> searchResponse = this.testSpecificationService
                .searchTestSpecifications(request.getParameterMap(), includeXml);
        tenantEnforcementService.verifyUserIsConfiguredToReadObjects(searchResponse, "ROLE_Test Spec Read");
        return searchResponse;
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{testSpecificationId}/retire", method = RequestMethod.PUT, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Admin" })
    @ResponseBody
    public TestSpecification retireTestSpecification(@PathVariable final String testSpecificationId,
            @RequestParam(value = "undoRetirement", required = false) final boolean undoRetirement) {
        checkWriteAccessForTenant(testSpecificationId);
        return this.testSpecificationService.retireTestSpecification(testSpecificationId, undoRetirement);
    }

    @ResponseStatus(HttpStatus.NO_CONTENT)
    @RequestMapping(value = "/{testSpecificationName}", method = RequestMethod.DELETE, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    // @Secured({ "ROLE_Test Spec Admin" })
    @ResponseBody
    public ResponseEntity<NoContentResponseResource> deleteTestSpecification(
            @PathVariable final String testSpecificationName) {
        final Optional<ValidationError> maybeError = testSpecificationService
                .deleteTestSpecification(testSpecificationName);
        if (maybeError.isPresent()) {
            final ValidationError error = maybeError.get();
            final HttpStatus httpStatus = error.getCode().equalsIgnoreCase(
                    ValidationErrorCode.TEST_SPECIFICATION_NOT_FOUND) ? HttpStatus.UNPROCESSABLE_ENTITY
                            : HttpStatus.INTERNAL_SERVER_ERROR;

            return new ResponseEntity<>(new NoContentResponseResource(error), httpStatus);
        }

        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/isAdminUser", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public boolean isAdminUser() {
        return this.testSpecificationService.isAdminUser();
    }

    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "/{testSpecificationId}/exportPackage", method = RequestMethod.POST, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public TestSpecification requestExportPackage(@PathVariable final String testSpecificationId) {
        checkReadAccessForTenant(testSpecificationId);
        return this.testSpecificationService.requestExportPackage(testSpecificationId);
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{testSpecificationId}/retryExportPackage", method = RequestMethod.PUT, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public TestSpecification retryExportPackage(@PathVariable final String testSpecificationId) {
        checkReadAccessForTenant(testSpecificationId);
        return this.testSpecificationService.retryExportPackage(testSpecificationId);
    }

    @RequestMapping(value = "/purpose", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public List<Purpose> getSpecificationPurposes() {
        return Arrays.asList(Purpose.values());
    }

    @RequestMapping(value = "/exportStatus", method = RequestMethod.GET, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Test Spec Read" })
    @ResponseBody
    public List<ExportPackageStatus> getExportStatuses() {
        return Arrays.asList(ExportPackageStatus.values());
    }

    private static HttpHeaders buildResponseHeaders(final int contentLength, final String filename) {
        final HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.clear();
        responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
        responseHeaders.setPragma("public");
        responseHeaders.setCacheControl("no-store, must-revalidate");
        responseHeaders.setExpires(Long.valueOf("-1"));
        responseHeaders.setContentDispositionFormData("inline", filename);
        responseHeaders.setContentLength(contentLength);
        responseHeaders.add(org.apache.http.HttpHeaders.ACCEPT_RANGES, "bytes");
        return responseHeaders;
    }

    private void checkReadAccessForTenant(final String testSpecId) {
        TestSpecification spec = testSpecificationService.getTestSpecification(testSpecId, true);
        tenantEnforcementService.verifyUserIsConfiguredToReadObjects(spec, "ROLE_Test Spec Read");
    }

    private void checkWriteAccessForTenant(final String testSpecId) {
        TestSpecification spec = testSpecificationService.getTestSpecification(testSpecId, true);
        tenantEnforcementService.enforceTenancyForObject(spec, new String[] { "ROLE_Test Spec Admin" });
    }

}