1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.ximtec.igesture.tool.core;
28
29 import java.beans.PropertyChangeEvent;
30 import java.lang.reflect.Method;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.concurrent.Executors;
36 import java.util.logging.Logger;
37
38 import javax.swing.SwingUtilities;
39
40 import org.sigtec.util.Constant;
41 import org.ximtec.igesture.tool.locator.Locator;
42
43
44
45
46
47
48
49
50
51 public abstract class DefaultController implements Controller {
52
53 private static final Logger LOGGER = Logger.getLogger(DefaultController.class
54 .getName());
55
56 private Map<String, Method> commandMethods;
57
58 private List<Controller> controllers;
59
60 private Controller parent;
61
62 private Map<String, LocateableAction> actions;
63
64 private Locator locator;
65
66
67 public DefaultController(Controller parentController) {
68 controllers = new ArrayList<Controller>();
69 actions = new HashMap<String, LocateableAction>();
70 this.setParent(parentController);
71 commandMethods = new HashMap<String, Method>();
72
73 for (Method method : this.getClass().getDeclaredMethods()) {
74
75 if (method.isAnnotationPresent(ExecCmd.class)) {
76 commandMethods.put(method.getAnnotation(ExecCmd.class).name(),
77 method);
78 }
79
80 }
81
82 }
83
84
85
86
87
88
89
90
91 @Override
92 public void addController(Controller controller) {
93 if ((controller.getParent() != null) && (controller.getParent() != this)) {
94 throw new RuntimeException("Controller should have only one parent.");
95 }
96 else {
97 controller.setParent(this);
98 }
99
100 controllers.add(controller);
101 }
102
103
104
105
106
107
108
109 @Override
110 public List<Controller> getControllers() {
111 return controllers;
112 }
113
114
115
116
117
118
119
120 @Override
121 public void removeAllControllers() {
122 controllers.clear();
123 }
124
125
126 @Override
127 public void removeController(Controller controller) {
128 controllers.remove(controller);
129 }
130
131
132 @Override
133 public final void execute(final Command command) {
134 if (SwingUtilities.isEventDispatchThread()) {
135 invokeInWorkerThread(command);
136 return;
137 }
138
139 if ((command != null) && (command.getCommand() != null)) {
140
141 if (!invokeCommand(command)) {
142 LOGGER.info("Command not handled in " + this.getClass().getName()
143 + ". " + Constant.SINGLE_QUOTE + command.getCommand()
144 + Constant.SINGLE_QUOTE);
145
146
147
148 if (parent != null) {
149 parent.execute(command);
150 }
151
152 }
153
154 }
155 else {
156 LOGGER.warning("Command " + Constant.SINGLE_QUOTE + command
157 + Constant.SINGLE_QUOTE + "not available.");
158 }
159
160 }
161
162
163
164
165
166
167
168 private void invokeInWorkerThread(final Command command) {
169 LOGGER.info("Dispatch event dispatch thread to a worker thread.");
170 Executors.newSingleThreadExecutor().execute(new Runnable() {
171
172 @Override
173 public void run() {
174 execute(command);
175 }
176
177 });
178 }
179
180
181 @Override
182 public void propertyChange(final PropertyChangeEvent event) {
183 for (final Controller controller : getControllers()) {
184
185 if (SwingUtilities.isEventDispatchThread()) {
186 controller.propertyChange(event);
187 }
188 else {
189 SwingUtilities.invokeLater(new Runnable() {
190
191 @Override
192 public void run() {
193 controller.propertyChange(event);
194
195 }
196
197 });
198 }
199
200 }
201 }
202
203
204
205
206
207
208
209
210
211 private boolean invokeCommand(Command command) {
212 LOGGER.info("Invoke " + Constant.SINGLE_QUOTE + command
213 + Constant.SINGLE_QUOTE);
214 Method method = commandMethods.get(command.getCommand());
215
216 if (method != null) {
217 try {
218 if (!method.isAccessible()) {
219 method.setAccessible(true);
220 }
221
222 if (method.getParameterTypes().length == 0) {
223 method.invoke(this);
224 }
225 else {
226 method.invoke(this, command);
227 }
228
229 LOGGER.info("Command invoked. " + command.getCommand());
230 return true;
231 }
232 catch (Exception e) {
233 LOGGER.warning("Could not execute command. " + command.getCommand()
234 + e.getMessage());
235 }
236
237 }
238 else {
239 LOGGER.warning("Command not defined. " + command.getCommand());
240 }
241
242 return false;
243 }
244
245
246 @Override
247 public Controller getParent() {
248 return parent;
249 }
250
251
252 @Override
253 public void setParent(Controller controller) {
254 this.parent = controller;
255
256 }
257
258
259 @Override
260 public LocateableAction getAction(String actionName) {
261 return actions.get(actionName);
262 }
263
264
265 public void addAction(String actionName, LocateableAction action) {
266 actions.put(actionName, action);
267 }
268
269
270 @Override
271 public Locator getLocator() {
272 if (locator != null) {
273 return locator;
274 }
275 else if (getParent() != null) {
276 return getParent().getLocator();
277 }
278
279 return null;
280 }
281
282
283 public void setLocator(Locator locator) {
284 this.locator = locator;
285 }
286
287
288
289
290
291
292
293 public boolean isRoot() {
294 return (getParent() == null);
295 }
296
297 }