/* userCategoryWizard.java A wizard to manage changes in the user object's user category field. Created: 13 October 1998 Module By: Jonathan Abbey, jonabbey@arlut.utexas.edu ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2013 The University of Texas at Austin Ganymede is a registered trademark of The University of Texas at Austin Contact information Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 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 2 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. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package arlut.csd.ganymede.gasharl; import java.rmi.RemoteException; import java.util.Calendar; import java.util.Date; import java.util.Vector; import arlut.csd.ganymede.common.GanyPermissionsException; import arlut.csd.ganymede.common.Invid; import arlut.csd.ganymede.common.ReturnVal; import arlut.csd.ganymede.common.SchemaConstants; import arlut.csd.ganymede.server.DBField; import arlut.csd.ganymede.server.DBObject; import arlut.csd.ganymede.server.Ganymede; import arlut.csd.ganymede.server.GanymedeSession; import arlut.csd.ganymede.server.GanymediatorWizard; /*------------------------------------------------------------------------------ class userCategoryWizard ------------------------------------------------------------------------------*/ /** * A wizard to handle the wizard interactions required when a user's category is * changed. This wizard takes care of asking for everything required to * set and/or change a user category. * * @see arlut.csd.ganymede.common.ReturnVal * @see arlut.csd.ganymede.rmi.Ganymediator */ public class userCategoryWizard extends GanymediatorWizard { final static boolean debug = true; // --- /** * The user-level session context that this wizard is acting in. This * object is used to handle necessary checkpoint/rollback activity by * this wizard, as well as to handle any necessary label lookups. */ GanymedeSession session; /** * Keeps track of the state of the wizard. Each time respond() is called, * state is checked to see what results from the user are expected and * what the appropriate dialogs or actions to perform in turn are.<br> * * state is also used by the userCustom object to make sure that * we have finished our interactions with the user when we tell the * user object to go ahead and remove the group. <br> * * <pre> * Values: * 1 - Wizard has been initialized, initial explanatory dialog * has been generated. * DONE (99) - Wizard has approved the proposed action, and is signalling * the user object code that it is okay to proceed with the * action without further consulting this wizard. * </pre> */ // int state; from superclass.. we don't want to shadow it here /** * The actual user object that this wizard is acting on */ userCustom userObject; /** * The username field in the user object that we may change */ DBField field; /** * The invid for the new category for the user */ Invid newCatInvid; /** * The proposed new category for the user */ DBObject newCategory; /** * The invid for the user's old category */ Invid oldCatInvid; /** * The old category for the user */ DBObject oldCategory; /** * Do we need to get an explanation from the user about this * change? */ boolean notificationRequired = false; /** * List of email addresses to send the change notification to. */ Vector<String> notifyList = null; /** * Do we need to set an expiration date? */ boolean needExpireDate = false; /** * Date that the user will be expired. */ Date expirationDate = null; /** * Latest date that the user's expiration may be set to. */ Date terminationDate = null; /** * The user's explanation of the category change. */ String justification = null; /* -- */ /** * * Constructor * */ /** * * This constructor registers the wizard as an active wizard * on the provided session. * * @param session The GanymedeSession object that this wizard will * use to interact with the Ganymede data store. * @param userObject The user object that this wizard will work with. * @param oldInvid The old category's Invid, if any * @param newInvid The new category's invid * */ public userCategoryWizard(GanymedeSession session, userCustom userObject, Invid oldInvid, Invid newInvid) throws RemoteException { super(session); // register ourselves this.session = session; this.userObject = userObject; this.newCatInvid = newInvid; this.oldCatInvid = oldInvid; if (oldInvid != null) { this.oldCategory = userObject.getDBSession().viewDBObject(oldInvid); } if (newInvid != null) { this.newCategory = userObject.getDBSession().viewDBObject(newInvid); } if (oldCategory != null) { if (debug) { System.err.println("userCategoryWizard(): oldCategory = " + oldCategory.getLabel()); } Boolean notifyBoolean = (Boolean) oldCategory.getFieldValueLocal(userCategorySchema.APPROVALREQ); if (notifyBoolean != null && notifyBoolean.booleanValue()) { this.notificationRequired = true; Vector<String> notifyList2 = (Vector<String>) oldCategory.getFieldValuesLocal(userCategorySchema.APPROVALLIST); this.notifyList = arlut.csd.Util.VectorUtils.union(this.notifyList, notifyList2); } } else if (debug) { System.err.println("userCategoryWizard(): oldCategory = null"); } if (newCategory != null) { if (debug) { System.err.println("userCategoryWizard(): newCategory = " + newCategory.getLabel()); } Boolean notifyBoolean = (Boolean) newCategory.getFieldValueLocal(userCategorySchema.APPROVALREQ); if (notifyBoolean != null && notifyBoolean.booleanValue()) { this.notificationRequired = true; Vector<String> notifyList2 = (Vector<String>) newCategory.getFieldValuesLocal(userCategorySchema.APPROVALLIST); this.notifyList = arlut.csd.Util.VectorUtils.union(this.notifyList, notifyList2); } // get the number of days in the future that the user's // expiration may be set to. Integer timelimit = (Integer) newCategory.getFieldValueLocal(userCategorySchema.LIMIT); if (timelimit != null) { int days = timelimit.intValue(); if (debug) { System.err.println("userCategoryWizard(): termination limit days = " + days); } Date nowDate = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(nowDate); cal.add(Calendar.DATE, days); this.terminationDate = cal.getTime(); if (debug) { System.err.println("userCategoryWizard(): termination limit = " + terminationDate.toString()); } } else if (debug) { System.err.println("userCategoryWizard(): no limit set"); } Boolean expireBoolean = (Boolean) newCategory.getFieldValueLocal(userCategorySchema.EXPIRE); if ((expireBoolean != null && expireBoolean.booleanValue()) || (terminationDate != null)) { this.needExpireDate = true; } } else if (debug) { System.err.println("userCategoryWizard(): newCategory = null"); } if (debug) { if (needExpireDate) { System.err.println("userCategoryWizard(): needExpireDate is true"); } else { System.err.println("userCategoryWizard(): needExpireDate is false"); } } // what is the user's expiration set to now? this.expirationDate = (Date) userObject.getFieldValueLocal(SchemaConstants.ExpirationField); } /** * * This method provides a default response if a user * hits cancel on a wizard dialog. This should be * subclassed if a wizard wants to provide a more * detailed cancel response. * */ public ReturnVal cancel() { return fail("Category Change Cancelled", "Category Change Cancelled", "OK", null, "ok.gif"); } /** * <P>This method starts off the wizard process.</P> */ public ReturnVal processDialog0() { ReturnVal retVal = null; StringBuffer tempBuffer = new StringBuffer(); /* -- */ if ((oldCatInvid == null) && !notificationRequired && (notifyList == null) && !needExpireDate) { // don't need to ask the user anything, let things go on. return null; } if (oldCatInvid == null) { tempBuffer.append("In order to put user "); tempBuffer.append(userObject.getLabel()); tempBuffer.append(" in category "); tempBuffer.append(newCategory.getLabel()); tempBuffer.append(", "); if (needExpireDate) { tempBuffer.append("you need to set an expiration date for this user"); if (notificationRequired) { tempBuffer.append(" and enter a short justification for this classification."); } } else if (notificationRequired) { tempBuffer.append(" you must enter a short justification for this classification."); } } else { tempBuffer.append("In order to move user "); tempBuffer.append(userObject.getLabel()); tempBuffer.append(" from category "); tempBuffer.append(oldCategory.getLabel()); tempBuffer.append(" to category "); tempBuffer.append(newCategory.getLabel()); tempBuffer.append(", "); if (needExpireDate) { tempBuffer.append("you need to set an expiration date for this user"); if (notificationRequired) { tempBuffer.append(" and enter a short justification for the new classification."); } } else if (notificationRequired) { tempBuffer.append(" you must enter a short justification for the new classification."); } } retVal = continueOn("User Category Change Dialog", tempBuffer.toString(), "Next", "Cancel", "question.gif"); if (!needExpireDate) { setNextState(2); // from GanymediatorWizard } return retVal; } /** * * The client will call us here with no params.. this step * will prompt for the expire date for this user. * */ public ReturnVal processDialog1() { ReturnVal retVal = null; StringBuffer tempBuffer = new StringBuffer(); /* -- */ if (debug) { System.err.println("Entering userCategoryWizard.processDialog1()"); } tempBuffer.append("Category "); tempBuffer.append(newCategory.getLabel()); tempBuffer.append(" requires that an expiration date be set."); if (terminationDate != null) { tempBuffer.append(" You may set this expiration date to any day on or before\n\n"); tempBuffer.append(terminationDate.toString()); } retVal = continueOn("Category Requires an Expiration", tempBuffer.toString(), "Next", "Cancel", "question.gif"); retVal.getDialog().addDate("Expiration Date:", expirationDate, terminationDate); return retVal; } /** * * Process expirationDate if needed, prompt for explanation if * needed. * */ public ReturnVal processDialog2() { ReturnVal retVal = null; /* -- */ if (debug) { System.err.println("Entering userCategoryWizard.processDialog2()"); } if (needExpireDate) { if (debug) { System.err.println("userCategoryWizard.processDialog2(): processing date"); } this.expirationDate = (Date) getParam("Expiration Date:"); if (this.expirationDate == null) { return fail("Category Change Cancelled", "Error, an expiration date is required to put " + userObject.getLabel() + " into category " + newCategory.getLabel() + ".", "OK", null, "ok.gif"); } } // if we need to get an explanation from the user, ask for it here. if (notificationRequired) { if (debug) { System.err.println("userCategoryWizard.processDialog2(): prompting for notification"); } StringBuffer tempBuffer = new StringBuffer(); tempBuffer.append("Before you can change "); tempBuffer.append(userObject.getLabel()); tempBuffer.append("'s classification, you need to provide a short justification of "); if (oldCatInvid == null) { tempBuffer.append("this user's classification."); } else { tempBuffer.append("this user's change in classification."); } retVal = continueOn("Justification for Category Change", tempBuffer.toString(), "Next", "Cancel", "question.gif"); retVal.getDialog().addMultiString("Reason:", null); return retVal; } else { return doIt(); } } /** * * Process explanation. * */ public ReturnVal processDialog3() { if (debug) { System.err.println("Entering userCategoryWizard.processDialog3()"); } this.justification = (String) getParam("Reason:"); if (this.justification == null || this.justification.equals("")) { return fail("Category Change Cancelled", "Error, an explanation is required to put " + userObject.getLabel() + " into category " + newCategory.getLabel() + ".", "OK", null, "ok.gif"); } else if (debug) { System.err.println("userCategoryWizard.processDialog3(): justification = \n" + justification); } return doIt(); } /** * * Do the thing. * */ public ReturnVal doIt() { ReturnVal retVal; /* -- */ if (debug) { System.err.println("Entering userCategoryWizard.doIt()"); } // let the userCustom object know that we approve the category change. state = DONE; // if we can't do both of these, we'll just leave it up to the // user to hit cancel. We could do a checkpoint here, but it // probably isn't necessary.. the category change is the only // thing likely to fail, if the categoryCustom object doesn't have // anonymousLinkOK() enabled. if (debug) { if (newCatInvid != null) { System.err.println("userCategoryWizard.doIt(): setting category to " + newCatInvid); } else { System.err.println("userCategoryWizard.doIt(): setting category to null"); } } try { retVal = userObject.setFieldValue(userCustom.CATEGORY, newCatInvid); } catch (GanyPermissionsException ex) { return Ganymede.createErrorDialog(this.session, "permissions", "permissions error setting category. " + ex); } if (retVal != null && !retVal.didSucceed()) { return retVal; } if (debug) { if (expirationDate != null) { System.err.println("userCategoryWizard.doIt(): setting expiration to " + expirationDate); } else { System.err.println("userCategoryWizard.doIt(): setting date to null"); } } try { retVal = userObject.setFieldValue(SchemaConstants.ExpirationField, expirationDate); } catch (GanyPermissionsException ex) { return Ganymede.createErrorDialog(this.session, "permissions", "permissions error setting expiration date " + ex); } if (retVal != null && !retVal.didSucceed()) { return retVal; } StringBuffer tempBuffer = new StringBuffer(); if (oldCatInvid == null) { tempBuffer.append("User "); tempBuffer.append(userObject.getLabel()); tempBuffer.append(" has been placed in category "); tempBuffer.append(newCategory.getLabel()); tempBuffer.append("."); } else { tempBuffer.append("User "); tempBuffer.append(userObject.getLabel()); tempBuffer.append(" has been reclassified as "); tempBuffer.append(newCategory.getLabel()); tempBuffer.append("."); } if (justification != null) { tempBuffer.append("\n\n"); tempBuffer.append(justification); } if (notifyList != null) { userObject.getEditSet().logMail(notifyList, "CategorySet: User " + userObject.getLabel() + " in " + newCategory.getLabel(), tempBuffer.toString()); } retVal = success("Category Changed", tempBuffer.toString(), "OK", null, "ok.gif"); retVal.addRescanField(userObject.getInvid(), SchemaConstants.ExpirationField); return retVal; } }