001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sections/tags/sakai_2-4-1/sections-app/src/java/org/sakaiproject/tool/section/jsf/backingbean/EditStudentSectionsBean.java $
003: * $Id: EditStudentSectionsBean.java 22767 2007-03-16 17:41:08Z jholtzman@berkeley.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2005, 2006 The Regents of the University of California and The Regents of the University of Michigan
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.section.jsf.backingbean;
021:
022: import java.io.Serializable;
023: import java.util.ArrayList;
024: import java.util.Collections;
025: import java.util.Comparator;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Set;
029:
030: import javax.faces.context.FacesContext;
031: import javax.faces.event.ActionEvent;
032:
033: import org.apache.commons.lang.StringUtils;
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036: import org.sakaiproject.section.api.coursemanagement.CourseSection;
037: import org.sakaiproject.section.api.coursemanagement.EnrollmentRecord;
038: import org.sakaiproject.section.api.coursemanagement.ParticipationRecord;
039: import org.sakaiproject.section.api.coursemanagement.User;
040: import org.sakaiproject.section.api.exception.RoleConfigurationException;
041: import org.sakaiproject.section.api.facade.Role;
042: import org.sakaiproject.tool.section.decorator.SectionDecorator;
043: import org.sakaiproject.tool.section.decorator.StudentSectionDecorator;
044: import org.sakaiproject.tool.section.jsf.JsfUtil;
045:
046: /**
047: * Controls the edit student sections page (where a single student is assigned to sections).
048: *
049: * @author <a href="mailto:jholtzman@berkeley.edu">Josh Holtzman</a>
050: *
051: */
052: public class EditStudentSectionsBean extends FilteredSectionListingBean
053: implements Serializable {
054: private static final long serialVersionUID = 1L;
055: private static final Log log = LogFactory
056: .getLog(EditStudentSectionsBean.class);
057:
058: protected static final String UNASSIGNED = "unassigned";
059:
060: protected String studentUid;
061: protected String studentName;
062: protected List<SectionDecorator> enrolledSections;
063: protected String elementToFocus;
064:
065: protected boolean showNegativeSpots;
066:
067: public EditStudentSectionsBean() {
068: showNegativeSpots = true;
069: }
070:
071: public void init() {
072: setDefaultPrefs();
073:
074: // Get the filter settings
075: String categoryFilter = getCategoryFilter();
076: String myFilter = getMyFilter();
077:
078: // Get the student's name
079: User student = getSectionManager().getSiteEnrollment(
080: getSiteContext(), studentUid);
081: studentName = student.getDisplayName();
082:
083: // Get all sections in the site
084: List sectionSet = getAllSiteSections();
085: sections = new ArrayList<SectionDecorator>();
086: enrolledSections = new ArrayList<SectionDecorator>();
087:
088: // Keep track of whether there are no sections in this site
089: siteWithoutSections = sectionSet.isEmpty();
090:
091: // Generate the category select items
092: categorySelectItems = generateCategorySelectItems();
093:
094: // Compute the filter state
095: computeFilterState(sectionSet);
096:
097: // Get the section enrollments for this student
098: Set enrolled = getEnrolledSections(studentUid);
099:
100: for (Iterator sectionIter = sectionSet.iterator(); sectionIter
101: .hasNext();) {
102: CourseSection section = (CourseSection) sectionIter.next();
103: String catName = getCategoryName(section.getCategory());
104:
105: boolean hideSectionInTable = false;
106:
107: // If we are filtering by categories, and the section is not in this category, skip it
108: if (StringUtils.trimToNull(categoryFilter) != null
109: && !categoryFilter.equals(section.getCategory())) {
110: if (log.isDebugEnabled())
111: log.debug("Filtering out " + section.getTitle()
112: + ", since it is not in category "
113: + categoryFilter);
114: hideSectionInTable = true;
115: }
116:
117: // Generate the string showing the TAs
118: List<ParticipationRecord> tas = getSectionManager()
119: .getSectionTeachingAssistants(section.getUuid());
120: List<String> taNames = generateTaNames(tas);
121: List<String> taUids = generateTaUids(tas);
122:
123: // If we're filtering by my sections, and the TAs in the section don't include me, skip this section
124: if ("MY".equals(myFilter)) {
125: String userUid = getUserUid();
126: if (!taUids.contains(userUid)) {
127: if (log.isDebugEnabled())
128: log.debug("Filtering out " + section.getTitle()
129: + ", since user " + userUid
130: + " is not a TA");
131: hideSectionInTable = true;
132: }
133: }
134:
135: // Sort the TA names
136: Collections.sort(taNames);
137:
138: // Get the enrollments and membership so we can decorate the section
139: int totalEnrollments = getSectionManager()
140: .getTotalEnrollments(section.getUuid());
141: boolean member = isEnrolledInSection(enrolled, section);
142: boolean memberOtherSection = isEnrolledInOtherSection(
143: enrolled, section);
144:
145: StudentSectionDecorator decoratedSection = new StudentSectionDecorator(
146: section, catName, taNames, totalEnrollments,
147: member, memberOtherSection, showNegativeSpots);
148:
149: if (!hideSectionInTable) {
150: sections.add(decoratedSection);
151: }
152:
153: if (member) {
154: enrolledSections.add(decoratedSection);
155: }
156: }
157: Collections.sort(sections, getComparator());
158: Collections.sort(enrolledSections, getComparator());
159: }
160:
161: protected boolean isEnrolledInSection(Set enrolledSections,
162: CourseSection section) {
163: for (Iterator iter = enrolledSections.iterator(); iter
164: .hasNext();) {
165: EnrollmentRecord enr = (EnrollmentRecord) iter.next();
166: if (enr.getLearningContext().equals(section)) {
167: return true;
168: }
169: }
170: return false;
171: }
172:
173: protected boolean isEnrolledInOtherSection(Set enrolledSections,
174: CourseSection section) {
175: String category = section.getCategory();
176: for (Iterator iter = enrolledSections.iterator(); iter
177: .hasNext();) {
178: EnrollmentRecord enr = (EnrollmentRecord) iter.next();
179: if (((CourseSection) enr.getLearningContext())
180: .getCategory().equals(category)) {
181: return true;
182: }
183: }
184: return false;
185: }
186:
187: protected void checkMaxEnrollments(String sectionUuid) {
188: // Add a warning if max enrollments has been exceeded
189: CourseSection section = getSectionManager().getSection(
190: sectionUuid);
191: Integer maxEnrollments = section.getMaxEnrollments();
192: int totalEnrollments = getSectionManager().getTotalEnrollments(
193: section.getUuid());
194: if (maxEnrollments != null
195: && totalEnrollments > maxEnrollments.intValue()) {
196: JsfUtil
197: .addRedirectSafeWarnMessage(JsfUtil
198: .getLocalizedMessage(
199: "edit_student_over_max_warning",
200: new String[] {
201: section.getTitle(),
202: Integer
203: .toString(totalEnrollments),
204: Integer
205: .toString(totalEnrollments
206: - maxEnrollments
207: .intValue()) }));
208: }
209: }
210:
211: protected Comparator<SectionDecorator> getComparator() {
212: String sortColumn = getSortColumn();
213: boolean sortAscending = isSortAscending();
214: if (sortColumn.equals("title")) {
215: return SectionDecorator.getTitleComparator(sortAscending);
216: } else if (sortColumn.equals("instructor")) {
217: return SectionDecorator
218: .getManagersComparator(sortAscending);
219: } else if (sortColumn.equals("available")) {
220: return SectionDecorator.getEnrollmentsComparator(
221: sortAscending, true);
222: } else if (sortColumn.equals("meetingDays")) {
223: return SectionDecorator.getDayComparator(sortAscending);
224: } else if (sortColumn.equals("meetingTimes")) {
225: return SectionDecorator.getTimeComparator(sortAscending);
226: } else if (sortColumn.equals("location")) {
227: return SectionDecorator
228: .getLocationComparator(sortAscending);
229: }
230: log.error("Invalid sort specified.");
231: return null;
232: }
233:
234: public void processJoinSection(ActionEvent event) {
235: String sectionUuid = (String) FacesContext.getCurrentInstance()
236: .getExternalContext().getRequestParameterMap().get(
237: "sectionUuid");
238: //is this section still joinable?
239: CourseSection section = getSectionManager().getSection(
240: sectionUuid);
241:
242: // The section might have been deleted
243: if (section == null) {
244: JsfUtil.addErrorMessage(JsfUtil
245: .getLocalizedMessage("error_section_deleted"));
246: return;
247: }
248:
249: try {
250: getSectionManager().addSectionMembership(studentUid,
251: Role.STUDENT, sectionUuid);
252: } catch (RoleConfigurationException rce) {
253: JsfUtil.addErrorMessage(JsfUtil
254: .getLocalizedMessage("role_config_error"));
255: }
256: // Don't focus on this component, since it won't be there any more. Focus on the unjoin component
257: String componentId = event.getComponent().getClientId(
258: FacesContext.getCurrentInstance());
259: elementToFocus = componentId.replaceAll(":join", ":unjoin");
260: }
261:
262: public void processDrop(ActionEvent event) {
263: String sectionUuid = (String) FacesContext.getCurrentInstance()
264: .getExternalContext().getRequestParameterMap().get(
265: "sectionUuid");
266: CourseSection section = getSectionManager().getSection(
267: sectionUuid);
268:
269: // The section might have been deleted
270: if (section == null) {
271: JsfUtil.addErrorMessage(JsfUtil
272: .getLocalizedMessage("error_section_deleted"));
273: return;
274: }
275:
276: getSectionManager().dropSectionMembership(studentUid,
277: sectionUuid);
278:
279: // Don't focus on this component, since it won't be there any more. Focus on the join component
280: String componentId = event.getComponent().getClientId(
281: FacesContext.getCurrentInstance());
282: elementToFocus = componentId.replaceAll(":unjoin", ":join");
283: }
284:
285: /**
286: * Sets the student id to use in displaying the page.
287: *
288: * @param studentUuid
289: */
290: public void setStudentUid(String studentUid) {
291: this .studentUid = studentUid;
292: }
293:
294: public String getStudentName() {
295: return studentName;
296: }
297:
298: public String getElementToFocus() {
299: return elementToFocus;
300: }
301:
302: public void setElementToFocus(String elementToFocus) {
303: this .elementToFocus = elementToFocus;
304: }
305:
306: public String getUnassignedValue() {
307: return UNASSIGNED;
308: }
309:
310: public List<SectionDecorator> getEnrolledSections() {
311: return enrolledSections;
312: }
313:
314: @Override
315: public String getSortColumn() {
316: return getPrefs().getEditStudentSectionsSortColumn();
317: }
318:
319: @Override
320: public boolean isSortAscending() {
321: return getPrefs().isEditStudentSectionsSortAscending();
322: }
323:
324: @Override
325: public void setSortAscending(boolean sortAscending) {
326: getPrefs().setEditStudentSectionsSortAscending(sortAscending);
327: }
328:
329: @Override
330: public void setSortColumn(String sortColumn) {
331: getPrefs().setEditStudentSectionsSortColumn(sortColumn);
332: }
333:
334: @Override
335: public String getCategoryFilter() {
336: return getPrefs().getEditStudentSectionsCategoryFilter();
337: }
338:
339: @Override
340: public String getMyFilter() {
341: return getPrefs().getEditStudentSectionsMyFilter();
342: }
343:
344: @Override
345: public void setCategoryFilter(String categoryFilter) {
346: getPrefs().setEditStudentSectionsCategoryFilter(categoryFilter);
347: }
348:
349: @Override
350: public void setMyFilter(String myFilter) {
351: getPrefs().setEditStudentSectionsMyFilter(myFilter);
352: }
353: }
|