package org.jscsi.target.settings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jscsi.target.settings.entry.Entry;
/**
* This is an abstract parent-class to {@link ConnectionSettingsNegotiator} and
* {@link SessionSettingsNegotiator}. The former one is in charge of all {@link Entry} objects with
* connection-specific parameters, the latter is in
* charge of all session-wide parameter {@link Entry} objects.
*
* @author Andreas Ergenzinger
*/
public abstract class SettingsNegotiator {
/**
* All {@link Entry} objects managed by this {@link SettingsNegotiator}.
* <p>
* These elements might change consecutively during parameter negotiations.
*/
protected List<Entry> entries = new ArrayList<Entry>();
/**
* A back-up copy of the last consistent state of all elements in {@link #entries} or <code>null</code>.
*
* @see #backUpEntries
* @see #commitOrRollBackChanges(boolean)
*/
protected List<Entry> backUpEntries;
/**
* Returns the first {@link Entry} in the specified {@link Collection} for
* which {@link Entry#matchKey(String)} returns <code>true</code>.
*
* @param key
* the key String identifying the {@link Entry}
* @param entries
* a {@link Collection} of {@link Entry} objects.
* @return a matching {@link Entry} or null, if no such {@link Entry} exists
*/
static final Entry getEntry(final String key, final Collection<Entry> entries) {
for (Entry e : entries)
if (e.matchKey(key))
return e;
return null;
}
/**
* Returns a deep copy of the passed {@link List} with exact copies of all
* contained {@link Entry} objects.
*
* @param entries
* the {@link List} to copy
* @return a copy of <i>entries</i>
*/
protected static final List<Entry> copy(final List<Entry> entries) {
if (entries == null)
return null;
final ArrayList<Entry> copy = new ArrayList<Entry>();
for (Entry e : entries)
copy.add(e.copy());
return copy;
}
/**
* The abstract constructor.
* <p>
* Calls {@link #initializeEntries()}.
*/
public SettingsNegotiator() {
initializeEntries();
}
/**
* Stores an exact copy of {@link #entries} in {@link #backUpEntries}.
*/
protected final void backUpEntries() {
backUpEntries = copy(entries);
}
/**
* This method must be called at the end of a parameter negotiation task,
* either to roll back any changes that must not take effect, or in order to
* ensure that consecutive negotiations are carried out correctly.
*
* @param commitChanges
* <code>true</code> if and only if the negotiated changes to the
* elements in {@link #entries} are to be remembered.
*/
protected final void commitOrRollBackChanges(final boolean commitChanges) {
if (commitChanges)
for (Entry e : entries)
// allow renegotiation where allowed
e.resetAlreadyNegotiated();
else
entries = backUpEntries;// roll back
backUpEntries = null;// won't be needed anymore
}
/**
* Adds a properly initialized {@link Entry} object to {@link #entries} for
* every parameter managed by this {@link SettingsNegotiator}.
*/
protected abstract void initializeEntries();
/**
* Checks constraints that cannot be checked at the {@link Entry} level,
* e.g. because they depend on the values of multiple parameters.
*
* @return <code>true</code> if everything is fine, <code>false</code> if
* that is not the case
*/
public abstract boolean checkConstraints();
}