View Javadoc

1   package org.jscsi.target.settings;
2   
3   
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.List;
7   
8   import org.jscsi.target.settings.entry.Entry;
9   
10  
11  /**
12   * This is an abstract parent-class to {@link ConnectionSettingsNegotiator} and {@link SessionSettingsNegotiator}. The
13   * former one is in charge of all {@link Entry} objects with connection-specific parameters, the latter is in charge of
14   * all session-wide parameter {@link Entry} objects.
15   * 
16   * @author Andreas Ergenzinger
17   */
18  public abstract class SettingsNegotiator {
19  
20      /**
21       * All {@link Entry} objects managed by this {@link SettingsNegotiator}.
22       * <p>
23       * These elements might change consecutively during parameter negotiations.
24       */
25      protected List<Entry> entries = new ArrayList<Entry>();
26  
27      /**
28       * A back-up copy of the last consistent state of all elements in {@link #entries} or <code>null</code>.
29       * 
30       * @see #backUpEntries
31       * @see #commitOrRollBackChanges(boolean)
32       */
33      protected List<Entry> backUpEntries;
34  
35      /**
36       * Returns the first {@link Entry} in the specified {@link Collection} for which {@link Entry#matchKey(String)}
37       * returns <code>true</code>.
38       * 
39       * @param key the key String identifying the {@link Entry}
40       * @param entries a {@link Collection} of {@link Entry} objects.
41       * @return a matching {@link Entry} or null, if no such {@link Entry} exists
42       */
43      static final Entry getEntry (final String key, final Collection<Entry> entries) {
44          for (Entry e : entries)
45              if (e.matchKey(key)) return e;
46          return null;
47      }
48  
49      /**
50       * Returns a deep copy of the passed {@link List} with exact copies of all contained {@link Entry} objects.
51       * 
52       * @param entries the {@link List} to copy
53       * @return a copy of <i>entries</i>
54       */
55      protected static final List<Entry> copy (final List<Entry> entries) {
56          if (entries == null) return null;
57          final ArrayList<Entry> copy = new ArrayList<Entry>();
58          for (Entry e : entries)
59              copy.add(e.copy());
60          return copy;
61      }
62  
63      /**
64       * The abstract constructor.
65       * <p>
66       * Calls {@link #initializeEntries()}.
67       */
68      public SettingsNegotiator () {
69          initializeEntries();
70      }
71  
72      /**
73       * Stores an exact copy of {@link #entries} in {@link #backUpEntries}.
74       */
75      protected final void backUpEntries () {
76          backUpEntries = copy(entries);
77      }
78  
79      /**
80       * This method must be called at the end of a parameter negotiation task, either to roll back any changes that must
81       * not take effect, or in order to ensure that consecutive negotiations are carried out correctly.
82       * 
83       * @param commitChanges <code>true</code> if and only if the negotiated changes to the elements in {@link #entries}
84       *            are to be remembered.
85       */
86      protected final void commitOrRollBackChanges (final boolean commitChanges) {
87          if (commitChanges)
88              for (Entry e : entries)
89                  // allow renegotiation where allowed
90                  e.resetAlreadyNegotiated();
91          else
92              entries = backUpEntries;// roll back
93          backUpEntries = null;// won't be needed anymore
94      }
95  
96      /**
97       * Adds a properly initialized {@link Entry} object to {@link #entries} for every parameter managed by this
98       * {@link SettingsNegotiator}.
99       */
100     protected abstract void initializeEntries ();
101 
102     /**
103      * Checks constraints that cannot be checked at the {@link Entry} level, e.g. because they depend on the values of
104      * multiple parameters.
105      * 
106      * @return <code>true</code> if everything is fine, <code>false</code> if that is not the case
107      */
108     public abstract boolean checkConstraints ();
109 }