package no.niths.application.rest.school;
import no.niths.application.rest.AbstractRESTControllerImpl;
import no.niths.application.rest.RESTConstants;
import no.niths.application.rest.exception.QRCodeException;
import no.niths.application.rest.helper.QRCodeDecoder;
import no.niths.application.rest.lists.ListAdapter;
import no.niths.application.rest.lists.school.FadderGroupList;
import no.niths.application.rest.lists.school.StudentList;
import no.niths.application.rest.school.interfaces.FadderGroupController;
import no.niths.common.constants.DomainConstantNames;
import no.niths.common.constants.SecurityConstants;
import no.niths.common.helpers.LazyFixer;
import no.niths.common.helpers.ValidationHelper;
import no.niths.domain.school.FadderGroup;
import no.niths.domain.school.Student;
import no.niths.services.interfaces.GenericService;
import no.niths.services.school.interfaces.FadderGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Controller for FadderGroup
* has the basic CRUD methods and
* methods too add and remove leader, child
* and children and remove all leaders and children
* in addition too methods for getAllStudentsNotInAGroup,
* getAllStudents and scanImage
* <p/>
* For the URL too get FadderGroup add /fadder
* after the {@value no.niths.common.constants.MiscConstants#NITHS_BASE_DOMAIN}
*/
@Controller
@RequestMapping(DomainConstantNames.FADDER)
public class FadderGroupControllerImpl extends
AbstractRESTControllerImpl<FadderGroup> implements
FadderGroupController {
@Autowired
private FadderGroupService service;
private FadderGroupList fadderGroupList = new FadderGroupList();
private StudentList studentList = new StudentList();
private LazyFixer<Student> lazyFixertStudent = new LazyFixer<Student>();
/**
* {@inheritDoc}
* <p/>
* Without nullifier
*/
@Override
public void renewList(List<FadderGroup> list) {
getList().clear();
getList().addAll(list);
getList().setData(getList()); // Used for XML marshaling
ValidationHelper.isListEmpty(getList());
}
@Override
@PreAuthorize(SecurityConstants.ADMIN_AND_SR_AND_STUDENT)
@RequestMapping(method = RequestMethod.GET, headers = RESTConstants.ACCEPT_HEADER)
@ResponseBody
public ArrayList<FadderGroup> getAll(FadderGroup domain) {
renewList(service.getAll(domain));
customLazyFixer();
return fadderGroupList;
}
/**
* This method is setting fadder children to null and
* removes fadder leaders children so a lazy exception is avoided
*/
private void customLazyFixer() {
for (FadderGroup fg : fadderGroupList) {
fg.setFadderChildren(null);
lazyFixertStudent.clearRelations(fg.getLeaders());
}
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(method = RequestMethod.POST, headers = RESTConstants.ACCEPT_HEADER)
@ResponseBody
public FadderGroup create(@RequestBody FadderGroup domain, HttpServletResponse res) {
return super.create(domain, res);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(method = RequestMethod.PUT)
public void update(@RequestBody FadderGroup domain) {
super.update(domain);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(method = RequestMethod.DELETE)
public void delete(@PathVariable long id) {
super.delete(id);
}
/**
* {@inheritDoc}
*/
@Override
public GenericService<FadderGroup> getService() {
return service;
}
/**
* {@inheritDoc}
*/
@Override
public ListAdapter<FadderGroup> getList() {
return fadderGroupList;
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = "{groupId}/leader/{studentId}",
method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK, reason = "Leader added")
public void addLeader(
@PathVariable Long groupId,
@PathVariable Long studentId) {
service.addLeader(groupId, studentId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = "{groupId}/leader/{studentId}",
method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK, reason = "Leader removed")
public void removeLeader(
@PathVariable Long groupId,
@PathVariable Long studentId) {
service.removeLeader(groupId, studentId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = "{groupId}/child/{studentId}",
method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK, reason = "Child added")
public void addChild(
@PathVariable Long groupId,
@PathVariable Long studentId) {
service.addChild(groupId, studentId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = {"{groupId}/children/{studentIds}"},
method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK, reason = "Children added")
public void addChildren(
@PathVariable Long groupId,
@PathVariable Long[] studentIds) {
service.addChildren(groupId, studentIds);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = "{groupId}/child/{studentId}",
method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK, reason = "Child removed")
public void removeChild(
@PathVariable Long groupId,
@PathVariable Long studentId) {
service.removeChild(groupId, studentId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = {"{groupId}/children/{studentIds}"},
method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK, reason = "Children removed")
public void removeChildren(
@PathVariable Long groupId,
@PathVariable Long[] studentIds) {
service.removeChildren(groupId, studentIds);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_SR_FADDER_LEADER)
@RequestMapping(
value = "{groupId}/children",
method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK, reason = "All children removed")
public void removeAllChildren(@PathVariable Long groupId) {
service.removeAllChildren(groupId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_AND_SR)
@RequestMapping(
value = "{groupId}/leaders",
method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK, reason = "All leaders removed")
public void removeAllLeaders(@PathVariable Long groupId) {
service.removeAllLeaders(groupId);
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_AND_SR_AND_STUDENT)
@RequestMapping(value = "{groupId}/children",
method = RequestMethod.GET,
headers = RESTConstants.ACCEPT_HEADER)
@ResponseBody
public List<Student> getAllStudents(@PathVariable Long groupId) {
// Clear the list as it is never newed up more than once.
studentList.clear();
FadderGroup fadderGroup = getGroup(groupId);
// Adds the current FadderGroups children to the list.
studentList.addAll(fadderGroup.getFadderChildren());
studentList.setData(studentList); // for XML marshalling
ValidationHelper.isListEmpty(studentList);
lazyFixertStudent.clearRelations(studentList);
return studentList;
}
/**
* {@inheritDoc}
*/
@Override
@PreAuthorize(SecurityConstants.ADMIN_AND_SR_AND_STUDENT)
@RequestMapping(value = "groupless",
method = RequestMethod.GET,
headers = RESTConstants.ACCEPT_HEADER)
@ResponseBody
public List<Student> getAllStudentsNotInAGroup() {
// Clear the list as it is never newed up more than once.
studentList.clear();
// Adds the current students to the list.
studentList.addAll(service.getStudentsNotInAGroup());
studentList.setData(studentList); // for XML marshalling
ValidationHelper.isListEmpty(studentList);
lazyFixertStudent.clearRelations(studentList);
return studentList;
}
/**
* {@inheritDoc}
*/
@Override
@RequestMapping(
value = "scan-qr-code/{studentId}",
method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK, reason = "Added to group")
public void scanImage(
@PathVariable Long studentId,
HttpServletRequest req,
HttpServletResponse response)
throws QRCodeException {
if (req instanceof MultipartHttpServletRequest) {
Map<String, MultipartFile> files =
((MultipartHttpServletRequest) req)
.getFileMap();
// Iterate over maps like a boss
for (Map.Entry<String, MultipartFile> entry : files.entrySet()) {
CommonsMultipartFile file = (CommonsMultipartFile) entry
.getValue();
Long groupId = new QRCodeDecoder().decodeFadderGroupQRCode(
file.getBytes());
// Add the student to the group,
// will throw exceptions if group/student does not exist
// or student is already added
service.addChild(groupId, studentId);
response.setHeader("group", groupId + "");
}
}
}
@ExceptionHandler(QRCodeException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Scan failed")
public void catchNotFoundException(QRCodeException e,
HttpServletResponse response) {
response.setHeader(ERROR, e.getMessage());
}
private FadderGroup getGroup(Long groupId) {
FadderGroup group = super.getById(groupId);
ValidationHelper.isObjectNull(group, FadderGroup.class);
return group;
}
}