package org.jscsi.target.settings.entry; import org.jscsi.parser.ProtocolDataUnit; import org.jscsi.parser.login.LoginStage; import org.jscsi.target.connection.stage.fullfeature.TextNegotiationStage; import org.jscsi.target.connection.stage.login.LoginOperationalParameterNegotiationStage; /** * Instances of this class are used by {@link Entry} objects to determine during * which circumstances a parameter may be negotiated or declared. * <p> * The factors to consider are: * <ul> * <li>the current stage of the connection</li> * <li>whether that connection is the leading connection, i.e. the initial connection in the enclosing * session.</li> * <li>if the <i>key-value</i> pair relating to the parameter was part of the first {@link ProtocolDataUnit} * sent over the connection</i> * </ul> * * @author Andreas Ergenzinger */ public enum Use { /** * The parameter may be negotiated by a leading connection in the * {@link LoginOperationalParameterNegotiationStage} only. */ LEADING_LOPNS, /** * The parameter may be negotiated by any connection in the * {@link LoginOperationalParameterNegotiationStage}. */ LOPNS, /** * The parameter may be negotiated by any connection in the * {@link LoginOperationalParameterNegotiationStage} or in the Full Feature * Phase (specifically the {@link TextNegotiationStage}). */ LOPNS_AND_FFP, /** * The parameter may be negotiated by any connection in the Full Feature * Phase (specifically the {@link TextNegotiationStage}). */ FFP, /** * The parameter may only be declared in the initial {@link ProtocolDataUnit}. */ INITIAL, /** * The parameter may only be declared in the initial {@link ProtocolDataUnit} or by any PDU sent as part * of the {@link TextNegotiationStage} in the Full Feature Phase. */ INITIAL_AND_FFP; /** * This method can be used for checking if a specified {@link Use} permits * negotiating its associated parameter given a situation described by * several parameters. * * @param use * describes the conditions * @param loginStage * specifies the stage of phase * @param leadingConnection * <code>true</code> if and only if the connection is the leading * connection of its session * @param initialPdu * <code>true</code> if and only if the {@link ProtocolDataUnit} is the first PDU sent over the * connection * @return <code>true</code> if and only if all requirements of the * <i>use</i> parameter have been met */ private static boolean checkUse(final Use use, final LoginStage loginStage, final boolean leadingConnection, final boolean initialPdu) { switch (use) { case LEADING_LOPNS: if (leadingConnection && loginStage == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) return true; return false; case LOPNS: if (loginStage == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) return true; return false; case LOPNS_AND_FFP: if (loginStage == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION || loginStage == LoginStage.FULL_FEATURE_PHASE) return true; return false; case FFP: if (loginStage == LoginStage.FULL_FEATURE_PHASE) return true; return false; case INITIAL_AND_FFP: if (initialPdu && loginStage == LoginStage.FULL_FEATURE_PHASE) return true; // fall through case INITIAL: if (initialPdu && (loginStage == LoginStage.SECURITY_NEGOTIATION || loginStage == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION)) return true; return false; default: return false;// unreachable } } /** * This method can be used for checking if this {@link Use} instance permits * negotiating its associated parameter given a situation described by the * passed parameters. * * @param loginStage * specifies the stage of phase * @param leadingConnection * <code>true</code> if and only if the connection is the leading * connection of its session * @param initialPdu * <code>true</code> if and only if the {@link ProtocolDataUnit} is the first PDU sent over the * connection * @return <code>true</code> if and only if all requirements of this {@link Use} instance have been met */ public boolean checkUse(final LoginStage loginStage, final boolean leadingConnection, final boolean initialPdu) { return checkUse(this, loginStage, leadingConnection, initialPdu); } }