org.opentestsystem.authoring.testauth.rest.ScoringRuleController.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.authoring.testauth.rest.ScoringRuleController.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.testauth.rest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.opentestsystem.authoring.testauth.domain.BlueprintDenotationType;
import org.opentestsystem.authoring.testauth.domain.BlueprintElement;
import org.opentestsystem.authoring.testauth.domain.BlueprintReference;
import org.opentestsystem.authoring.testauth.domain.BlueprintReferenceType;
import org.opentestsystem.authoring.testauth.domain.ScoringRule;
import org.opentestsystem.authoring.testauth.service.ScoringRuleService;
import org.opentestsystem.authoring.testauth.validation.ScoringRuleValidator;
import org.opentestsystem.shared.exception.LocalizedException;
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.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
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 org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;

/**
 * Used to retrieve scoringRule info
 */
@Controller
public class ScoringRuleController extends AbstractRestController {

    @Autowired
    private ScoringRuleService scoringRuleService;

    @Autowired
    private ScoringRuleValidator scoringRuleValidator;

    @Autowired
    private ObjectMapper objectMapper;

    @InitBinder("scoringRule")
    public void initBinder(final WebDataBinder binder) {
        binder.setValidator(this.scoringRuleValidator);
    }

    @RequestMapping(value = "/scoringRule/{scoringRuleId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Read" })
    @PostAuthorize("hasPermission(returnObject, 'ROLE_Scoring Rule Read')")
    @ResponseBody
    public ScoringRule findScoringRuleById(@PathVariable final String scoringRuleId) {
        return this.scoringRuleService.getScoringRule(scoringRuleId);
    }

    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "/scoringRule", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Scoring Rule Modify" })
    @PreAuthorize("hasPermission(#ScoringRule, 'ROLE_Scoring Rule Modify')")
    @ResponseBody
    public ScoringRule saveScoringRule(@RequestBody @Valid final ScoringRule scoringRule,
            final HttpServletResponse response) {
        return this.scoringRuleService.saveScoringRule(null, scoringRule);
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/scoringRule/{scoringRuleId}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Scoring Rule Modify" })
    @PreAuthorize("hasPermission(#ScoringRule, 'ROLE_Scoring Rule Modify')")
    @ResponseBody
    public ScoringRule updateScoringRule(@PathVariable final String scoringRuleId,
            @RequestBody @Valid final ScoringRule scoringRule, final HttpServletResponse response) {
        return this.scoringRuleService.saveScoringRule(scoringRuleId, scoringRule);
    }

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/scoringRule", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Modify" })
    @PreAuthorize("hasPermission(#scoringRuleList, 'ROLE_Scoring Rule Modify')")
    @ResponseBody
    public List<ScoringRule> updateScoringRuleList(@RequestBody final List<ScoringRule> scoringRuleList) {
        return this.scoringRuleService.saveScoringRuleList(scoringRuleList, true);
    }

    @RequestMapping(value = "/scoringRule/{scoringRuleId}", method = RequestMethod.DELETE)
    @Secured({ "ROLE_Scoring Rule Modify" })
    @PreAuthorize("hasPermission(#scoringRuleId, 'scoringRule', 'ROLE_Scoring Rule Modify')")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void removeScoringRuleById(@PathVariable final String scoringRuleId) {
        this.scoringRuleService.removeScoringRule(scoringRuleId);
    }

    @RequestMapping(value = "/scoringRule", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Read" })
    @PostAuthorize("hasPermission(returnObject, 'ROLE_Scoring Rule Read')")
    @ResponseBody
    public SearchResponse<ScoringRule> searchScoringRule(final HttpServletRequest request,
            final HttpServletResponse response) {
        return this.scoringRuleService.searchScoringRules(request.getParameterMap());
    }

    @RequestMapping(value = "/scoringRule/blueprintReferenceTypes", method = RequestMethod.GET, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Scoring Rule Read" })
    // NOTE: there is intentionally no @PreAuthorize annotation...BlueprintReferenceTypes are non-tenanted
    @ResponseBody
    public List<BlueprintReferenceType> getBlueprintReferenceTypes() {
        return Lists.newArrayList(BlueprintReferenceType.values());
    }

    @RequestMapping(value = "/scoringRule/blueprintDenotationTypes", method = RequestMethod.GET, produces = {
            MediaType.APPLICATION_JSON_VALUE })
    @Secured({ "ROLE_Scoring Rule Read" })
    // NOTE: there is intentionally no @PreAuthorize annotation...BlueprintDenotationTypes are non-tenanted
    @ResponseBody
    public List<BlueprintDenotationType> getBlueprintDenotationTypes() {
        return Lists.newArrayList(BlueprintDenotationType.values());
    }

    @RequestMapping(value = "/scoringRule/activeBlueprintLevels/{assessmentId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Read" })
    @PostAuthorize("hasPermission(#assessmentId, 'assessment', 'ROLE_Scoring Rule Read')")
    @ResponseBody
    public Map<String, String> findDistinctActiveLevelsForAssessment(@PathVariable final String assessmentId,
            final HttpServletResponse response) {
        return this.scoringRuleService.findDistinctActiveBlueprintLevelsByAssessmentId(assessmentId);
    }

    @RequestMapping(value = "/scoringRule/blueprintElementsNotCovered/{assessmentId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Read" })
    @PostAuthorize("hasPermission(#assessmentId, 'assessment', 'ROLE_Scoring Rule Read')")
    @ResponseBody
    public List<BlueprintElement> findBlueprintElementsMissingScoringRule(@PathVariable final String assessmentId) {
        return this.scoringRuleService.findBlueprintElementsMissingScoringRule(assessmentId);
    }

    @RequestMapping(value = "/scoringRule/conversionTableFile/{fileGridId}", method = RequestMethod.GET)
    @Secured({ "ROLE_Scoring Rule Read" })
    // NOTE: there is intentionally no @PreAuthorize annotation...ability to read scoring rule is all that is needed since scoring rule conversion table files are non-tenanted
    public ResponseEntity<byte[]> getConversionTableFile(@PathVariable final String fileGridId,
            final HttpServletResponse response) {
        final ByteArrayOutputStream ret = new ByteArrayOutputStream();
        String filename = null;
        try {
            final GridFSDBFile grid = this.scoringRuleService.getConversionTableFile(fileGridId);
            grid.writeTo(ret);
            filename = grid.getFilename();
            ret.flush();
        } catch (final IOException e) {
            throw new LocalizedException("scoringRule.conversionTableFile.notfound", new String[] { fileGridId },
                    e);
        }
        final byte[] bytes = ret.toByteArray();
        final HttpHeaders responseHeaders = buildResponseHeaders(bytes.length, filename);
        return new ResponseEntity<byte[]>(bytes, responseHeaders, HttpStatus.OK);
    }

    private HttpHeaders buildResponseHeaders(final int contentLength, final String filename) {
        final HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.clear();
        responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE,
                com.google.common.net.MediaType.CSV_UTF_8.toString());
        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;
    }

    @ResponseStatus(HttpStatus.CREATED)
    @RequestMapping(value = "/scoringRule/conversionTableFile/{type}", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)
    @Secured({ "ROLE_Scoring Rule Modify" })
    // NOTE: there is intentionally no @PreAuthorize annotation...ability to modify scoring rule is all that is needed since scoring rule conversion table files are non-tenanted
    @ResponseBody
    public String uploadConversionTableFile(
            @RequestParam("conversionTableFile") final MultipartFile conversionTableFile,
            @PathVariable("type") final String type, final HttpServletRequest request,
            final HttpServletResponse response) throws IOException {
        String jsonAsStringForIE = null;
        try {
            final GridFSFile savedFile = this.scoringRuleService.saveConversionTableFile(type,
                    conversionTableFile.getOriginalFilename(), conversionTableFile.getBytes(),
                    conversionTableFile.getContentType());
            jsonAsStringForIE = savedFile.toString();
        } catch (final LocalizedException e) {
            // return a 201 here -
            // IE9 and browsers which require iframe transport must receive an OK status to get the response result after file upload
            jsonAsStringForIE = this.objectMapper.writeValueAsString(super.handleException(e));
        } catch (final IOException e) {
            // return a 201 here -
            // IE9 and browsers which require iframe transport must receive an OK status to get the response result after file upload
            jsonAsStringForIE = this.objectMapper.writeValueAsString(super.handleException(e));
        }

        return jsonAsStringForIE;
    }

    @ResponseStatus(HttpStatus.NO_CONTENT)
    @RequestMapping(value = "/scoringRule/conversionTableFile/{fileGridId}", method = RequestMethod.DELETE)
    @Secured({ "ROLE_Scoring Rule Modify" })
    // NOTE: there is intentionally no @PreAuthorize annotation...ability to modify scoring rule is all that is needed since scoring rule conversion table files are non-tenanted
    public void deleteConversionTableFile(@PathVariable final String fileGridId, final HttpServletResponse response)
            throws IOException {
        this.scoringRuleService.deleteConversionTableFile(fileGridId);
    }

    @RequestMapping(value = "/scoringRule/blueprintReferences", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @Secured({ "ROLE_Scoring Rule Read" })
    @PostAuthorize("hasPermission(returnObject, 'ROLE_Scoring Rule Read')")
    @ResponseBody
    public List<BlueprintReference> searchBlueprintReferences(final HttpServletRequest request,
            final HttpServletResponse response) {
        return this.scoringRuleService.getBlueprintReferences(request.getParameterMap());
    }
}