1 package com.indexdata.mkjsf.pazpar2.state;
\r
3 import java.io.Serializable;
\r
4 import java.util.ArrayList;
\r
5 import java.util.Arrays;
\r
6 import java.util.HashMap;
\r
7 import java.util.List;
\r
8 import java.util.Map;
\r
10 import javax.enterprise.context.SessionScoped;
\r
12 import org.apache.log4j.Logger;
\r
14 import com.indexdata.mkjsf.pazpar2.commands.Pazpar2Command;
\r
15 import com.indexdata.mkjsf.utils.Utils;
\r
18 public class StateManager implements Serializable {
\r
20 private static final long serialVersionUID = 8152558351351730035L;
\r
22 Map<String, Pazpar2State> states = new HashMap<String, Pazpar2State>();
\r
23 String currentKey = "";
\r
24 private static List<String> allCommands = new ArrayList<String>(Arrays.asList("init","ping","settings","search","stat","show","record","termlist","bytarget","auth"));
\r
25 Map<String,Boolean> pendingStateChanges = new HashMap<String,Boolean>();
\r
26 private static Logger logger = Logger.getLogger(StateManager.class);
\r
27 private List<StateListener> listeners = new ArrayList<StateListener>();
\r
29 public StateManager () {
\r
30 logger.info("Initializing a Pazpar2 state manager [" + Utils.objectId(this) + "]");
\r
31 Pazpar2State initialState = new Pazpar2State(this);
\r
32 states.put(initialState.getKey(), initialState);
\r
33 currentKey = initialState.getKey();
\r
34 for (String command : allCommands) {
\r
35 pendingStateChanges.put(command, new Boolean(false));
\r
39 public void addStateListener(StateListener listener) {
\r
40 listeners.add(listener);
\r
43 public void removeStateListener (StateListener listener) {
\r
44 listeners.remove(listener);
\r
47 private void updateListeners (String command) {
\r
48 for (StateListener lsnr : listeners) {
\r
49 lsnr.stateUpdated(command);
\r
54 * Registers a Pazpar2 command for execution.
\r
56 * The state manager will update current state and flag that
\r
57 * a request change was made but that it was not yet carried
\r
58 * out against Pazpar2.
\r
60 * Any command that is created or modified must be checked in
\r
61 * like this to come into effect.
\r
65 public void checkIn(Pazpar2Command command) {
\r
66 if (getCurrentState().stateMutating(command)) {
\r
67 logger.debug("State changed by: " + command.getCommandName());
\r
68 Pazpar2State state = new Pazpar2State(getCurrentState(),command);
\r
69 states.put(state.getKey(), state);
\r
70 currentKey = state.getKey();
\r
71 hasPendingStateChange(command.getCommandName(),new Boolean(true));
\r
72 logger.debug("Updating " + listeners.size() + " listener(s) with state change from " + command);
\r
73 updateListeners(command.getCommandName());
\r
75 logger.debug("Command " + command.getCommandName() + " not found to change the state [" + command.getEncodedQueryString() + "]");
\r
79 public Pazpar2Command getCommand (String commandName) {
\r
80 return getCurrentState().getCommand(commandName);
\r
83 public Pazpar2State getCurrentState () {
\r
84 return states.get(currentKey);
\r
88 * Changes the current state key. Invoked from the UI to have the state
\r
89 * manager switch to another state than the current one.
\r
93 public void setCurrentStateKey(String key) {
\r
94 if (currentKey.equals(key)) {
\r
95 logger.debug("setCurrentStateKey: no key change detected");
\r
97 logger.debug("State key change. Was: [" + currentKey + "]. Will be ["+key+"]");
\r
98 if (states.get(key)==null) {
\r
99 logger.error("The back-end received an unknow state key: ["+ key +"].");
\r
101 if (states.get(key).getCommand("search").equals(states.get(currentKey).getCommand("search"))) {
\r
102 logger.debug("No search change detected");
\r
104 hasPendingStateChange("search",true);
\r
106 if (states.get(key).getCommand("record").equals(states.get(currentKey).getCommand("record"))) {
\r
107 logger.debug("No record change detected");
\r
109 hasPendingStateChange("record",true);
\r
117 * Sets a pending-state-change flag for the given command and notifies
\r
118 * registered listeners.
\r
120 * It is up to the listener to reset the flag as needed.
\r
125 public void hasPendingStateChange(String command, boolean bool) {
\r
126 pendingStateChanges.put(command, new Boolean(bool));
\r
132 * @return true if there is a non-executed command change in this state
\r
134 public boolean hasPendingStateChange (String command) {
\r
135 return pendingStateChanges.get(command).booleanValue();
\r