/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sections/trunk/sections-app/src/java/org/sakaiproject/tool/section/jsf/backingbean/StudentViewBean.java $
* $Id: StudentViewBean.java 105080 2012-02-24 23:10:31Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2005, 2006, 2007, 2008 The Sakai Foundation
*
* 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.section.jsf.backingbean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.component.UIViewRoot;
import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.section.api.coursemanagement.CourseSection;
import org.sakaiproject.section.api.coursemanagement.EnrollmentRecord;
import org.sakaiproject.section.api.exception.RoleConfigurationException;
import org.sakaiproject.section.api.exception.SectionFullException;
import org.sakaiproject.section.api.facade.Role;
import org.sakaiproject.tool.section.decorator.SectionDecorator;
import org.sakaiproject.tool.section.decorator.StudentSectionDecorator;
import org.sakaiproject.tool.section.jsf.JsfUtil;
/**
* Controls the student view page.
*
* @author <a href="mailto:jholtzman@berkeley.edu">Josh Holtzman</a>
*
*/
public class StudentViewBean extends EditStudentSectionsBean implements Serializable {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(StudentViewBean.class);
private boolean externallyManaged;
private boolean joinAllowed;
private boolean switchAllowed;
private String instructions;
private String filter;
// Students don't need a full preferences bean, so we just store the sorting as fields
private String sortColumn;
private boolean sortAscending;
public StudentViewBean() {
super();
showNegativeSpots = false;
sortColumn = "title";
sortAscending = true;
}
public void init() {
// Initialize the sections using the current user's uid
studentUid = getUserUid();
super.init();
// Determine whether this course is externally managed
externallyManaged = getSectionManager().isExternallyManaged(getCourse().getUuid());
// Determine whether the sections are joinable and/or switchable
joinAllowed = getSectionManager().isSelfRegistrationAllowed(getCourse().getUuid());
switchAllowed = getSectionManager().isSelfSwitchingAllowed(getCourse().getUuid());
// Keep track of whether there are joinable Sections
boolean joinableSectionsExist = false;
// Keep track of whether there are switchable Sections
boolean switchableSectionsExist = false;
List<SectionDecorator> sectionCopy = new ArrayList<SectionDecorator>(sections);
for(Iterator<SectionDecorator> iter = sectionCopy.iterator(); iter.hasNext();) {
StudentSectionDecorator decoratedSection = (StudentSectionDecorator)iter.next();
// Filter sections
if(StringUtils.trimToNull(filter) != null) {
if("MY".equals(filter) && ! decoratedSection.isMember()) {
sections.remove(decoratedSection);
}
if(! "MY".equals(filter) && ! decoratedSection.getCategory().equals(filter)) {
sections.remove(decoratedSection);
}
}
if(decoratedSection.isJoinable()) {
joinableSectionsExist = true;
} else if (decoratedSection.isSwitchable()) {
switchableSectionsExist = true;
}
}
Collections.sort(sections, getComparator());
instructions = generateInstructions(joinableSectionsExist, switchableSectionsExist);
}
private String generateInstructions(boolean joinableSectionsExist, boolean switchableSectionsExist) {
//This site is externally managed, or joining and switching are both disallowed
if(!joinAllowed && ! switchAllowed) {
return JsfUtil.getLocalizedMessage("student_view_instructions_no_join_or_switch");
}
// Joining and switching are both possible
if(switchAllowed && switchableSectionsExist && joinAllowed && joinableSectionsExist) {
return JsfUtil.getLocalizedMessage("student_view_instructions_join_or_switch");
}
// Joining is possible, but switching is not
if(joinAllowed && joinableSectionsExist && !(switchAllowed && switchableSectionsExist)) {
return JsfUtil.getLocalizedMessage("student_view_instructions_join");
}
// Switching is possible, but joining is not
if(switchAllowed && switchableSectionsExist && !(joinAllowed && joinableSectionsExist)) {
return JsfUtil.getLocalizedMessage("student_view_instructions_switch");
}
// No sections can be joined or switched into
return JsfUtil.getLocalizedMessage("student_view_instructions_no_sections");
}
public void processJoinSection(ActionEvent event) {
String sectionUuid = (String)FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get("sectionUuid");
//is this section still joinable?
CourseSection section = getSectionManager().getSection(sectionUuid);
// The section might have been deleted
if(section == null) {
// There's nothing we can do in the UI, really.
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_no_sections_not_available"));
return;
}
refresh();
// Check that there are still places available
int maxEnrollments = Integer.MAX_VALUE;
if(section.getMaxEnrollments() != null) {
maxEnrollments = section.getMaxEnrollments().intValue();
}
if (maxEnrollments == Integer.MAX_VALUE) {
// No maximum size is set for this section
try {
if(getSectionManager().joinSection(sectionUuid) == null) {
// This operation failed
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_already_member_in_category"));
}
} catch (RoleConfigurationException rce) {
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
}
} else {
// Enforce a maximum size
Map roleMap = getSectionManager().getTotalEnrollmentsMap(sectionUuid);
if (roleMap.size() < 3) {
log.warn("Cannot get section enrollment information for section " + sectionUuid);
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
return;
}
int studentsEnrolled = ((Integer) roleMap.get(Role.STUDENT)).intValue();
int otherMembers = ((Integer) roleMap.get(Role.TA)).intValue() +
((Integer) roleMap.get(Role.INSTRUCTOR)).intValue();
if (studentsEnrolled >= maxEnrollments) {
if(log.isDebugEnabled()) log.debug("Attempted to join a section with no spaces");
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_membership_full", new String[] {section.getTitle()}));
return;
}
try {
if(getSectionManager().joinSection(sectionUuid, maxEnrollments + otherMembers) == null) {
// This operation failed
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_already_member_in_category"));
}
} catch (RoleConfigurationException rce) {
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
} catch (SectionFullException sfe) {
if(log.isDebugEnabled()) log.debug("Attempted to join a section with no spaces");
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_membership_full", new String[] {section.getTitle()}));
}
}
return;
}
public void processSwitchSection(ActionEvent event) {
String sectionUuid = (String)FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get("sectionUuid");
// Does the section still exist, and is it still joinable?
CourseSection section = getSectionManager().getSection(sectionUuid);
if(section == null) {
// There's nothing we can do in the UI, really.
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_no_sections_not_available"));
return;
}
refresh();
// Check that there are still places available
int maxEnrollments = Integer.MAX_VALUE;
if(section.getMaxEnrollments() != null) {
maxEnrollments = section.getMaxEnrollments().intValue();
}
if (maxEnrollments == Integer.MAX_VALUE) {
// No maximum size is set for this section
try {
getSectionManager().switchSection(sectionUuid);
} catch (RoleConfigurationException rce) {
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
}
} else {
// Enforce a maximum size
Map roleMap = getSectionManager().getTotalEnrollmentsMap(sectionUuid);
if (roleMap.size() < 3) {
log.warn("Cannot get section enrollment information for section " + sectionUuid);
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
return;
}
int studentsEnrolled = ((Integer) roleMap.get(Role.STUDENT)).intValue();
int otherMembers = ((Integer) roleMap.get(Role.TA)).intValue() +
((Integer) roleMap.get(Role.INSTRUCTOR)).intValue();
if (studentsEnrolled >= maxEnrollments) {
if(log.isDebugEnabled()) log.debug("Attempted to join a section with no spaces");
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_membership_full", new String[] {section.getTitle()}));
return;
}
try {
getSectionManager().switchSection(sectionUuid, maxEnrollments + otherMembers);
} catch (RoleConfigurationException rce) {
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("role_config_error"));
} catch (SectionFullException sfe) {
if(log.isDebugEnabled()) log.debug("Attempted to join a section with no spaces");
JsfUtil.addErrorMessage(JsfUtil.getLocalizedMessage("student_view_membership_full", new String[] {section.getTitle()}));
}
}
return;
}
public boolean isExternallyManaged() {
return externallyManaged;
}
public boolean isJoinAllowed() {
return joinAllowed;
}
public boolean isSwitchAllowed() {
return switchAllowed;
}
public String getInstructions() {
return instructions;
}
public boolean isSortAscending() {
return sortAscending;
}
public void setSortAscending(boolean sortAscending) {
this.sortAscending = sortAscending;
}
public String getSortColumn() {
return sortColumn;
}
public void setSortColumn(String sortColumn) {
this.sortColumn = sortColumn;
}
public String getFilter() {
return filter;
}
public void setFilter(String filter) {
this.filter = filter;
}
public void refresh() {
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ViewHandler viewHandler = application.getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, context
.getViewRoot().getViewId());
context.setViewRoot(viewRoot);
context.renderResponse(); //Optional
}
}