au.com.ors.rest.controller.JobAppController.java Source code

Java tutorial

Introduction

Here is the source code for au.com.ors.rest.controller.JobAppController.java

Source

package au.com.ors.rest.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.xml.transform.TransformerException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
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 au.com.ors.rest.bean.JobApplication;
import au.com.ors.rest.bean.JobPosting;
import au.com.ors.rest.bean.RESTError;
import au.com.ors.rest.commons.DAOErrorCode;
import au.com.ors.rest.commons.JobAppStatus;
import au.com.ors.rest.commons.RESTErrorCode;
import au.com.ors.rest.dao.JobAppDAO;
import au.com.ors.rest.dao.JobPostingDAO;
import au.com.ors.rest.exceptions.DAOException;
import au.com.ors.rest.exceptions.JobAppMalformatException;
import au.com.ors.rest.exceptions.JobAppStatusCannotModifyException;
import au.com.ors.rest.exceptions.JobApplicationNotFoundException;
import au.com.ors.rest.resource.JobApplicationResource;
import au.com.ors.rest.resource.assembler.JobApplicationResourceAssembler;

/**
 * Job application resource controller<br/>
 * 
 * @author hansmong
 *
 */
@Controller
@RequestMapping("/jobapplications")
public class JobAppController {
    @Autowired
    JobAppDAO jobAppDao;

    @Autowired
    JobPostingDAO jobDao;

    @Autowired
    JobApplicationResourceAssembler appResourceAssembler;

    /*************************************************************************************
     * GET methods
     *************************************************************************************/

    /**
     * Get job applications<br/>
     * If a job ID is not given, the method will get all applications<br/>
     * Otherwise it will get the applications which point to the job with job ID<br/>
     * 
     * @param _jobId
     *            job ID
     * @return applications list
     */
    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<List<JobApplicationResource>> jobApplications(
            @RequestParam(name = "_jobId", required = false) String _jobId,
            @RequestParam(name = "status", required = false) String status) {
        List<JobApplication> appsList = new ArrayList<>();
        System.out.println("status=" + status);
        if (!StringUtils.isEmpty(_jobId) && !StringUtils.isEmpty(status)) { // by
            // two
            // factors
            System.out.println("getting according to two factors, jobappdao=" + (jobAppDao == null));
            List<JobApplication> appsByJobIdList = jobAppDao.findByJobPostingId(_jobId);
            if (appsByJobIdList != null) {

                for (JobApplication app : appsByJobIdList) {
                    System.out.println("found appsbyjobid size: " + appsByJobIdList.size());
                    System.out.println("appstatus=" + app.getStatus());
                    System.out.println("hooray!");
                    if (app.getStatus().equals(status)) {
                        appsList.add(app);
                    }
                }
            }
        } else if (!StringUtils.isEmpty(_jobId)) {
            appsList = jobAppDao.findByJobPostingId(_jobId);
        } else if (!StringUtils.isEmpty(status)) {
            appsList = jobAppDao.findByStatus(status);
        } else {
            appsList = jobAppDao.findAll();
        }

        if (appsList == null) {
            appsList = new ArrayList<>();
        }

        System.out.println("appsList size: " + appsList.size());

        List<JobApplicationResource> appListResource = appResourceAssembler.toResources(appsList);
        return new ResponseEntity<List<JobApplicationResource>>(appListResource, HttpStatus.OK);
    }

    /**
     * Get application by _appId<br/>
     * 
     * @param _appId
     *            application Id
     * @return a HATEOAS job application
     * @throws JobApplicationNotFoundException
     */
    @RequestMapping(value = "/{_appId}", method = RequestMethod.GET)
    public ResponseEntity<JobApplicationResource> jobAppById(@PathVariable(value = "_appId") String _appId)
            throws JobApplicationNotFoundException {
        JobApplication application = jobAppDao.findById(_appId);

        if (application == null) {
            throw new JobApplicationNotFoundException(
                    "Application with _appid=" + _appId + " not found in database.");
        }

        JobApplicationResource appResource = appResourceAssembler.toResource(application);

        return new ResponseEntity<JobApplicationResource>(appResource, HttpStatus.OK);
    }

    /*************************************************************************************
     * POST methods
     *************************************************************************************/
    /**
     * Create a new application<br/>
     * 
     * @param application
     *            application JSON object
     * @return a HATEOAS application object with HTTP status 201 created
     * @throws JobAppMalformatException
     * @throws TransformerException
     */
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<JobApplicationResource> createApplication(@RequestBody JobApplication application)
            throws JobAppMalformatException, TransformerException {
        if (application == null) {
            throw new JobAppMalformatException("Cannot create null job application");
        }

        if (StringUtils.isEmpty(application.get_jobId())) {
            throw new JobAppMalformatException("Job application malformed: _jobId required");
        }

        JobPosting jobFound = jobDao.findByJid(application.get_jobId());
        if (jobFound == null) {
            throw new JobAppMalformatException("Job application malformed: job with _jobId not found in database");
        }

        if (StringUtils.isEmpty(application.getDriverLicenseNumber())) {
            throw new JobAppMalformatException("Job application malformed: driverLicenseNumber required");
        }

        if (StringUtils.isEmpty(application.getFullName())) {
            throw new JobAppMalformatException("Job application malformed: fullName required");
        }

        if (StringUtils.isEmpty(application.getPostCode())) {
            throw new JobAppMalformatException("Job application malformed: postCode required");
        }

        application.set_appId(UUID.randomUUID().toString());

        if (StringUtils.isEmpty(application.getTextCoverLetter())) {
            application.setTextCoverLetter("");
        }

        if (StringUtils.isEmpty(application.getTextBriefResume())) {
            application.setTextBriefResume("");
        }

        // after the create, status becomes submit but not processed yet
        application.setStatus(JobAppStatus.APP_SUBMITTED_NOT_PROCESSED.name());

        JobApplication createdApp = jobAppDao.create(application);

        JobApplicationResource createdAppResource = appResourceAssembler.toResource(createdApp);

        return new ResponseEntity<JobApplicationResource>(createdAppResource, HttpStatus.CREATED);
    }

    /*************************************************************************************
     * PUT methods
     *************************************************************************************/

    /**
     * Update an application by its candidate<br/>
     * 
     * @param application
     *            an application JSON object
     * @return a HATEOAS application after updated
     * @throws JobApplicationNotFoundException
     * @throws JobAppStatusCannotModifyException
     * @throws JobAppMalformatException
     * @throws TransformerException
     */
    @RequestMapping(value = "/{_appId}", method = RequestMethod.PUT)
    @ResponseBody
    public ResponseEntity<JobApplicationResource> updateApplication(@PathVariable(value = "_appId") String _appId,
            @RequestBody JobApplication application) throws JobApplicationNotFoundException,
            JobAppStatusCannotModifyException, JobAppMalformatException, TransformerException {
        // check if the application exist
        JobApplication existApp = jobAppDao.findById(_appId);

        if (existApp == null) {
            throw new JobApplicationNotFoundException(
                    "Job application with _appId=" + _appId + " not found in database.");
        }

        application.set_appId(_appId);
        application.setStatus(existApp.getStatus());

        // check if the application can be updated in current status
        String status = existApp.getStatus();
        if (StringUtils.isEmpty(status)
                || !status.equalsIgnoreCase(JobAppStatus.APP_SUBMITTED_NOT_PROCESSED.name())) {
            // only in submitted_but_not_processed status the application can be
            // updated
            throw new JobAppStatusCannotModifyException("Job application with _appId=" + _appId
                    + " is in the status of: '" + status + "', and cannot be modified currently.");
        }

        // check if the application has been modified, only if so do update
        // method, otherwise return the application directly
        if (StringUtils.isEmpty(existApp.get_jobId()) || StringUtils.isEmpty(application.get_jobId())
                || !existApp.get_jobId().equals(application.get_jobId())) {
            // _jobId is not permitted to be updated
            throw new JobAppMalformatException("Job application malformat on _jobId: request ["
                    + application.get_jobId() + "], database [" + existApp.get_jobId() + "]");
        }

        List<Boolean> needUpdateInfoList = new ArrayList<>();

        // check required information (cannot be null or empty)

        // check driver license
        String appDriverLicenseNumber = application.getDriverLicenseNumber();
        String driverLicenseNumber = existApp.getDriverLicenseNumber();
        boolean needUpdateDriverLicense = false;
        if (checkApplicationRequiredInfoEmpty(appDriverLicenseNumber, driverLicenseNumber)) {
            throw new JobAppMalformatException("Job application malformat on driver license number: request ["
                    + appDriverLicenseNumber + "], database [" + driverLicenseNumber + "]");
        } else {
            needUpdateDriverLicense = checkNeedUpdate(appDriverLicenseNumber, driverLicenseNumber);
            needUpdateInfoList.add(needUpdateDriverLicense);
        }

        // check full name
        String appFullName = application.getFullName();
        String fullName = existApp.getFullName();
        boolean needUpdateFullName = false;
        if (checkApplicationRequiredInfoEmpty(appFullName, fullName)) {
            throw new JobAppMalformatException("Job application malformat on full name: request [" + appFullName
                    + "], database [" + fullName + "]");
        } else {
            needUpdateFullName = checkNeedUpdate(appFullName, fullName);
            needUpdateInfoList.add(needUpdateFullName);
        }

        // check post code
        String appPostCode = application.getPostCode();
        String postCode = existApp.getPostCode();
        boolean needUpdatePostCode = false;
        if (checkApplicationRequiredInfoEmpty(appPostCode, postCode)) {
            throw new JobAppMalformatException("Job application malformat on post code: get from database ["
                    + appPostCode + "], parameter [" + postCode + "]");
        } else {
            needUpdatePostCode = checkNeedUpdate(appPostCode, postCode);
            needUpdateInfoList.add(needUpdatePostCode);
        }

        // check not-required information

        // check text cover letter
        String appTextCoverLetter = application.getTextCoverLetter();
        String textCoverLetter = existApp.getTextCoverLetter();
        if (StringUtils.isEmpty(appTextCoverLetter)) {
            appTextCoverLetter = "";
            application.setTextCoverLetter("");
        }

        // String appTextCoverLetter = application.getTextCoverLetter();
        boolean needUpdateTextCoverLetter = checkNeedUpdate(appTextCoverLetter, textCoverLetter);
        needUpdateInfoList.add(needUpdateTextCoverLetter);

        // check text brief resume
        String appTextBriefResume = application.getTextBriefResume();
        String textBriefResume = existApp.getTextBriefResume();
        if (StringUtils.isEmpty(appTextBriefResume)) {
            appTextBriefResume = "";
            application.setTextBriefResume("");
        }

        boolean needUpdateTextBriefResume = checkNeedUpdate(appTextBriefResume, textBriefResume);
        needUpdateInfoList.add(needUpdateTextBriefResume);

        // check need update flag to decide whether do writing update into XML
        boolean needWriteUpdate = false;
        for (boolean need : needUpdateInfoList) {
            if (need) {
                needWriteUpdate = true;
                break;
            }
        }

        if (needWriteUpdate) {
            jobAppDao.update(application);
        }

        JobApplicationResource updatedAppResource = appResourceAssembler.toResource(application);

        return new ResponseEntity<JobApplicationResource>(updatedAppResource, HttpStatus.OK);
    }

    /**
     * Update application status<br/>
     * 
     * @param _appId
     *            application ID
     * @param status
     *            status to be updated
     * @return a HATEOAS application object
     * @throws JobApplicationNotFoundException
     * @throws JobAppMalformatException
     * @throws TransformerException
     */
    @RequestMapping(value = "/status/{_appId}", method = RequestMethod.PUT)
    @ResponseBody
    public ResponseEntity<JobApplicationResource> updateJobStatus(@PathVariable(value = "_appId") String _appId,
            @RequestParam(name = "status") String status)
            throws JobApplicationNotFoundException, JobAppMalformatException, TransformerException {
        // check application existence
        JobApplication app = jobAppDao.findById(_appId);
        if (app == null) {
            throw new JobApplicationNotFoundException("Job application with _appId=" + _appId
                    + " not found in database, you cannot update its status");
        }

        // check input status
        if (StringUtils.isEmpty(status)) {
            throw new JobAppMalformatException("Job application update status: required input status");
        }

        if (!JobAppStatus.contains(status)) {
            throw new JobAppMalformatException("Job application update status invalid");
        }

        if (!status.equals(app.getStatus())) { // need update
            app.setStatus(status);
            jobAppDao.update(app);
        }

        JobApplicationResource updatedAppResource = appResourceAssembler.toResource(app);

        return new ResponseEntity<JobApplicationResource>(updatedAppResource, HttpStatus.OK);
    }

    /*************************************************************************************
     * DELETE methods
     *************************************************************************************/
    /**
     * Candidate archives its application<br/>
     * 
     * @param _appId
     *            application ID
     * @return a HATEOAS application object
     * @throws JobApplicationNotFoundException
     * @throws JobAppStatusCannotModifyException
     * @throws TransformerException
     */
    @RequestMapping(value = "/{_appId}", method = RequestMethod.DELETE)
    @ResponseBody
    public ResponseEntity<JobApplicationResource> archiveApplication(@PathVariable(value = "_appId") String _appId)
            throws JobApplicationNotFoundException, JobAppStatusCannotModifyException, TransformerException {
        // check application existence
        JobApplication app = jobAppDao.findById(_appId);
        if (app == null) {
            throw new JobApplicationNotFoundException(
                    "Job application with _appId=" + _appId + " not found in database, you cannot archive it");
        }

        // check application status
        String appStatus = app.getStatus();
        if (!appStatus.equals(JobAppStatus.APP_INTERVIEW_PASSED.name())
                && !appStatus.equals(JobAppStatus.APP_INTERVIEW_FAILED.name())
                && !appStatus.equals(JobAppStatus.APP_REJECTED_BY_CANDIDATE.name())
                && !appStatus.equals(JobAppStatus.APP_NOT_SHORTLISTED.name())
                && !appStatus.equals(JobAppStatus.APP_CANCELLED.name())) {
            throw new JobAppStatusCannotModifyException(
                    "Job application status is " + appStatus + ", cannot be archived yet");
        }

        app.setStatus(JobAppStatus.APP_ARCHIVED.name());
        jobAppDao.update(app);

        JobApplicationResource updatedAppResource = appResourceAssembler.toResource(app);

        return new ResponseEntity<JobApplicationResource>(updatedAppResource, HttpStatus.OK);
    }

    /*************************************************************************************
     * Exception handler
     *************************************************************************************/
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @ExceptionHandler
    ResponseEntity handleExceptions(Exception e) {
        ResponseEntity responseEntity = null;

        RESTError error = new RESTError();
        if (e instanceof DAOException || e instanceof TransformerException) {
            error.setErrCode(DAOErrorCode.DATA_ERROR);
            error.setErrMessage(e.getMessage());
            responseEntity = new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
        } else if (e instanceof JobApplicationNotFoundException) {
            error.setErrCode(RESTErrorCode.JOB_APP_NOT_FOUND);
            error.setErrMessage(e.getMessage());
            responseEntity = new ResponseEntity(error, HttpStatus.NOT_FOUND);
        } else if (e instanceof JobAppMalformatException || e instanceof JobAppStatusCannotModifyException) {
            error.setErrCode(RESTErrorCode.CLIENT_BAD_REQUEST);
            error.setErrMessage(e.getMessage());
            responseEntity = new ResponseEntity(error, HttpStatus.BAD_REQUEST);
        } else {
            error.setErrCode(RESTErrorCode.GENERAL_SERVER_ERROR);
            error.setErrMessage(e.getMessage());
            responseEntity = new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        return responseEntity;
    }

    /*************************************************************************************
     * General private methods used in controller
     *************************************************************************************/

    /**
     * Check if info of an application is need and can be updated<br/>
     * 
     * @param fromRequest
     * @param fromDatabase
     * @return
     */
    private boolean checkApplicationRequiredInfoEmpty(String fromRequest, String fromDatabase) {
        return StringUtils.isEmpty(fromDatabase) // from database not empty
                || StringUtils.isEmpty(fromRequest); // from param not empty
    }

    /**
     * Check if info of an application is needed to be updated<br/>
     * 
     * @param fromRequest
     * @param fromDatabase
     * @return
     */
    private boolean checkNeedUpdate(String fromRequest, String fromDatabase) {
        return !fromDatabase.equals(fromRequest);
    }
}