org.sakaiproject.tool.gradebook.ui.AssignmentBean.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.tool.gradebook.ui.AssignmentBean.java

Source

/**********************************************************************************
*
* $Id: AssignmentBean.java  $
*
***********************************************************************************
*
 * Copyright (c) 2005, 2006, 2007, 2008, 2009 The Sakai Foundation, The MIT Corporation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*
**********************************************************************************/

package org.sakaiproject.tool.gradebook.ui;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import javax.faces.application.FacesMessage;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.section.api.coursemanagement.EnrollmentRecord;
import org.sakaiproject.section.api.facade.Role;
import org.sakaiproject.service.gradebook.shared.ConflictingAssignmentNameException;
import org.sakaiproject.service.gradebook.shared.StaleObjectModificationException;
import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.tool.gradebook.Assignment;
import org.sakaiproject.tool.gradebook.Category;
import org.sakaiproject.tool.gradebook.Gradebook;
import org.sakaiproject.tool.gradebook.jsf.FacesUtil;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.service.gradebook.shared.MultipleAssignmentSavingException;
import org.sakaiproject.service.gradebook.shared.GradebookService;

public class AssignmentBean extends GradebookDependentBean implements Serializable {
    private static final Log logger = LogFactory.getLog(AssignmentBean.class);

    private Long assignmentId;
    private Assignment assignment;
    private List categoriesSelectList;
    private String extraCreditCategories;
    private String assignmentCategory;
    // these 2 used to determine whether to zero-out the point value in applyPointsPossibleForDropScoreCategories
    private boolean categoryChanged;
    public boolean gradeEntryTypeChanged;

    private Category selectedCategory;
    private boolean selectedCategoryDropsScores;
    private boolean selectedAssignmentIsOnlyOne;
    private List<Category> categories;

    private ScoringAgentData scoringAgentData;

    // added to support bulk gradebook item creation
    public List newBulkItems;
    public int numTotalItems = 1;
    public List addItemSelectList;

    public String gradeEntryType;
    public static final String UNASSIGNED_CATEGORY = "unassigned";
    public static final String GB_ADJUSTMENT_ENTRY = "Adjustment";

    private static final String GB_EDIT_ASSIGNMENT_PAGE = "editAssignment";

    /** 
     * To add the proper number of blank gradebook item objects for bulk creation 
     */
    private static final int NUM_EXTRA_ASSIGNMENT_ENTRIES = 50;

    protected void init() {
        if (logger.isDebugEnabled())
            logger.debug("init assignment=" + assignment);

        if (assignment == null) {
            if (assignmentId != null) {
                assignment = getGradebookManager().getAssignment(assignmentId);
            }
            if (assignment == null) {
                // it is a new assignment
                assignment = new Assignment();
                assignment.setReleased(true);
            }
        }

        // initialization; shouldn't enter here after category drop down changes
        if (selectedCategory == null && !UNASSIGNED_CATEGORY.equals(assignmentCategory)) {
            Category assignCategory = assignment.getCategory();
            if (assignCategory != null) {
                assignmentCategory = assignCategory.getId().toString();
                selectedCategoryDropsScores = assignCategory.isDropScores();
                assignCategory.setAssignmentList(retrieveCategoryAssignmentList(assignCategory));
                selectedAssignmentIsOnlyOne = isAssignmentTheOnlyOne(assignment, assignCategory);
                selectedCategory = assignCategory;
            } else {
                assignmentCategory = getLocalizedString("cat_unassigned");
            }
        }

        categoriesSelectList = new ArrayList();
        //create comma seperate string representation of the list of EC categories
        List<String> extraCreditCategoriesList = new ArrayList<String>();
        // The first choice is always "Unassigned"
        categoriesSelectList
                .add(new SelectItem(UNASSIGNED_CATEGORY, FacesUtil.getLocalizedString("cat_unassigned")));
        List gbCategories = getGradebookManager().getCategories(getGradebookId());
        if (gbCategories != null && gbCategories.size() > 0) {
            Iterator catIter = gbCategories.iterator();
            while (catIter.hasNext()) {
                Category cat = (Category) catIter.next();
                categoriesSelectList.add(new SelectItem(cat.getId().toString(), cat.getName()));
                if (cat.isExtraCredit()) {
                    extraCreditCategoriesList.add(cat.getId().toString());
                }
            }
        }
        extraCreditCategories = StringUtils.join(extraCreditCategoriesList, ",");

        // To support bulk creation of assignments
        if (newBulkItems == null) {
            newBulkItems = new ArrayList();
        }

        // initialize the number of items to add dropdown
        addItemSelectList = new ArrayList();
        addItemSelectList.add(new SelectItem("0", ""));
        for (int i = 1; i < NUM_EXTRA_ASSIGNMENT_ENTRIES; i++) {
            addItemSelectList.add(new SelectItem(new Integer(i).toString(), new Integer(i).toString()));
        }

        if (newBulkItems.size() == NUM_EXTRA_ASSIGNMENT_ENTRIES) {
            applyPointsPossibleForDropScoreCategories(newBulkItems);
        } else {
            for (int i = newBulkItems.size(); i < NUM_EXTRA_ASSIGNMENT_ENTRIES; i++) {
                BulkAssignmentDecoratedBean item = getNewAssignment();

                if (i == 0) {
                    item.setSaveThisItem("true");
                }

                newBulkItems.add(item);
            }
        }

        if (isScoringAgentEnabled()) {
            scoringAgentData = initializeScoringAgentData(getGradebookUid(), assignment.getId(), null);
        }
    }

    private boolean isAssignmentTheOnlyOne(Assignment assignment, Category category) {
        if (assignment != null && category != null && category.getAssignmentList() != null) {
            if (category.getAssignmentList().size() == 1)
                return ((Assignment) category.getAssignmentList().get(0)).getId().equals(assignment.getId());
            else if (category.getAssignmentList().size() == 0)
                return true;
            else
                return false;
        } else {
            return false;
        }
    }

    /* 
     * sets pointsPossible for items in categories that drop scores
     * and sets the assignment's category, so that the ui can read item.assignment.category.dropScores
     */
    private void applyPointsPossibleForDropScoreCategories(List items) {
        categories = getCategories();

        Map<String, Category> categoryCache = new HashMap<String, Category>();

        for (int i = 0; i < items.size(); i++) {
            BulkAssignmentDecoratedBean bulkAssignment = (BulkAssignmentDecoratedBean) items.get(i);

            String assignmentCategory = bulkAssignment.getCategory();
            if (getLocalizedString("cat_unassigned").equalsIgnoreCase(assignmentCategory)) {
                Category unassigned = new Category();
                bulkAssignment.getAssignment().setCategory(unassigned); // set this unassigned category, so that in the ui, item.assignment.category.dropScores will return false
                if (categoryChanged || gradeEntryTypeChanged) {
                    //bulkAssignment.setPointsPossible(null);
                    bulkAssignment.getAssignment().setPointsPossible(null);
                }
            } else {
                for (int j = 0; j < categories.size(); j++) {
                    Category category = (Category) categories.get(j);

                    if (assignmentCategory.equals(category.getId().toString())) {
                        if (categoryCache.containsKey(category.getId().toString())) {
                            category = categoryCache.get(category.getId().toString());
                        } else {
                            category = retrieveSelectedCategory(category.getId().toString(), true);
                            categoryCache.put(category.getId().toString(), category);
                        }

                        bulkAssignment.getAssignment().setCategory(category); // set here, because need to read item.assignment.category.dropScores in the ui
                        if (category.getAssignmentList() != null && category.getAssignmentList().size() > 0
                                && category.isDropScores()
                                && !GB_ADJUSTMENT_ENTRY.equals(bulkAssignment.getSelectedGradeEntryValue())) {
                            bulkAssignment.setPointsPossible(category.getItemValue().toString());
                            bulkAssignment.getAssignment().setPointsPossible(category.getItemValue());
                        } else if (categoryChanged || gradeEntryTypeChanged) {
                            if (category.isDropScores()) {
                                bulkAssignment.setPointsPossible(null);
                            }
                            bulkAssignment.getAssignment().setPointsPossible(null);
                        }
                        continue;
                    }
                }
            }
        }
    }

    private Category getCategoryById(String categoryId) {
        if (categoryId == null) {
            return null;
        }
        Category category = null;
        for (int i = 0; i < categories.size(); i++) {
            category = (Category) categories.get(i);
            String id = category.getId().toString();

            if (id != null && categoryId.trim().equals(id)) {
                break;
            }
        }
        return category;
    }

    private BulkAssignmentDecoratedBean getNewAssignment() {
        Assignment assignment = new Assignment();
        assignment.setReleased(true);
        if (selectedCategory != null && selectedCategory.isDropScores()) {
            assignment.setPointsPossible(selectedCategory.getItemValue());
        }
        BulkAssignmentDecoratedBean bulkAssignmentDecoBean = new BulkAssignmentDecoratedBean(assignment,
                getItemCategoryString(assignment));

        return bulkAssignmentDecoBean;
    }

    private String getItemCategoryString(Assignment assignment) {
        String assignmentCategory;
        Category assignCategory = assignment.getCategory();
        if (assignCategory != null) {
            assignmentCategory = assignCategory.getId().toString();
        } else {
            assignmentCategory = getLocalizedString("cat_unassigned");
        }

        return assignmentCategory;
    }

    /**
     * Used to check if all gradebook items are valid before saving. Due to the way JSF works, had to turn off
     * validators for bulk assignments so had to perform checks here.
     * This is an all-or-nothing save, ie, either all items are OK and we save them all, or return to add page
     * and highlight errors.
     */
    public String saveNewAssignment() {
        String resultString = "overview";
        boolean saveAll = true;

        // keep list of new assignment names just in case
        // duplicates entered on screen
        List newAssignmentNameList = new ArrayList();

        // used to hold assignments that are OK since we 
        // need to determine if all are correct before saving
        List itemsToSave = new ArrayList();

        Iterator assignIter = newBulkItems.iterator();
        int i = 0;
        Map<String, Category> categoryCache = new HashMap<String, Category>();
        while (i < numTotalItems && assignIter.hasNext()) {
            BulkAssignmentDecoratedBean bulkAssignDecoBean = (BulkAssignmentDecoratedBean) assignIter.next();

            if (bulkAssignDecoBean.getBlnSaveThisItem()) {
                Assignment bulkAssignment = bulkAssignDecoBean.getAssignment();

                // Check for blank entry else check if duplicate within items to be
                // added or with item currently in gradebook.
                if ("".equals(bulkAssignment.getName().toString().trim())) {
                    bulkAssignDecoBean.setBulkNoTitleError("blank");
                    saveAll = false;
                    resultString = "failure";
                } else if (newAssignmentNameList.contains(bulkAssignment.getName().trim())
                        || !getGradebookManager().checkValidName(getGradebookId(), bulkAssignment)) {
                    bulkAssignDecoBean.setBulkNoTitleError("dup");
                    saveAll = false;
                    resultString = "failure";
                } else {
                    bulkAssignDecoBean.setBulkNoTitleError("OK");
                    newAssignmentNameList.add(bulkAssignment.getName().trim());
                }

                Category selectedCategory;
                if (categoryCache.containsKey(bulkAssignDecoBean.getCategory())) {
                    selectedCategory = categoryCache.get(bulkAssignDecoBean.getCategory());
                } else {
                    selectedCategory = retrieveSelectedCategory(bulkAssignDecoBean.getCategory(), true);
                    categoryCache.put(bulkAssignDecoBean.getCategory(), selectedCategory);
                }
                boolean categoryDropsScores = false;
                if (selectedCategory != null && selectedCategory.isDropScores()
                        && selectedCategory.getAssignmentList() != null
                        && selectedCategory.getAssignmentList().size() > 0) {
                    categoryDropsScores = true;
                    if (!GB_ADJUSTMENT_ENTRY.equals(bulkAssignDecoBean.getSelectedGradeEntryValue())) {
                        bulkAssignDecoBean.setPointsPossible(selectedCategory.getItemValue().toString()); // if category drops scores and is not adjustment, point value will come from the category level
                    }
                }
                // Check if points possible is blank else convert to double. Exception at else point
                // means non-numeric value entered.
                if (bulkAssignDecoBean.getPointsPossible() == null
                        || ("".equals(bulkAssignDecoBean.getPointsPossible().trim()))) {
                    bulkAssignDecoBean.setBulkNoPointsError("blank");
                    saveAll = false;
                    resultString = "failure";
                } else {
                    try {
                        // Check if PointsPossible uses local number format
                        String strPointsPossible = bulkAssignDecoBean.getPointsPossible();
                        NumberFormat nf = NumberFormat.getInstance(new ResourceLoader().getLocale());

                        double dblPointsPossible = new Double(nf.parse(strPointsPossible).doubleValue());

                        // Added per SAK-13459: did not validate if point value was valid (> zero)
                        if (dblPointsPossible > 0) {
                            // No more than 2 decimal places can be entered.
                            BigDecimal bd = new BigDecimal(dblPointsPossible);
                            bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP); // Two decimal places
                            double roundedVal = bd.doubleValue();
                            double diff = dblPointsPossible - roundedVal;
                            if (diff != 0) {
                                saveAll = false;
                                resultString = "failure";
                                bulkAssignDecoBean.setBulkNoPointsError("precision");
                            } else {
                                bulkAssignDecoBean.setBulkNoPointsError("OK");
                                bulkAssignDecoBean.getAssignment()
                                        .setPointsPossible(new Double(bulkAssignDecoBean.getPointsPossible()));
                            }
                        } else {
                            saveAll = false;
                            resultString = "failure";
                            bulkAssignDecoBean.setBulkNoPointsError("invalid");
                        }
                    } catch (Exception e) {
                        bulkAssignDecoBean.setBulkNoPointsError("NaN");
                        saveAll = false;
                        resultString = "failure";
                    }
                }

                if (saveAll) {
                    bulkAssignDecoBean.getAssignment()
                            .setCategory(retrieveSelectedCategory(bulkAssignDecoBean.getCategory(), false));
                    // if points possible is still 0 at this point, set it to null to avoid Division By Zero exceptions.  These should never be allowed in the database.
                    if (null != bulkAssignDecoBean.getAssignment().getPointsPossible()
                            && bulkAssignDecoBean.getAssignment().getPointsPossible() == 0)
                        bulkAssignDecoBean.getAssignment().setPointsPossible(null);
                    itemsToSave.add(bulkAssignDecoBean.getAssignment());
                }

                // Even if errors increment since we need to go back to add page
                i++;
            }
        }

        // Now ready to save, the only problem is due to duplicate names.
        if (saveAll) {
            try {
                getGradebookManager().createAssignments(getGradebookId(), itemsToSave);

                String authzLevel = (getGradebookBean().getAuthzService().isUserAbleToGradeAll(getGradebookUid()))
                        ? "instructor"
                        : "TA";
                for (Iterator gbItemIter = itemsToSave.iterator(); gbItemIter.hasNext();) {
                    String itemName = ((Assignment) gbItemIter.next()).getName();
                    FacesUtil.addRedirectSafeMessage(
                            getLocalizedString("add_assignment_save", new String[] { itemName }));
                    getGradebookBean().getEventTrackingService().postEvent("gradebook.newItem",
                            "/gradebook/" + getGradebookId() + "/" + itemName + "/" + authzLevel);
                }
            } catch (MultipleAssignmentSavingException e) {
                FacesUtil.addErrorMessage(FacesUtil.getLocalizedString("validation_messages_present"));
                resultString = "failure";
            }
        } else {
            // There are errors so need to put an error message at top
            FacesUtil.addErrorMessage(FacesUtil.getLocalizedString("validation_messages_present"));
        }

        return resultString;
    }

    public String updateAssignment() {
        try {
            Category category = retrieveSelectedCategory();
            assignment.setCategory(category);

            if (!GB_ADJUSTMENT_ENTRY.equals(assignment.getSelectedGradeEntryValue()) && category != null
                    && category.isDropScores() && !isAssignmentTheOnlyOne(assignment, category)) {
                assignment.setPointsPossible(category.getItemValue()); // if category drops scores, point value will come from the category level
            }

            Assignment originalAssignment = getGradebookManager().getAssignment(assignmentId);
            Double origPointsPossible = originalAssignment.getPointsPossible();
            Double newPointsPossible = assignment.getPointsPossible();
            boolean scoresEnteredForAssignment = getGradebookManager().isEnteredAssignmentScores(assignmentId);

            /* If grade entry by percentage or letter and the points possible has changed for this assignment,
             * we need to convert all of the stored point values to retain the same value
             */
            if ((getGradeEntryByPercent() || getGradeEntryByLetter()) && scoresEnteredForAssignment) {
                if (!newPointsPossible.equals(origPointsPossible)) {
                    List enrollments = getSectionAwareness().getSiteMembersInRole(getGradebookUid(), Role.STUDENT);
                    List studentUids = new ArrayList();
                    for (Iterator iter = enrollments.iterator(); iter.hasNext();) {
                        studentUids.add(((EnrollmentRecord) iter.next()).getUser().getUserUid());
                    }
                    getGradebookManager().convertGradePointsForUpdatedTotalPoints(getGradebook(),
                            originalAssignment, assignment.getPointsPossible(), studentUids);
                }
            }

            getGradebookManager().updateAssignment(assignment);
            long dueDateMillis = -1;
            Date dueDate = assignment.getDueDate();
            if (dueDate != null)
                dueDateMillis = dueDate.getTime();
            getGradebookBean().getEventTrackingService().postEvent("gradebook.updateAssignment",
                    "/gradebook/" + getGradebookUid() + "/" + assignment.getName() + "/"
                            + assignment.getPointsPossible() + "/" + dueDateMillis + "/" + assignment.isReleased()
                            + "/" + assignment.isCounted() + "/" + getAuthzLevel());

            if ((!origPointsPossible.equals(newPointsPossible)) && scoresEnteredForAssignment) {
                if (getGradeEntryByPercent())
                    FacesUtil.addRedirectSafeMessage(getLocalizedString("edit_assignment_save_percentage",
                            new String[] { assignment.getName() }));
                else if (getGradeEntryByLetter())
                    FacesUtil.addRedirectSafeMessage(getLocalizedString("edit_assignment_save_converted",
                            new String[] { assignment.getName() }));
                else
                    FacesUtil.addRedirectSafeMessage(getLocalizedString("edit_assignment_save_scored",
                            new String[] { assignment.getName() }));

            } else {
                FacesUtil.addRedirectSafeMessage(
                        getLocalizedString("edit_assignment_save", new String[] { assignment.getName() }));
            }

        } catch (ConflictingAssignmentNameException e) {
            logger.error(e);
            FacesUtil.addErrorMessage(getLocalizedString("edit_assignment_name_conflict_failure"));
            return "failure";
        } catch (StaleObjectModificationException e) {
            logger.error(e);
            FacesUtil.addErrorMessage(getLocalizedString("edit_assignment_locking_failure"));
            return "failure";
        }

        return navigateBack();
    }

    public String navigateToAssignmentDetails() {
        return navigateBack();
    }

    /**
     * Go to assignment details page. InstructorViewBean contains duplicate
     * of this method, cannot migrate up to GradebookDependentBean since
     * needs assignmentId, which is defined here.
     */
    public String navigateBack() {
        String breadcrumbPage = getBreadcrumbPage();
        final Boolean middle = new Boolean((String) SessionManager.getCurrentToolSession().getAttribute("middle"));

        if (breadcrumbPage == null || middle) {
            AssignmentDetailsBean assignmentDetailsBean = (AssignmentDetailsBean) FacesUtil
                    .resolveVariable("assignmentDetailsBean");
            assignmentDetailsBean.setAssignmentId(assignmentId);
            assignmentDetailsBean.setBreadcrumbPage(breadcrumbPage);

            breadcrumbPage = "assignmentDetails";
        }

        // wherever we go, we're not editing, and middle section
        // does not need to be shown.
        setNav(null, "false", null, "false", null);

        return breadcrumbPage;
    }

    /**
     * View maintenance methods.
     */
    public Long getAssignmentId() {
        if (logger.isDebugEnabled())
            logger.debug("getAssignmentId " + assignmentId);
        return assignmentId;
    }

    public void setAssignmentId(Long assignmentId) {
        if (logger.isDebugEnabled())
            logger.debug("setAssignmentId " + assignmentId);
        if (assignmentId != null) {
            this.assignmentId = assignmentId;
        }
    }

    public Assignment getAssignment() {
        if (logger.isDebugEnabled())
            logger.debug("getAssignment " + assignment);
        if (assignment == null) {
            if (assignmentId != null) {
                assignment = getGradebookManager().getAssignment(assignmentId);
            }
            if (assignment == null) {
                // it is a new assignment
                assignment = new Assignment();
                assignment.setReleased(true);
            }
        }

        return assignment;
    }

    public List getCategoriesSelectList() {
        return categoriesSelectList;
    }

    public String getExtraCreditCategories() {
        return extraCreditCategories;
    }

    public List getAddItemSelectList() {
        return addItemSelectList;
    }

    public String getAssignmentCategory() {
        return assignmentCategory;
    }

    public void setAssignmentCategory(String assignmentCategory) {
        this.assignmentCategory = assignmentCategory;
    }

    /**
     * getNewBulkItems
     * 
     * Generates and returns a List of blank Assignment objects.
     * Used to support bulk gradebook item creation.
     */
    public List getNewBulkItems() {
        if (newBulkItems == null) {
            newBulkItems = new ArrayList();
        }

        for (int i = newBulkItems.size(); i < NUM_EXTRA_ASSIGNMENT_ENTRIES; i++) {
            newBulkItems.add(getNewAssignment());
        }

        return newBulkItems;
    }

    public void setNewBulkItems(List newBulkItems) {
        this.newBulkItems = newBulkItems;
    }

    public List getCategories() {
        if (categories == null) {
            categories = getGradebookManager().getCategories(getGradebookId());
        }

        return categories;
    }

    public int getNumTotalItems() {
        return numTotalItems;
    }

    public void setNumTotalItems(int numTotalItems) {
        this.numTotalItems = numTotalItems;
    }

    public Gradebook getLocalGradebook() {
        return getGradebook();
    }

    /**
     * Returns the Category associated with assignmentCategory
     * If unassigned or not found, returns null
     * 
     * added parameterized version to support bulk gradebook item creation
     */
    private Category retrieveSelectedCategory() {
        return retrieveSelectedCategory(assignmentCategory, true);
    }

    private Category retrieveSelectedCategory(String assignmentCategory, boolean includeAssignments) {
        Long catId = null;
        Category category = null;

        if (assignmentCategory != null && !assignmentCategory.equals(UNASSIGNED_CATEGORY)) {
            try {
                catId = new Long(assignmentCategory);
            } catch (Exception e) {
                catId = null;
            }

            if (catId != null) {
                // check to make sure there is a corresponding category
                category = getGradebookManager().getCategory(catId);
                if (includeAssignments) {
                    //populate assignments list
                    category.setAssignmentList(retrieveCategoryAssignmentList(category));
                }
            }
        }

        return category;
    }

    private List retrieveCategoryAssignmentList(Category cat) {
        List assignmentsToUpdate = new ArrayList();
        if (cat != null) {
            List assignments = cat.getAssignmentList();
            if (cat.isDropScores() && (assignments == null || assignments.size() == 0)) { // don't populate, if assignments are already in category (to improve performance)
                assignments = getGradebookManager().getAssignmentsForCategory(cat.getId());

                // only include assignments which are not adjustments must not update adjustment item pointsPossible
                for (Object o : assignments) {
                    if (o instanceof Assignment) {
                        Assignment assignment = (Assignment) o;
                        if (!Assignment.item_type_adjustment.equals(assignment.getItemType())) {
                            assignmentsToUpdate.add(assignment);
                        }
                    }
                }
            }
        }
        return assignmentsToUpdate;
    }

    public boolean isSelectedCategoryDropsScores() {
        return selectedCategoryDropsScores;
    }

    public void setSelectedCategoryDropsScores(boolean selectedCategoryDropsScores) {
        this.selectedCategoryDropsScores = selectedCategoryDropsScores;
    }

    public Category getSelectedCategory() {
        return selectedCategory;
    }

    public void setSelectedCategory(Category selectedCategory) {
        this.selectedCategory = selectedCategory;
    }

    public String processCategoryChangeInEditAssignment(ValueChangeEvent vce) {
        String changeCategory = (String) vce.getNewValue();
        assignmentCategory = changeCategory;
        if (vce.getOldValue() != null && vce.getNewValue() != null
                && !vce.getOldValue().equals(vce.getNewValue())) {
            if (changeCategory.equals(UNASSIGNED_CATEGORY)) {
                selectedCategoryDropsScores = false;
                selectedAssignmentIsOnlyOne = false;
                selectedCategory = null;
                assignmentCategory = getLocalizedString("cat_unassigned");
            } else {
                List<Category> categories = getGradebookManager().getCategories(getGradebookId());
                if (categories != null && categories.size() > 0) {
                    for (Category category : categories) {
                        if (changeCategory.equals(category.getId().toString())) {
                            selectedCategoryDropsScores = category.isDropScores();
                            category.setAssignmentList(retrieveCategoryAssignmentList(category));
                            selectedCategory = category;
                            selectedAssignmentIsOnlyOne = isAssignmentTheOnlyOne(assignment, selectedCategory);
                            assignmentCategory = category.getId().toString();
                            break;
                        }
                    }
                }
            }
        }
        return GB_EDIT_ASSIGNMENT_PAGE;
    }

    /**
     * For bulk assignments, need to set the proper classes as a string
     */
    public String getRowClasses() {
        StringBuffer rowClasses = new StringBuffer();

        if (newBulkItems == null) {
            newBulkItems = getNewBulkItems();
        }

        //if shown in UI, set class to 'bogus show' otherwise 'bogus hide'
        for (int i = 0; i < newBulkItems.size(); i++) {
            Object obj = newBulkItems.get(i);
            if (obj instanceof BulkAssignmentDecoratedBean) {
                BulkAssignmentDecoratedBean assignment = (BulkAssignmentDecoratedBean) newBulkItems.get(i);

                if (i != 0)
                    rowClasses.append(",");

                if (assignment.getBlnSaveThisItem() || i == 0) {
                    rowClasses.append("show bogus");
                } else {
                    rowClasses.append("hide bogus");
                }
            }
        }

        return rowClasses.toString();
    }

    public boolean isSelectedAssignmentIsOnlyOne() {
        return selectedAssignmentIsOnlyOne;
    }

    public void setSelectedAssignmentIsOnlyOne(boolean selectedAssignmentIsOnlyOne) {
        this.selectedAssignmentIsOnlyOne = selectedAssignmentIsOnlyOne;
    }

    public ScoringAgentData getScoringAgentData() {
        return this.scoringAgentData;
    }

}