package com.indexdata.pz2utils4jsf.pazpar2.state;\r
\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
import java.util.HashMap;\r
+import java.util.List;\r
import java.util.Map;\r
\r
+import javax.enterprise.context.SessionScoped;\r
+\r
import org.apache.log4j.Logger;\r
\r
-import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+import com.indexdata.pz2utils4jsf.pazpar2.commands.CommandReadOnly;\r
+import com.indexdata.pz2utils4jsf.pazpar2.commands.Pazpar2Command;\r
+import com.indexdata.pz2utils4jsf.utils.Utils;\r
\r
-public class StateManager {\r
+@SessionScoped\r
+public class StateManager implements Serializable {\r
\r
+ private static final long serialVersionUID = 8152558351351730035L;\r
+\r
Map<String, Pazpar2State> states = new HashMap<String, Pazpar2State>();\r
String currentKey = "";\r
+ private static List<String> allCommands = new ArrayList<String>(Arrays.asList("init","ping","settings","search","stat","show","record","termlist","bytarget"));\r
Map<String,Boolean> pendingStateChanges = new HashMap<String,Boolean>();\r
private static Logger logger = Logger.getLogger(StateManager.class);\r
+ private List<StateListener> listeners = new ArrayList<StateListener>();\r
\r
public StateManager () {\r
- Pazpar2State initialState = new Pazpar2State();\r
+ logger.info("Initializing a Pazpar2 state manager [" + Utils.objectId(this) + "]");\r
+ Pazpar2State initialState = new Pazpar2State(this);\r
states.put(initialState.getKey(), initialState);\r
currentKey = initialState.getKey();\r
- for (String command : Pazpar2Command.allCommands) {\r
+ for (String command : allCommands) {\r
pendingStateChanges.put(command, new Boolean(false));\r
}\r
-\r
+ }\r
+ \r
+ public void addStateListener(StateListener listener) {\r
+ listeners.add(listener);\r
+ }\r
+ \r
+ public void removeStateListener (StateListener listener) {\r
+ listeners.remove(listener);\r
+ }\r
+ \r
+ private void updateListeners (String command) {\r
+ for (StateListener lsnr : listeners) {\r
+ lsnr.stateUpdated(command);\r
+ }\r
}\r
\r
/**\r
*/\r
public void checkIn(Pazpar2Command command) {\r
if (getCurrentState().stateMutating(command)) {\r
+ logger.debug("State changed by: " + command.getName());\r
Pazpar2State state = new Pazpar2State(getCurrentState(),command);\r
states.put(state.getKey(), state);\r
currentKey = state.getKey();\r
- hasPendingStateChange(command.getName(),new Boolean(true));\r
+ hasPendingStateChange(command.getName(),new Boolean(true)); \r
+ logger.debug("Updating listeners with state change from " + command);\r
+ updateListeners(command.getName()); \r
} else {\r
logger.debug("Command " + command.getName() + " not found to change the state [" + command.getEncodedQueryString() + "]");\r
}\r
}\r
\r
+ /**\r
+ * Gets a detached copy of a command. For the change manager\r
+ * to become aware of any changes to the copy it must be \r
+ * checked back in with 'checkIn(Pazpar2Command)'\r
+ * \r
+ * @param commandName\r
+ * @return Copy this state's instance of the given command\r
+ */\r
public Pazpar2Command checkOut (String commandName) {\r
+ logger.debug("Getting " + commandName + " from state manager.");\r
return getCurrentState().getCommand(commandName).copy();\r
}\r
\r
+ public CommandReadOnly getCommand (String commandName) {\r
+ return getCurrentState().getCommand(commandName);\r
+ }\r
+ \r
public Pazpar2State getCurrentState () {\r
return states.get(currentKey);\r
}\r
- \r
+ \r
+ /**\r
+ * Changes the current state key. Invoked from the UI to have the state \r
+ * manager switch to another state than the current one. \r
+ * \r
+ * @param key\r
+ */\r
public void setCurrentStateKey(String key) { \r
if (currentKey.equals(key)) {\r
logger.debug("setCurrentStateKey: no key change detected");\r
}\r
}\r
\r
- \r
+ /**\r
+ * Sets a pending-state-change flag for the given command and notifies\r
+ * registered listeners. \r
+ * \r
+ * It is up to the listener to reset the flag as needed.\r
+ * \r
+ * @param command\r
+ * @param bool\r
+ */\r
public void hasPendingStateChange(String command, boolean bool) {\r
pendingStateChanges.put(command, new Boolean(bool));\r
}\r
\r
+ /**\r
+ * \r
+ * @param command\r
+ * @return true if there is a non-executed command change in this state\r
+ */\r
public boolean hasPendingStateChange (String command) {\r
return pendingStateChanges.get(command).booleanValue();\r
}\r