Renames project from pz2utils4jsf to mkjsf
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / pz2utils4jsf / pazpar2 / state / StateManager.java
index 638effd..f1ae6b6 100644 (file)
@@ -1,27 +1,53 @@
 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.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
@@ -38,47 +64,73 @@ public class StateManager {
    */\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.size() + " listener(s) 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
-  public Pazpar2Command checkOut (String commandName) {\r
-    return getCurrentState().getCommand(commandName).copy();\r
+      \r
+  public Pazpar2Command 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
     } else {\r
       logger.debug("State key change. Was: [" + currentKey + "]. Will be ["+key+"]");\r
-      if (states.get(key).getCommand("search").equals(states.get(currentKey).getCommand("search"))) {\r
-        logger.debug("No search change detected");\r
+      if (states.get(key)==null) {\r
+        logger.error("The back-end received an unknow state key.");        \r
       } else {\r
-        hasPendingStateChange("search",true);\r
-      }\r
-      if (states.get(key).getCommand("record").equals(states.get(currentKey).getCommand("record"))) {\r
-        logger.debug("No record change detected");\r
-      } else {\r
-        hasPendingStateChange("record",true);\r
-      }\r
-      currentKey = key;\r
+        if (states.get(key).getCommand("search").equals(states.get(currentKey).getCommand("search"))) {\r
+          logger.debug("No search change detected");\r
+        } else {\r
+          hasPendingStateChange("search",true);\r
+        }\r
+        if (states.get(key).getCommand("record").equals(states.get(currentKey).getCommand("record"))) {\r
+          logger.debug("No record change detected");\r
+        } else {\r
+          hasPendingStateChange("record",true);\r
+        }\r
+        currentKey = key;\r
+      }      \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