com.virtusa.akura.common.controller.ManageGradeController.java Source code

Java tutorial

Introduction

Here is the source code for com.virtusa.akura.common.controller.ManageGradeController.java

Source

/*
 * < KURA, This application manages the daily activities of a Teacher and a Student of a School>
 *
 * Copyright (C) 2012 Virtusa Corporation.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.virtusa.akura.common.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.ListUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.virtusa.akura.api.dto.ClassGrade;
import com.virtusa.akura.api.dto.Grade;
import com.virtusa.akura.api.dto.GradeSubject;
import com.virtusa.akura.api.dto.SchoolClass;
import com.virtusa.akura.api.dto.Subject;
import com.virtusa.akura.api.exception.AkuraAppException;
import com.virtusa.akura.api.exception.AkuraException;
import com.virtusa.akura.api.exception.ErrorMsgLoader;
import com.virtusa.akura.common.AkuraWebConstant;
import com.virtusa.akura.common.service.CommonService;
import com.virtusa.akura.common.validator.GradeValidator;
import com.virtusa.akura.util.SortUtil;

/**
 * The controller is to handle Add/Edit/Delete/View operations for Grade and ClassGrade reference module.
 * 
 * @author Virtusa Corporation
 */
@Controller
public class ManageGradeController {

    /** Class Size. */
    private static final String CLASS_SIZE = "classSize";

    /**
     * Logger to log the exceptions.
     */
    private static final Logger LOG = Logger.getLogger(ManageGradeController.class);

    /** view post method manage grade. */
    private static final String VIEW_POST_MANAGE_GRADE = "redirect:manageGrade.htm";

    /** view get method manage grade. */
    private static final String VIEW_GET_MANAGE_GRADE = "reference/manageGrade";

    /** model attribute of grade. */
    private static final String MODEL_ATT_GRADE = "grade";

    /** model attribute of class grade map. */
    private static final String MODEL_ATT_GRADE_MAP = "gradeMap";

    /** model attribute of school Class List. */
    private static final String MODEL_ATT_SCHOOL_CLASS_LIST = "schoolClassList";

    /** request mapping value for save or update ClassGrade. */
    private static final String REQ_MAP_VALUE_SAVEORUPDATE = "/saveOrUpdateGrade.htm";

    /** request mapping value for delete ClassGrade. */
    private static final String REQ_MAP_VALUE_DELETE = "/manageDeleteGrade.htm";

    /** request parameter for class id. */
    private static final String REQ_CLASS_ID = "classId";

    /** request parameter for grade name. */
    private static final String REQ_SELECTEDGRADE = "selectedGrade";

    /** Check for classes field empty. */
    private static final String FIELD_NAME = "gradeId";

    /** this is an appender to append string. */
    private static final String APPENDER = ",";

    /** attribute for holding error message key. */
    private static final String ERROR_MSG_KEY = "REF.UI.GRADE.DESCRIPTION.EXIST";

    /** attribute for holding error message key. */
    private static final String ERROR_MSG_DELETE = "REF.UI.GRADE.DELETE";

    /** attribute for holding error message key. */
    private static final String ERROR_MSG_EDIT = "REF.UI.GRADE.EDIT";

    /** attribute for holding message. */
    private static final String EDITPANE = "editpane";

    /** Model attribute of "selectedObjId". */
    private static final String SELECTED_OBJ_ID = "selectedObjId";

    /** attribute for holding message. */
    private static final String MESSAGE = "message";

    /** {@link CommonService}. */
    private CommonService commonService;

    /**
     * Represents gradeValidator instance of {@link GradeValidator}.
     */
    private GradeValidator gradeValidator;

    /**
     * Set the commonService to inject the service.
     * 
     * @param commonServiceValue the commonService to set
     */
    public void setCommonService(CommonService commonServiceValue) {

        this.commonService = commonServiceValue;
    }

    /**
     * Set the gradeValidator to inject the validator.
     * 
     * @param gradeValidatorValue the gradeValidator to set
     */
    public void setGradeValidator(GradeValidator gradeValidatorValue) {

        this.gradeValidator = gradeValidatorValue;
    }

    /**
     * Handle GET requests for Grade_details view.
     * 
     * @param model - ModelMap
     * @return the name of the view.
     */
    @RequestMapping(method = RequestMethod.GET)
    public String showGradeDetail(ModelMap model) {

        Grade grade = (Grade) model.get(MODEL_ATT_GRADE);

        if (grade == null) {
            grade = new Grade();
        }

        model.addAttribute(MODEL_ATT_GRADE, grade);

        return VIEW_GET_MANAGE_GRADE;
    }

    /**
     * Method is to return list of grades with classes belongs to.
     * 
     * @return a map which has key - grade and value - list of classes.
     * @throws AkuraException - Details exception
     */
    @ModelAttribute(MODEL_ATT_GRADE_MAP)
    public Map<String, String> populateClassGrades() throws AkuraException {

        List<Grade> grades = commonService.getGradeList();
        grades = SortUtil.sortGradesList(grades);
        Map<String, String> newMap = new LinkedHashMap<String, String>();

        for (Grade grade : grades) {

            int classGradeSize = 0;
            StringBuilder builder = new StringBuilder();
            List<ClassGrade> classGrades = commonService.getClassGradeListByGrade(grade);
            Iterator<ClassGrade> classGradeIter = classGrades.iterator();

            while (classGradeIter.hasNext()) {

                classGradeSize++;

                ClassGrade classGrade = (ClassGrade) classGradeIter.next();
                SchoolClass schoolClass = classGrade.getSchoolClass();
                builder.append(schoolClass.getDescription());

                // Don't append , with the last class
                if (classGradeSize != classGrades.size()) {
                    builder.append(APPENDER);
                }
            }

            newMap.put(grade.getDescription(), builder.toString());
        }

        return newMap;
    }

    /**
     * Method is to return schoolClass list.
     * 
     * @param model - {@link ModelMap}
     * @return list of schoolClass
     * @throws AkuraAppException - Detailed exception.
     */
    @ModelAttribute(MODEL_ATT_SCHOOL_CLASS_LIST)
    public List<SchoolClass> populateSchoolClasss(ModelMap model) throws AkuraAppException {

        List<SchoolClass> schoolClasses = commonService.getClassList();
        model.addAttribute(CLASS_SIZE, schoolClasses.size());

        return SortUtil.sortGradeClasses(schoolClasses);
    }

    /**
     * This method handles Add/Edit Grade and ClassGrade details.
     * 
     * @param grade - Grade obj.
     * @param request - HttpServletRequest
     * @param model {@link ModelMap}
     * @param bindingResult - holds errors
     * @return name of the view which is redirected to.
     * @throws AkuraAppException - throw detailed exception.
     */
    @RequestMapping(value = REQ_MAP_VALUE_SAVEORUPDATE, method = RequestMethod.POST)
    public String saveOrUpdateClassGrade(@ModelAttribute(MODEL_ATT_GRADE) Grade grade, BindingResult bindingResult,
            HttpServletRequest request, ModelMap model) throws AkuraAppException {

        gradeValidator.validate(grade, bindingResult);
        String gradeName = grade.getDescription().trim();
        String selectedGradeName = request.getParameter(REQ_SELECTEDGRADE);

        if (bindingResult.hasErrors() || (request.getParameterValues(REQ_CLASS_ID) == null)
                || "".equals(gradeName)) {
            if ((request.getParameterValues(REQ_CLASS_ID) == null) || "".equals(gradeName)) {

                model.addAttribute(EDITPANE, EDITPANE);
                model.addAttribute(SELECTED_OBJ_ID, selectedGradeName);
                bindingResult.rejectValue(FIELD_NAME, AkuraWebConstant.MANDATORY_FIELD_ERROR_CODE);
            }
            // model.addAttribute(EDITPANE, grade.getGradeId());
            model.addAttribute(EDITPANE, EDITPANE);
            model.addAttribute(SELECTED_OBJ_ID, selectedGradeName);
            return VIEW_GET_MANAGE_GRADE;
        } else {

            // Check whether the grade is already exist and populate a message
            // to user.
            if (isExistsGrade(gradeName, selectedGradeName)) {
                String message = new ErrorMsgLoader().getErrorMessage(ERROR_MSG_KEY);
                Grade newGrade = new Grade();

                model.addAttribute(EDITPANE, EDITPANE);
                model.addAttribute(SELECTED_OBJ_ID, selectedGradeName);
                model.addAttribute(MODEL_ATT_GRADE, newGrade);
                model.addAttribute(MESSAGE, message);
                return VIEW_GET_MANAGE_GRADE;
            } else {

                try {
                    // If selectedGradeName is empty, add a new grade otherwise
                    // update already existing grade.
                    grade = saveorUpdateGrade(grade, gradeName, selectedGradeName);

                    // Gets the classes for the selected grade.
                    String[] oldClassIds = getClassesForGrade(grade);

                    // There is no update for class_grade table, we have
                    // add/remove or add&remove, so that we use the below logic to be done.

                    // checked(from check boxes) new ids of classes
                    String[] classIds = request.getParameterValues(REQ_CLASS_ID);

                    // add new classes for the garde.
                    addClassesForGrade(grade, classIds, oldClassIds);

                    // Remove old clsses from the grade.
                    removeClassesFromGrade(grade, oldClassIds, classIds);

                    // update ClassGrade description of existing records.
                    updateClassGradeDescription(grade);

                } catch (AkuraAppException e) {
                    if (e.getCause() instanceof DataIntegrityViolationException) {
                        String message = new ErrorMsgLoader().getErrorMessage(ERROR_MSG_EDIT);
                        Grade newGrade = new Grade();
                        model.addAttribute(EDITPANE, EDITPANE);
                        model.addAttribute(SELECTED_OBJ_ID, selectedGradeName);
                        model.addAttribute(MODEL_ATT_GRADE, newGrade);
                        model.addAttribute(MESSAGE, message);

                        return VIEW_GET_MANAGE_GRADE;
                    } else {
                        throw e;
                    }
                }
            }
        }
        return VIEW_POST_MANAGE_GRADE;
    }

    /**
     * Removes the old classes from the grade.
     * 
     * @param grade the grade.
     * @param oldClassIds the old classes.
     * @param classIds the new classes.
     * @throws AkuraAppException the AkuraAppException.
     */
    private void removeClassesFromGrade(Grade grade, String[] oldClassIds, String[] classIds)
            throws AkuraAppException {

        // Get the class ids to be removed.
        @SuppressWarnings("unchecked")
        List<String> toBeRomoved = ListUtils.subtract(Arrays.asList(oldClassIds), Arrays.asList(classIds));

        // toBeRomoved list is not empty means, removing already
        // assigned classes from a grade
        if (!toBeRomoved.isEmpty()) {

            for (Object strClassId : toBeRomoved) {
                int classId = Integer.parseInt(strClassId + String.valueOf(""));
                List<ClassGrade> removeClassGrade = commonService
                        .getClassGradeByGradeIdAndClassId(grade.getGradeId(), classId);

                commonService.deleteClassGradeList(removeClassGrade);
            }
        }
    }

    /**
     * Gets the clases for the garde.
     * 
     * @param grade the garde.
     * @return the classes for the gared.
     * @throws AkuraAppException the AkuraAppException.
     */
    private String[] getClassesForGrade(Grade grade) throws AkuraAppException {

        List<ClassGrade> classGrades = commonService.getClassGradeListByGrade(grade);
        String[] oldClassIds = new String[classGrades.size()];
        int i = 0;

        for (ClassGrade oldClassGrade : classGrades) {
            oldClassIds[i] = oldClassGrade.getSchoolClass().getClassId() + String.valueOf("");
            i++;
        }
        return oldClassIds;
    }

    /**
     * Adds Classes for the garde.
     * 
     * @param grade the garde.
     * @param classIds the selected Class ids.
     * @param oldClassIds the previous class ids.
     * @throws AkuraAppException the AkuraAppException.
     */
    private void addClassesForGrade(Grade grade, String[] classIds, String[] oldClassIds) throws AkuraAppException {

        ClassGrade classGrade;
        // Get the class ids to be added.
        @SuppressWarnings("rawtypes")
        List toBeAdd = ListUtils.subtract(Arrays.asList(classIds), Arrays.asList(oldClassIds));

        // toBeAdd list is not empty means, assigning classes
        // additionally for a grade
        if (!toBeAdd.isEmpty()) {
            classGrade = new ClassGrade();

            for (Object strClassId : toBeAdd) {
                int classId = Integer.parseInt(strClassId + String.valueOf(""));
                SchoolClass schoolClass = commonService.findClass(classId);
                classGrade.setGrade(grade);
                classGrade.setSchoolClass(schoolClass);
                classGrade.setDescription(grade.getDescription().trim() + schoolClass.getDescription().trim());

                commonService.saveClassGrade(classGrade);
            }
        }
    }

    /**
     * update existing Class grade description.
     * 
     * @param grade the grade.
     * @throws AkuraAppException the AkuraAppException.
     */
    private void updateClassGradeDescription(Grade grade) throws AkuraAppException {

        // Get the existing class grade list.
        List<ClassGrade> classGradeList = commonService.getClassGradeListByGrade(grade);

        if (!classGradeList.isEmpty()) {

            for (ClassGrade classGrade : classGradeList) {
                classGrade.setDescription(
                        grade.getDescription().trim() + classGrade.getSchoolClass().getDescription().trim());
                commonService.updateClassGrade(classGrade);
            }
        }
    }

    /**
     * Saves or Updates the Grade.
     * 
     * @param grade the grade to save.
     * @param gradeName grade name.
     * @param selectedGradeName the slected grade name.
     * @return the updated grade.
     * @throws AkuraAppException the AkuraAppException
     */
    private Grade saveorUpdateGrade(Grade grade, String gradeName, String selectedGradeName)
            throws AkuraAppException {

        // If selectedGradeName is empty, add a new grade otherwise
        // update already existing grade.
        if (!"".equals(selectedGradeName)) {
            Grade gradeByName = commonService.getGradeByGradeName(selectedGradeName);
            gradeByName.setDescription(gradeName);
            commonService.updateGrade(gradeByName);
            grade = gradeByName;
        } else {
            grade.setDescription(gradeName);
            commonService.saveGrade(grade);
        }
        return grade;
    }

    /**
     * Delete a grade and classes belongs to.
     * 
     * @param request {@link HttpServletRequest}
     * @param model {@link ModelMap}
     * @return name of the view which is redirected to.
     * @throws AkuraAppException - throw this.
     */
    @RequestMapping(value = REQ_MAP_VALUE_DELETE, method = RequestMethod.POST)
    public String deleteGrade(HttpServletRequest request, ModelMap model) throws AkuraAppException {

        String description = request.getParameter(REQ_SELECTEDGRADE);
        Grade grade = commonService.getGradeByGradeName(description);

        List<GradeSubject> gradeSubjectList = commonService.getGradeSubjectIdListByGrade(grade.getGradeId());

        List<ClassGrade> classGrades = commonService.getClassGradeListByGrade(grade);

        List<Integer> classGradeIds = new ArrayList<Integer>();

        for (ClassGrade classGrade : classGrades) {
            classGradeIds.add(classGrade.getClassGradeId());
        }

        try {
            if ((gradeSubjectList == null || gradeSubjectList.isEmpty())) {
                commonService.deleteClassGradeList(classGrades);
                commonService.deleteGrade(grade);
            } else {
                String message = new ErrorMsgLoader().getErrorMessage(ERROR_MSG_DELETE);
                Grade newGrade = new Grade();
                model.addAttribute(MODEL_ATT_GRADE, newGrade);
                model.addAttribute(MESSAGE, message);

                return VIEW_GET_MANAGE_GRADE;
            }

        } catch (DataAccessException ex) {
            LOG.error("ManageGradeController - error occured while deleting list of class grade " + classGrades
                    + "-->" + ex.toString());
            throw new AkuraAppException(AkuraWebConstant.HIBERNATE_INVALID_DEL_OPERATION, ex);
        } catch (AkuraAppException ex) {
            if (ex.getCause() instanceof DataIntegrityViolationException) {
                String message = new ErrorMsgLoader().getErrorMessage(ERROR_MSG_DELETE);
                Grade newGrade = new Grade();
                model.addAttribute(MODEL_ATT_GRADE, newGrade);
                model.addAttribute(MESSAGE, message);

                return VIEW_GET_MANAGE_GRADE;
            } else {
                LOG.error("ManageGradeController - error occured while deleting grade object " + grade + "-->"
                        + ex.toString());
                throw new AkuraAppException(AkuraWebConstant.HIBERNATE_INVALID_DEL_OPERATION, ex);
            }
        }

        return VIEW_POST_MANAGE_GRADE;
    }

    /**
     * Check whether Grade is already added.
     * 
     * @param gradeName - String
     * @param selectedGradeName - String
     * @return true if it already exist else false
     * @throws AkuraAppException - Detailed exception
     */
    private boolean isExistsGrade(String gradeName, String selectedGradeName) throws AkuraAppException {

        boolean isExists = false;
        List<Grade> grades = commonService.getGradeList();

        for (Grade grade : grades) {

            boolean check = (!"".equals(selectedGradeName)) ? isExists
                    : grade.getDescription().equalsIgnoreCase(gradeName);

            if (check) {
                isExists = check;
                break;
            }
        }
        return isExists;
    }
}