d185559ac42948a5023c6704abb451eb94d3bdaf
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / mkjsf / pazpar2 / state / StateManager.java
1 package com.indexdata.mkjsf.pazpar2.state;\r
2 \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
9 \r
10 import javax.enterprise.context.SessionScoped;\r
11 \r
12 import org.apache.log4j.Logger;\r
13 \r
14 import com.indexdata.mkjsf.pazpar2.commands.Pazpar2Command;\r
15 import com.indexdata.mkjsf.pazpar2.commands.sp.AuthCommand;\r
16 import com.indexdata.mkjsf.utils.Utils;\r
17 \r
18 @SessionScoped\r
19 public class StateManager implements Serializable {\r
20   \r
21   private static final long serialVersionUID = 8152558351351730035L;\r
22 \r
23   Map<String, Pazpar2State> states = new HashMap<String, Pazpar2State>();\r
24   String currentKey = "";\r
25   private static List<String> allCommands = new ArrayList<String>(Arrays.asList("init","ping","settings","search","stat","show","record","termlist","bytarget",\r
26                                                                 /* SP extras */ "auth","categories"));\r
27   Map<String,Boolean> pendingStateChanges = new HashMap<String,Boolean>();\r
28   private static Logger logger = Logger.getLogger(StateManager.class);\r
29   private List<StateListener> listeners = new ArrayList<StateListener>();\r
30   \r
31   public StateManager () {\r
32     logger.info("Initializing a Pazpar2 state manager [" + Utils.objectId(this) + "]");\r
33     Pazpar2State initialState = new Pazpar2State(this);\r
34     states.put(initialState.getKey(), initialState);\r
35     currentKey = initialState.getKey();\r
36     for (String command : allCommands) {\r
37       pendingStateChanges.put(command, new Boolean(false));\r
38     }\r
39   }\r
40   \r
41   public void addStateListener(StateListener listener) {\r
42     listeners.add(listener);\r
43   }\r
44   \r
45   public void removeStateListener (StateListener listener) {\r
46     listeners.remove(listener);\r
47   }\r
48   \r
49   private void updateListeners (String command) {\r
50     for (StateListener lsnr : listeners) {\r
51       lsnr.stateUpdated(command);\r
52     }\r
53   }\r
54   \r
55   /**\r
56    * Registers a Pazpar2 command for execution.\r
57    * \r
58    * The state manager will update current state and flag that\r
59    * a request change was made but that it was not yet carried \r
60    * out against Pazpar2.\r
61    * \r
62    * Any command that is created or modified must be checked in\r
63    * like this to come into effect.\r
64    * \r
65    * @param command\r
66    */\r
67   public void checkIn(Pazpar2Command command) {\r
68     if (getCurrentState().stateMutating(command)) {\r
69       logger.debug("State changed by: " + command.getCommandName());\r
70       Pazpar2State state = new Pazpar2State(getCurrentState(),command);\r
71       states.put(state.getKey(), state);\r
72       currentKey = state.getKey();\r
73       hasPendingStateChange(command.getCommandName(),new Boolean(true));      \r
74       logger.debug("Updating " + listeners.size() + " listener(s) with state change from " + command);\r
75       updateListeners(command.getCommandName());      \r
76     } else {\r
77       logger.debug("Command " + command.getCommandName() + " not found to change the state [" + command.getEncodedQueryString() + "]");\r
78     }\r
79   }\r
80       \r
81   public Pazpar2Command getCommand (String commandName) {\r
82     return getCurrentState().getCommand(commandName);\r
83   }\r
84   \r
85   public Pazpar2State getCurrentState () {\r
86     return states.get(currentKey);\r
87   }\r
88     \r
89   /**\r
90    * Changes the current state key. Invoked from the UI to have the state \r
91    * manager switch to another state than the current one. \r
92    * \r
93    * @param key\r
94    */\r
95   public void setCurrentStateKey(String key) {    \r
96     if (currentKey.equals(key)) {\r
97       logger.debug("setCurrentStateKey: no key change detected");\r
98     } else {\r
99       logger.debug("State key change. Was: [" + currentKey + "]. Will be ["+key+"]");\r
100       if (states.get(key)==null) {\r
101         logger.error("The back-end received an unknow state key, probably UI generated: ["+ key +"].");\r
102         if (key == null || key.length()==0) {\r
103           logger.info("Empty key received, treating it as identical to current key going forward.");\r
104           key = currentKey;\r
105         } else {\r
106           if (states.get(currentKey) != null) {\r
107             logger.info("Current search state cached under both of [" + key + "] and [" + currentKey + "]");\r
108             states.put(key,states.get(currentKey));\r
109           }\r
110         }\r
111       }\r
112       \r
113       if (states.get(key).getCommand("search").equals(states.get(currentKey).getCommand("search"))) {\r
114         logger.debug("No search change detected");\r
115       } else {\r
116         hasPendingStateChange("search",true);\r
117       }\r
118       if (states.get(key).getCommand("record").equals(states.get(currentKey).getCommand("record"))) {\r
119         logger.debug("No record change detected");\r
120       } else {\r
121         hasPendingStateChange("record",true);\r
122       }\r
123       currentKey = key;            \r
124     }\r
125   }\r
126 \r
127   /**\r
128    * Sets a pending-state-change flag for the given command and notifies\r
129    * registered listeners. \r
130    * \r
131    * It is up to the listener to reset the flag as needed.\r
132    * \r
133    * @param command\r
134    * @param bool\r
135    */\r
136   public void hasPendingStateChange(String command, boolean bool) {\r
137     pendingStateChanges.put(command, new Boolean(bool));\r
138   }\r
139   \r
140   /**\r
141    * \r
142    * @param command\r
143    * @return true if there is a non-executed command change in this state\r
144    */\r
145   public boolean hasPendingStateChange (String command) {\r
146     return pendingStateChanges.get(command).booleanValue();\r
147   }\r
148 \r
149 }\r