/** * Copyright © 2001 The JA-SIG Collaborative. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the JA-SIG Collaborative * (http://www.jasig.org/)." * * THIS SOFTWARE IS PROVIDED BY THE JA-SIG COLLABORATIVE "AS IS" AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JA-SIG COLLABORATIVE OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * */ package org.jasig.portal.channels; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.jasig.portal.ApplicantManager; import org.jasig.portal.ChannelRuntimeData; import org.jasig.portal.ChannelStaticData; import org.jasig.portal.Applicant; import org.jasig.portal.UserInstitution; import org.jasig.portal.EntityIdentifier; import org.jasig.portal.GeneralRenderingException; import org.jasig.portal.PortalException; import org.jasig.portal.security.IAuthorizationPrincipal; import org.jasig.portal.security.IPermissionManager; import org.jasig.portal.security.IPerson; import org.jasig.portal.services.AuthorizationService; import org.jasig.portal.services.EntityNameFinderService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.portal.utils.DocumentFactory; import org.jasig.portal.utils.XSLT; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.ContentHandler; /** *

CGraduateApplication is a channel which presents, accepts, processes and provides status of * graduate school applications.

* * @author rtwigg@uccs.edu * @version $Revision: 2.4.1 $ */ public class CGraduateApplication extends BaseChannel { private static final Log log = LogFactory.getLog(CGraduateApplication.class); protected static final String sslLocation = "CGraduateApplication/CGraduateApplication.ssl"; protected static final Document emptyDoc = DocumentFactory.getNewDocument(); protected short state; protected static final short FORM = 0; protected static final short DEFAULT_APP_STATE = 0; protected static final short DEFAULT_LIST_STATE = 1; protected static final short REVIEW_DETAILS_STATE = 2; protected static final short APPLICANT_LIST_STATE = 3; protected static final short EVAL_LIST_STATE = 4; protected static final short CHECK_STATUS_STATE = 5; protected static final short REVIEW_APPLICATION_STATE = 6; protected static final short NEW_APPLICATION_STATE = 7; protected static final short INSTITUTION_STATE = 8; protected static final short SUBMITTED = 0; protected static final short TRANSCRIPTS_RECEIVED = 2; protected static final short COMMITTEE_READY = 2; protected static final String [] appStatusDesc = { "Submitted", "Waiting for transcripts", "Transcripts received", "Application incomplete", "Candidate accepted to graduate school", "Candidate not accepted to graduate school", "Candidate has been waitlisted" }; protected static final String [] degreeValues = {"", "BS", "BA", "AS", "AA", "MS", "MA", "MBA", "PhD", "N/A"}; protected static final String [] tranStatusValues = {"Yes", "No", "N/A"}; protected String action = "none"; protected String capture = "none"; protected Document applicantManagerDoc; protected Applicant applicant; protected UserInstitution ui; protected ModifyChannelSettings modChanSettings = new ModifyChannelSettings(); protected IPerson person; protected String channelPublishId; protected String msg=""; protected boolean canEdit = false; protected boolean notify = false; protected CState cState = null; // state class private class CState { private String portalUser; private String currentApp; private boolean dirtyData; private String appSet; public CState() { portalUser = null; currentApp = null; dirtyData = false; appSet = "0"; //default to showing set of all applicants, not just those for committee evaluation } } // Called after application is submitted so that you won't see any previous settings // on the next submission attempt protected void resetSettings () { applicant = new Applicant(); modChanSettings = new ModifyChannelSettings(); msg = ""; notify = false; } public void setStaticData (ChannelStaticData sd) throws PortalException { staticData = sd; cState = new CState(); state=DEFAULT_APP_STATE; person = sd.getPerson(); if (person != null) { cState.portalUser = (String)person.getAttribute(IPerson.USERNAME); EntityIdentifier ei = person.getEntityIdentifier(); IAuthorizationPrincipal ap = AuthorizationService.instance().newPrincipal(ei.getKey(), ei.getType()); if (ap.canEdit(Integer.parseInt(sd.getChannelPublishId()))) { state=DEFAULT_LIST_STATE; canEdit = true; } } if (applicant==null) { applicant = new Applicant(); } } public void setRuntimeData (ChannelRuntimeData rd) throws PortalException { runtimeData = rd; action = runtimeData.getParameter("uPGA_action"); // Prepare the appropriate XML documents for the destination screen doCapture(); doAction(); } public void renderXML (ContentHandler out) throws PortalException { XSLT xslt = XSLT.getTransformer(this, runtimeData.getLocales()); xslt.setXML(applicantManagerDoc); xslt.setXSL(sslLocation, runtimeData.getBrowserInfo()); xslt.setTarget(out); xslt.setStylesheetParameter("baseActionURL", runtimeData.getBaseActionURL()); String action = null; switch (state) { case DEFAULT_APP_STATE: action = "appStart"; break; case DEFAULT_LIST_STATE: action = "listStart"; break; case REVIEW_APPLICATION_STATE: xslt.setStylesheetParameter("currentUser", applicant.getUserName()); action = "reviewApp"; break; case NEW_APPLICATION_STATE: action = "newApp"; break; case INSTITUTION_STATE: xslt.setStylesheetParameter("currentUser", applicant.getUserName()); action = "addInst"; break; case CHECK_STATUS_STATE: action = "showStat"; xslt.setStylesheetParameter("currentUser", cState.portalUser); break; case APPLICANT_LIST_STATE: action = "appList"; break; case EVAL_LIST_STATE: action = "comList"; break; case REVIEW_DETAILS_STATE: action = "reviewDetails"; xslt.setStylesheetParameter("currentUser", cState.currentApp); break; default: action = "none"; break; } xslt.setStylesheetParameter("comStatus", Integer.toString(COMMITTEE_READY)); xslt.setStylesheetParameter("appSet", cState.appSet); xslt.setStylesheetParameter("action", action); xslt.setStylesheetParameter("msg", msg); xslt.transform(); } /** * Collect the request parameters for a new application. */ protected void doCapture () { String firstName, lastName, email, passwd, institutionName, major, degree, GPA, userName, appStatus, tranStatus, institutionID; msg=""; String capture = runtimeData.getParameter("uPGA_capture"); if (capture != null) { if (capture.equals("newApplication")) { firstName = runtimeData.getParameter("firstName"); lastName = runtimeData.getParameter("lastName"); email = runtimeData.getParameter("email"); passwd = runtimeData.getParameter("passwd"); // First name, last name and password are all required if (passwd == null || passwd.equals("")) { msg="Please enter a password"; action = "createNew"; applicant.setPasswd(""); } else { applicant.setPasswd(passwd.trim()); applicant.setPasswdMask(passwd.trim()); } if (email != null) { applicant.setEmail(email.trim()); } if (lastName == null || lastName.equals("")) { msg="Please enter your last name"; action = "createNew"; applicant.setLastName(""); } else { applicant.setLastName(lastName.trim()); } if (firstName == null || firstName.equals("")) { msg="Please enter your first name"; action = "createNew"; applicant.setFirstName(""); } else { applicant.setFirstName(firstName.trim()); } applicant.setID("FORM"); applicant.setStatus(SUBMITTED); } else if (capture.equals("addInstitutions")) { institutionName = runtimeData.getParameter("institutionName"); major = runtimeData.getParameter("major"); degree = runtimeData.getParameter("degree"); GPA = runtimeData.getParameter("GPA"); ui = (UserInstitution)applicant.getUserInstitution("0"); if (ui == null) { ui = new UserInstitution(); } // Institution name is required if (institutionName == null || institutionName.equals("")) { msg = "Please enter an institution name"; action = "institutionForm"; ui.setInstitutionName(""); } else { ui.setInstitutionName(institutionName.trim()); } if (major != null) { ui.setMajor(major.trim()); } if (degree != null) { ui.setDegree(degree.trim()); } if (GPA != null) { ui.setGPA(GPA.trim()); } ui.setID("0"); ui.setTranscriptStatus("No"); applicant.addInstitution(ui); } else if (capture.equals("updateStatus")) { appStatus = runtimeData.getParameter("appStatus"); int oldAppStatus = applicant.getStatus(); if (appStatus != null) { for (int i=0; i < appStatusDesc.length; i++) { if (appStatus.equals(appStatusDesc[i])) { applicant.setStatus(i); if (oldAppStatus != i) { cState.dirtyData=true; if (i == COMMITTEE_READY) notify = true; } } } } } else if (capture.equals("updateInst")) { tranStatus = runtimeData.getParameter("tranStatus"); institutionID = runtimeData.getParameter("institutionID"); ui = (UserInstitution)applicant.getUserInstitution(institutionID.trim()); String oldTranStatus = ui.getTranscriptStatus(); if (oldTranStatus != tranStatus) cState.dirtyData=true; ui.setTranscriptStatus(tranStatus); } } } /** * Controller method that reacts to the action parameter. * @exception PortalException */ protected void doAction () throws PortalException { Element applicantE = null; if (action != null) { if (action.equals("createNew")) { state = NEW_APPLICATION_STATE; applicantManagerDoc = getApplicantDoc(); } else if (action.equals("addInstitution")) { state = INSTITUTION_STATE; ui = (UserInstitution)applicant.getInstitution("0"); if (ui != null) { ui.setID(Integer.toString(applicant.getNextuiID())); applicant.addInstitution(ui); applicant.removeInstitution("0"); } applicantManagerDoc = getApplicantDoc(); } else if (action.equals("removeInstitution")) { state = INSTITUTION_STATE; String institutionID = runtimeData.getParameter("institutionID"); applicant.removeInstitution(institutionID.trim()); applicantManagerDoc = getApplicantDoc(); } else if (action.equals("institutionForm")) { state = INSTITUTION_STATE; applicantManagerDoc = getApplicantDoc(); } else if (action.equals("review")) { state = REVIEW_APPLICATION_STATE; applicantManagerDoc = getApplicantDoc(); } else if (action.equals("viewDetails")) { state=REVIEW_DETAILS_STATE; cState.currentApp = runtimeData.getParameter("appUser"); applicantE = ApplicantManager.getApplicantDetails(cState.currentApp); applicant.setFromXML(applicantE); } else if (action.equals("checkStatus")) { // Check if user has submitted an application applicantE = ApplicantManager.getApplicantDetails(cState.portalUser); if (applicantE != null) { applicant.setFromXML(applicantE); state = CHECK_STATUS_STATE; applicantManagerDoc = getApplicantDoc(); } else { msg = "No application exists for " + cState.portalUser + "."; } } else if (action.equals("listAll")) { cState.appSet = "0"; state = APPLICANT_LIST_STATE; applicantManagerDoc = getApplicantManagerDoc(modChanSettings); } else if (action.equals("listEval")) { cState.appSet = "2"; state = EVAL_LIST_STATE; applicantManagerDoc = getApplicantManagerDoc(modChanSettings); } else if (action.equals("submit")) { try { applicantE = applicant.getDocument(applicantManagerDoc); ApplicantManager.listApplicant(applicantE); resetSettings(); } catch (Exception e) { throw new PortalException(e); } state=DEFAULT_APP_STATE; msg="Your application has been submitted."; } else if (action.equals("updateInst")) { try { applicantManagerDoc = getApplicantDoc(); } catch (Exception e) { throw new PortalException(e); } state=REVIEW_DETAILS_STATE; } else if (action.equals("update")) { if (cState.dirtyData == true) { try { applicantE = applicant.getDocument(applicantManagerDoc); ApplicantManager.listApplicant(applicantE); if (notify == true) ApplicantManager.notifyCommittee(applicantE); resetSettings(); } catch (Exception e) { throw new PortalException(e); } msg="Application updated for user " + cState.currentApp + "."; cState.dirtyData = false; } applicantManagerDoc = getApplicantManagerDoc(modChanSettings); state=APPLICANT_LIST_STATE; } else if (action.equals("changePage")) { String newPage = runtimeData.getParameter("newPage"); if (newPage != null) { modChanSettings.setCurrentPage(newPage); applicantManagerDoc = getApplicantManagerDoc(modChanSettings); } } else if (action.equals("changeRecordsPerPage")) { String recordsPerPage = runtimeData.getParameter("recordsPerPage"); if (recordsPerPage != null) { // Figure out what page we should be on based on the change in records per page. try { int oldPage = Integer.parseInt(modChanSettings.getCurrentPage()); int oldRecordsPerPage = Integer.parseInt(modChanSettings.getRecordsPerPage()); int recsPerPage = Integer.parseInt(recordsPerPage); if (recsPerPage > 0 && recsPerPage != oldRecordsPerPage) { // Thanks to jweight@campuspipeline.com for the following formula: String newPage = String.valueOf(((((oldPage-1)*oldRecordsPerPage)+1)/(recsPerPage)+1)); modChanSettings.setCurrentPage(newPage); modChanSettings.setRecordsPerPage(recordsPerPage); applicantManagerDoc = getApplicantManagerDoc(modChanSettings); } } catch (NumberFormatException nfe) { // do nothing here, just leave the current page as is. } } } } if (action == null || action.equals("cancel")) { state = canEdit ? DEFAULT_LIST_STATE : DEFAULT_APP_STATE; resetSettings(); applicantManagerDoc = DocumentFactory.getNewDocument(); } } protected Document getApplicantDoc () throws PortalException { Element applicantManager, application, applicantE, constantsE; applicantManagerDoc = DocumentFactory.getNewDocument(); // Add the top level to the document applicantManager = applicantManagerDoc.createElement("manageApplicants"); applicantManagerDoc.appendChild(applicantManager); // Add a fragment to constantsE = getConstantsXML(applicantManagerDoc); constantsE = (Element)applicantManagerDoc.importNode(constantsE, true); applicantManager.appendChild(constantsE); application = applicantManagerDoc.createElement("application"); applicantManager.appendChild(application); applicantE = applicant.getDocument(applicantManagerDoc); applicantE = (Element)applicantManagerDoc.importNode(applicantE, true); application.appendChild(applicantE); return applicantManagerDoc; } /** * Produces an XML document used as an input to * this channel's XSLT transformation. * @param modChanSettings * @return * @exception PortalException */ protected Document getApplicantManagerDoc (ModifyChannelSettings modChanSettings) throws PortalException { Document applicantManagerDoc = DocumentFactory.getNewDocument(); // Add the top level to the document Element applicantManager = applicantManagerDoc.createElement("manageApplicants"); applicantManagerDoc.appendChild(applicantManager); // Get the applicant listing Document applicantListingDoc = ApplicantManager.getApplicantListing(); // Set the listing ID attribute to "-1" Element listing = applicantListingDoc.getDocumentElement(); listing.setAttribute("ID", "-1"); // Add the to Element applicantListing = (Element)applicantManagerDoc.importNode(applicantListingDoc.getDocumentElement(),true); applicantManager.appendChild(applicantListing); // Add a fragment to Element constantsE = getConstantsXML(applicantManagerDoc); constantsE = (Element)applicantManagerDoc.importNode(constantsE, true); applicantManager.appendChild(constantsE); // Add a fragment to appendModifyChannelSettings(applicantManager, modChanSettings); return applicantManagerDoc; } /** * Return an xml representation of constants used in this channel */ public Element getConstantsXML(Document doc) { Element constants = doc.createElement("constants"); // Add degrees Element degrees = doc.createElement("degrees"); constants.appendChild(degrees); for (int i=0; i < degreeValues.length; i++) { Element degree = doc.createElement("degree"); degree.setAttribute("description", degreeValues[i] + ""); degrees.appendChild(degree); } // Add application statuses Element appStatuses = doc.createElement("appStatuses"); constants.appendChild(appStatuses); for (int i=0; i < appStatusDesc.length; i++) { Element status = doc.createElement("status"); status.setAttribute("number", i + ""); status.setAttribute("description", appStatusDesc[i] + ""); appStatuses.appendChild(status); } // Add transcript statuses Element tranStatuses = doc.createElement("tranStatuses"); constants.appendChild(tranStatuses); for (int i=0; i < tranStatusValues.length; i++) { Element status = doc.createElement("status"); status.setAttribute("description", tranStatusValues[i] + ""); tranStatuses.appendChild(status); } return constants; } protected static void appendModifyChannelSettings (Element applicantManager, ModifyChannelSettings modChanSettings) { Document doc = applicantManager.getOwnerDocument(); Element userSettingsE = doc.createElement("userSettings"); Element modifyView = doc.createElement("modifyView"); userSettingsE.appendChild(modifyView); Element recordsPerPageE = doc.createElement("recordsPerPage"); recordsPerPageE.appendChild(doc.createTextNode(modChanSettings.getRecordsPerPage())); modifyView.appendChild(recordsPerPageE); Element currentPageE = doc.createElement("currentPage"); currentPageE.appendChild(doc.createTextNode(modChanSettings.getCurrentPage())); modifyView.appendChild(currentPageE); applicantManager.appendChild(userSettingsE); } /** * Keeps track of page settings for APPLICANT_LIST_STATE */ protected class ModifyChannelSettings { private String recordsPerPage; private String currentPage; /** * put your documentation comment here */ protected ModifyChannelSettings () { recordsPerPage = "8"; currentPage = "1"; } // Accessor methods protected String getRecordsPerPage () { return recordsPerPage; } protected String getCurrentPage () { return currentPage; } protected void setRecordsPerPage (String recordsPerPage) { this.recordsPerPage = recordsPerPage; } protected void setCurrentPage (String currentPage) { this.currentPage = currentPage; } } }