/* emailRedirectCustom.java Custom plug-in for managing fields in the email redirect object type. Created: 25 June 1999 Module By: Jonathan Abbey, jonabbey@arlut.utexas.edu ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2014 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.util.Vector; import arlut.csd.ganymede.common.Invid; import arlut.csd.ganymede.common.ReturnVal; import arlut.csd.ganymede.common.SchemaConstants; import arlut.csd.ganymede.server.DBEditObject; import arlut.csd.ganymede.server.DBEditSet; import arlut.csd.ganymede.server.DBField; import arlut.csd.ganymede.server.DBObject; import arlut.csd.ganymede.server.DBObjectBase; import arlut.csd.ganymede.server.Ganymede; import arlut.csd.ganymede.server.GanymedeSession; import arlut.csd.ganymede.server.StringDBField; /*------------------------------------------------------------------------------ class emailRedirectCustom ------------------------------------------------------------------------------*/ /** * Custom plug-in for managing fields in the email redirect object type. */ public class emailRedirectCustom extends DBEditObject implements SchemaConstants, emailRedirectSchema { /** * * Customization Constructor * */ public emailRedirectCustom(DBObjectBase objectBase) { super(objectBase); } /** * * Create new object constructor * */ public emailRedirectCustom(DBObjectBase objectBase, Invid invid, DBEditSet editset) { super(objectBase, invid, editset); } /** * * Check-out constructor, used by DBObject.createShadow() * to pull out an object for editing. * */ public emailRedirectCustom(DBObject original, DBEditSet editset) { super(original, editset); } /** * <p>This method is used to control whether or not it is acceptable to * make a link to the given field in this * {@link arlut.csd.ganymede.server.DBObject DBObject} type when the * user only has editing access for the source * {@link arlut.csd.ganymede.server.InvidDBField InvidDBField} and not * the target.</p> * * <p>This version of anonymousLinkOK takes additional parameters * to allow an object type to decide that it does or does not want * to allow a link based on what field of what object wants to link * to it.</p> * * <p>By default, the 3 variants of the DBEditObject * anonymousLinkOK() method are chained together, so that the * customizer can choose which level of detail he is interested in. * {@link arlut.csd.ganymede.server.InvidDBField InvidDBField}'s * {@link * arlut.csd.ganymede.server.InvidDBField#bind(arlut.csd.ganymede.common.Invid,arlut.csd.ganymede.common.Invid,boolean) * bind()} method calls this version. This version calls the three * parameter version, which calls the two parameter version, which * returns false by default. Customizers can implement any of the * three versions, but unless you maintain the version chaining * yourself, there's no point to implementing more than one of * them.</p> * * <p>Note that the {@link * arlut.csd.ganymede.server.DBEditObject#choiceListHasExceptions(arlut.csd.ganymede.server.DBField) * choiceListHasExceptions()} method will call this version of * anonymousLinkOK() with a null targetObject, to determine that the * client should not use its cache for an InvidDBField's choices. * Any overriding done of this method must be able to handle a null * targetObject, or else an exception will be thrown * inappropriately.</p> * * <p>The only reason to consult targetObject in any case is to * allow or disallow anonymous object linking to a field based on * the current state of the target object. If you are just writing * generic anonymous linking rules for a field in this object type, * targetObject won't concern you anyway. If you do care about the * targetObject's state, though, you have to be prepared to handle * a null valued targetObject.</p> * * <p><b>*PSEUDOSTATIC*</b></p> * * @param targetObject The object that the link is to be created in (may be null) * @param targetFieldID The field that the link is to be created in * @param sourceObject The object on the other side of the proposed link * @param sourceFieldID The field on the other side of the proposed link * @param gsession Who is trying to do this linking? */ @Override public boolean anonymousLinkOK(DBObject targetObject, short targetFieldID, DBObject sourceObject, short sourceFieldID, GanymedeSession gsession) { // if someone tries to put this redirect in a email list, // let them. if ((targetFieldID == SchemaConstants.BackLinksField) && (sourceObject.getTypeID() == emailListSchema.BASE) && // email list (sourceFieldID == emailListSchema.MEMBERS)) // email list members { return true; } // the default anonymousLinkOK() method returns false return super.anonymousLinkOK(targetObject, targetFieldID, sourceObject, sourceFieldID, gsession); } /** * <p>This method allows the DBEditObject to have executive approval * of any vector add operation, and to take any special actions in * reaction to the add.. if this method returns null or a success * code in its ReturnVal, the DBField that called us is guaranteed * to proceed to make the change to its vector. If this method * returns a non-success code in its ReturnVal, the DBField that * called us will not make the change, and the field will be left * unchanged.</p> * * <p>The <field> parameter identifies the field that is * requesting approval for item deletion, and the <value> * parameter carries the value to be added.</p> * * <p>The DBField that called us will take care of all standard * checks on the operation (including vector bounds, etc.) before * calling this method. Under normal circumstances, we won't need * to do anything here.</p> * * @return A ReturnVal indicating success or failure. May * be simply 'null' to indicate success if no feedback need * be provided. */ @Override public ReturnVal finalizeAddElement(DBField field, Object value) { if (field.getID() != emailRedirectSchema.TARGETS) { return null; } Vector<String> newItemVect = new Vector<String>(); newItemVect.add((String)value); if (!fitsInNIS(newItemVect)) { return Ganymede.createErrorDialog(this.getGSession(), "Overflow error", "The address that you are attempting to add to the " + getTypeName() + " email redirection cannot all fit. No NIS email alias definition in the laboratory's " + "network can be longer than 1024 characters."); } return null; } /** * <p>This method allows the DBEditObject to have executive approval * of any vector-vector add operation, and to take any special * actions in reaction to the add.. if this method returns null or a * success code in its ReturnVal, the DBField that called us is * guaranteed to proceed to make the change to its vector. If this * method returns a non-success code in its ReturnVal, the DBField * that called us will not make the change, and the field will be * left unchanged.</p> * * <p>The <field> parameter identifies the field that is * requesting approval for item deletion, and the <submittedValues> * parameter carries the values to be added.</p> * * <p>The DBField that called us will take care of all standard * checks on the operation (including vector bounds, etc.) before * calling this method. Under normal circumstances, we won't need * to do anything here.</p> * * @return A ReturnVal indicating success or failure. May * be simply 'null' to indicate success if no feedback need * be provided. */ @Override public ReturnVal finalizeAddElements(DBField field, Vector submittedValues) { if (field.getID() != emailRedirectSchema.TARGETS) { return null; } if (!fitsInNIS((Vector<String>)submittedValues)) { return Ganymede.createErrorDialog(this.getGSession(), "Overflow error", "The " + submittedValues.size() + " addresses that you are attempting to add to the " + getTypeName() + " email redirection cannot all fit. No NIS email list in the laboratory's " + "network can be longer than 1024 characters when converted to an " + "NIS email alias definition."); } return null; } /** * <p>This method takes a vector of new items and returns true if the new items should * be able to fit in the NIS line built from this emailList object.</p> */ private boolean fitsInNIS(Vector<String> newItemVect) { StringDBField targets = getStringField(emailRedirectSchema.TARGETS); int totalLength = targets.getValueString().length(); for (String label: newItemVect) { totalLength += label.length() + 2; // need a comma and space if (totalLength >= 1024) { return false; } } return true; } }