Source code: org/mitre/cvw/CVWAdminTool.java
1 /*
2 * Copyright (c) 1996-2000. The MITRE Corporation (http://www.mitre.org/).
3 * All rights reserved.
4 * CVW comes with ABSOLUTELY NO WARRANTY. See license for details.
5 */
6
7 package org.mitre.cvw;
8
9 import java.util.*;
10 import java.net.*;
11 import java.io.File;
12
13 /**
14 * CLASS DESCRIPTION
15 * @version 1.0
16 * @author Dee Goepel
17 */
18 public class CVWAdminTool extends CVWObject {
19
20 transient AdminThreadReader atThreadReader = null;
21 transient AdminThreadWriter atThreadWriter = null;
22 static boolean clientServerProtocolSync = true;
23 static Float currentClientServerStartVersion = new Float(1.0);
24 static Float currentClientServerEndVersion = new Float(1.0);
25 static Float currentClientAdminVersion = new Float(1.0);
26
27 CVWCoordinator jcvw = CVWCoordinator.getInstance();
28 AdminServerMgr adminServerMgr;
29 String localHost;
30 int port;
31 boolean isOpen = false;
32
33 /* create a private class variable and an accessor method
34 * so that objects can access the current instance of the AdminTool
35 * same as CVWCoordinator
36 */
37 private static CVWAdminTool at = null;
38
39 /**
40 * Constructor
41 */
42 CVWAdminTool() {
43 port = 0;
44 at = this;
45 localHost = jcvw.getParameter("wbLocalHost");
46 startServerMgr();
47 }
48
49 /**
50 * This opens the Admin Tool
51 */
52 public void open() {
53 if (!clientServerProtocolSync) {
54 errorMsg("Unable to open Admin Tool. JCVW Client/MOO Server protocol out of sync.");
55 return;
56 }
57
58 /* We need to check if window is already open, if so raise it and return
59 otherwise continue with launch
60 */
61 if (this.isOpen) {
62 showWindow();
63 return;
64 }
65
66 // Check to ensure directory exists
67 String adminRoot = NPDocServer.getSystemDir();
68 String sep = System.getProperty("file.separator");
69 String adminPath = new String(adminRoot + sep + "modules" + sep + "cvw-admintool");
70 File adminDir = new File(adminPath);
71
72 if (!adminDir.isDirectory()) {
73 errorMsg("Unable to start Admin Tool. Admin tool directory not found: " + adminPath);
74 return;
75 }
76
77 // register the window with the window manager
78 //winMgr.addWindow(winMgr.TOOL,this);
79
80 // launch the tool
81 String[] cmd;
82 cmd = getStartCmd();
83 new AdminProc(this, cmd).start();
84 }
85
86 /**
87 * This builds the command string that is executed to launch the Admin Tool
88 * @return
89 */
90 public String[] getStartCmd() {
91 String os = System.getProperty("os.name");
92
93 String adminRoot = NPDocServer.getSystemDir();
94 String sep = System.getProperty("file.separator");
95 String adminPath = new String(adminRoot + sep + "modules" + sep
96 + "cvw-admintool" + sep + "bin");
97 String adminPath2 = adminPath.replace('\\', '/');
98 String adminInterp = new String(adminRoot + sep + "modules" + sep
99 + "cvw-admintool" + sep + "bin" + sep + "wish80.exe");
100
101 String adminFile = new String(adminRoot + sep + "modules" + sep
102 + "cvw-admintool" + sep + "bin" + sep + "at.tcl");
103
104 String[] cmd = {adminInterp, adminFile, adminPath2,
105 jcvw.getParameter("wbLocalHost") + " " + port + " {" +
106 NPDocServer.getSystemDir("images/cvwsplash.gif") + "}"};
107
108 return cmd;
109 }
110
111
112 /**
113 * This launches the Admin Server Manager that opens a socket for communication
114 * with the Admin Tool and handles the dispatch of comms on that socket
115 */
116 void startServerMgr() {
117 adminServerMgr = new AdminServerMgr(this, localHost);
118 adminServerMgr.start();
119 }
120
121 /**
122 * FUNCTION DESCRIPTION
123 * @param port
124 */
125 public void setPort(int port) {
126 this.port = port;
127 }
128
129 /**
130 * FUNCTION DESCRIPTION
131 * @return
132 */
133 public synchronized int getPort() {
134 return this.port;
135 }
136
137 /**
138 * Displays errorMessages associated with the Admin Tool
139 * @param message
140 */
141 public void errorMsg(String message) {
142 jcvw.displayError(message);
143 }
144
145 /**
146 * Displays debugging lines associated with the Admin Tool if debugging is
147 * turned on
148 * @param message
149 */
150 public void debugMsg(String message) {
151 if (jcvw.DEBUG) System.out.println("AT: "+message);
152 }
153
154 /**
155 * A synchronized wrapper for processMsg
156 * @param message
157 * @see processMsg
158 */
159 public synchronized void msg(String message) {
160 processMsg(message);
161 }
162
163
164 void sendMsg(String msg) {
165 if (atThreadWriter != null)
166 atThreadWriter.putMsg(msg);
167 }
168
169
170 void setThreadReader(AdminThreadReader atThreadReader) {
171 this.atThreadReader = atThreadReader;
172 }
173
174 void setThreadWriter(AdminThreadWriter atThreadWriter) {
175 this.atThreadWriter = atThreadWriter;
176 }
177
178
179 /**
180 * This processes requests from the Admin Tool & acts upon them
181 * @param message
182 */
183 void processMsg(String msg) {
184 int tokenNum = 0;
185 String cmd = new String();
186 String args = "";
187 String exitStatus = null;
188
189 debugMsg("client heard: "+msg);
190 StringTokenizer parser = new StringTokenizer(msg);
191 int tokenCount = parser.countTokens();
192
193 if (tokenCount > 0) {
194 try {
195 while (tokenNum < 1 && parser.hasMoreTokens()) {
196 if (tokenNum == 0) {
197 cmd = parser.nextToken();
198 tokenNum++;
199 } else {
200 errorMsg("CVWAdminTool::processMsg() handling tokens");
201 }
202 }
203
204 if ((msg.trim()).length() > cmd.length()) {
205 // the command has arguments
206 args = msg.substring(cmd.length(), msg.length()).trim();
207
208 // arguments may be surrounded by {} so we need to strip them
209 if (args.indexOf('{') == 0 && args.lastIndexOf('}') == (args.length()-1) )
210 args = args.substring(1, args.length()-1);
211 }
212 debugMsg("cmd is: "+cmd+" args are: "+args);
213
214 if (cmd.equals("ADMIN_STARTED")) {
215 // okay, we're up and running
216 this.isOpen = true;
217 } else if (cmd.equals("ADMIN_STOPPED")) {
218 closeWindow();
219
220 } else if (cmd.equals("TERMINATED")) {
221 if (atThreadReader != null) {
222 atThreadReader.stopThread();
223 atThreadReader = null;
224 }
225 if (atThreadWriter != null) {
226 atThreadWriter.stopThread();
227 atThreadWriter = null;
228 }
229 // tool closed
230 isOpen = false;
231 } else if (cmd.equals("GET_MAP")) {
232 sendMapDataToAdminTool();
233
234 } else if (cmd.equals("APPLICATION_DISPLAY")) {
235 // put line in scrollback
236 jcvw.displayPrvSysMsg(args);
237
238 } else if (cmd.equals("DEBUG_MSG")) {
239 // this is debugging info from AdminTool
240 // don't need to do anything with it, since all messages
241 // from the adminTool are printed to the console anyway
242 // if debugging is on
243 } else if (cmd.equals("MCP_TO_SERVER")) {
244 // the admin tool is sending mcp to the moo server
245 int split = args.indexOf(' ');
246 if (split > 0 && split < (args.length()-1)) {
247 // split the mcp command from the mcp args
248 debugMsg("MCP_TO_SERVER: "+args.substring(0,split)+" | "+ args.substring(split+1));
249 CVWServerComm.sendMCPCmdToServer(args.substring(0,split), args.substring(split+1));
250 } else {
251 // we only have an mcp command, no mcp args
252 debugMsg("MCP_TO_SERVER: "+args+" | ");
253 CVWServerComm.sendMCPCmdToServer(args);
254 }
255
256 } else if (cmd.equals("LINE_TO_SERVER")) {
257 // the admin tool is sending text to the moo server
258 debugMsg("LINE_TO_SERVER: "+args);
259 CVWServerComm.sendRawCmdToServer(args);
260
261 } else if (cmd.equals("EXITED")) {
262 // Not currently used, since we don't use protocols for the tool
263 // will be useful once we have real mcp
264 if (tokenCount > 1) {
265 try {
266 while (parser.hasMoreTokens()) {
267 if (tokenNum == 1) {
268 exitStatus = parser.nextToken();
269 }
270 tokenNum++;
271 }
272
273 if (exitStatus.equals("2")) {
274 errorMsg("Protocol version out of sync. Unable to open the Admin Tool.");
275 }
276
277 } catch (NoSuchElementException e) {
278 errorMsg("CVWAdminTool::processMsg() EXITED " + e.getMessage());
279 return;
280 }
281 }
282 // tool closed
283 this.isOpen = false;
284 }
285 } catch (NoSuchElementException e) {
286 errorMsg("CVWAdminTool::processMsg() " + e.getMessage());
287 }
288 }
289 }
290
291
292 void showWindow() {
293 String cmd = new String("TOOL_RAISE");
294 sendMsg(cmd);
295 }
296
297
298 void closeWindow() {
299 String cmd = new String("TERMINATE");
300 sendMsg(cmd);
301 }
302
303
304 /**
305 * Returns the current instance of CVWAdminTool, this is a singleton class.
306 * @return the current instance
307 */
308 public static CVWAdminTool getInstance() {
309 return at;
310 }
311
312 /**
313 * This function is a stub. It is not used now, but will be needed when real
314 * MCP commands are written for the admin tool (right now it uses depricated
315 * non-protocol MCP commands).
316 * @param fromVersion
317 * @param toVersion
318 */
319 public static void setClientServerProtocolVersion(String fromVersion, String toVersion) {
320 // These version numbers need to be consistent with those in
321 // CVWCoordinator's startProtocolExchange() method
322 Float startVersion, endVersion;
323
324 if ((fromVersion != null) && (toVersion != null)) {
325 startVersion = Float.valueOf(fromVersion);
326 endVersion = Float.valueOf(toVersion);
327 } else {
328 CVWCoordinator.getInstance().displayError("Unable to determine JCVW Client/MOO Server admin protocol version.");
329 CVWCoordinator.getInstance().displayError("Admin Tool is unavailable.");
330 clientServerProtocolSync = false;
331 return;
332 }
333
334
335 if ((startVersion.floatValue() >=
336 currentClientServerStartVersion.floatValue()) &&
337 (endVersion.floatValue() <=
338 currentClientServerEndVersion.floatValue()))
339 clientServerProtocolSync = true;
340 else
341 clientServerProtocolSync = false;
342 }
343
344
345 /**
346 * This function sends a user's data to the admin tool. It is sent in
347 * response to a #$#x-verify-request from the admin tool to the moo server.
348 *
349 * @param caller - unique name identifying the calling method in the admin
350 * tool, used by the admin tool to identify who gets the result
351 * @param keys - enumeration of all the mcp keywords
352 * @param elements - corresponding enumeration of mcp keyword values
353 */
354 public void verifyResult(String caller, Enumeration keys, Enumeration elements) {
355 String pairList = "";
356
357 while (keys.hasMoreElements()) {
358 // keys & elements are the same length, by definition
359 pairList = new String(pairList + " \"" + keys.nextElement() + "\" \"" + elements.nextElement() + "\"");
360 }
361 String cmd = new String("VERIFY_RESULT " + caller + " {" + pairList.trim() + "}");
362 sendMsg(cmd);
363 }
364
365 /**
366 * This function sends a user's home info the admin tool. It is sent in
367 * response to a #$#x-get-home from the admin tool to the moo server.
368 *
369 * @param home - the object number of the user's home, in String form
370 */
371 public void sendHomeInfo(String home) {
372 String cmd = new String("HOME_INFO " + home);
373 sendMsg(cmd);
374 }
375
376 /**
377 * This sends progress status of a user creation attempt. It is sent in
378 * response to a #$#admin-create from the admin tool to the moo server.
379 *
380 * @param message - progress/status messages, lines delimited with ">>!<<"
381 */
382 public void sendUserCreateStatus(String message) {
383 String cmd = new String("USER_CREATE_LINE " + "{" + message + "}");
384 sendMsg(cmd);
385 }
386
387 /**
388 * This returns the result of a user create attempt. It is sent in
389 * response to a #$#admin-create from the admin tool to the moo server.
390 *
391 * @param problem - 0/1 integer denoting whether an error occured
392 * @param person - user's full name
393 * @param login - user's login name
394 * @param user - user's user name
395 * @param gender - user's gender ("Male" or "Female")
396 * @param proxy - whether a proxy was created ("Yes" or "No")
397 * @param office - user's office
398 * @param phone - user's phone
399 * @param email - user's email address
400 * @param badge - unique id given to the user
401 * @param icon - name of icon file associated with the user
402 * @param home - user's home room
403 */
404 public void sendUserCreateResult(int problem, String person, String login, String user, String gender, String proxy, String office, String phone, String email, String badge, String icon, String home) {
405 String cmd = new String("USER_CREATE_RES " + gender + " {" + office + "} {" + person + "} " + login + " " + proxy + " {" + phone + "} {" + email + "} {" + badge + "} " + user + " {" + icon + "} {" + home + "} " + problem);
406 sendMsg(cmd);
407 }
408
409 /**
410 * This sends progress status of a user modify attempt. It is sent in
411 * response to a #$#admin-modify from the admin tool to the moo server.
412 *
413 * @param message - progress/status messages, lines delimited with ">>!<<"
414 */
415 public void sendUserModifyStatus(String message) {
416 String cmd = new String("USER_MOD_LINE " + "{" + message + "}");
417 sendMsg(cmd);
418 }
419
420 /**
421 * This returns the result of a user modification attempt. It is sent in
422 * response to a #$#admin-modify from the admin tool to the moo server.
423 *
424 * @param problem - 0/1 integer denoting whether an error occured
425 * @param person - user's full name
426 * @param login - user's login name
427 * @param user - user's user name
428 * @param gender - user's gender ("Male" or "Female")
429 * @param proxy - whether a proxy was created ("Yes" or "No")
430 * @param office - user's office
431 * @param phone - user's phone
432 * @param email - user's email address
433 * @param badge - unique id given to the user
434 * @param icon - name of icon file associated with the user
435 * @param password - user's password
436 */
437 public void sendUserModifyResult(int problem, String person, String login, String user, String gender, String proxy, String office, String phone, String email, String badge, String icon, String home, String password) {
438 String cmd = new String("USER_MOD_RES " + gender + " {" + office + "} {" + person + "} " + login + " " + proxy + " {" + phone + "} {" + email + "} {" + badge + "} " + user + " {" + icon + "} {" + home + "} " + problem + " {" + password + "}");
439 sendMsg(cmd);
440 }
441
442 /**
443 * This returns the result of a user delete attempt. It is sent in
444 * response to a #$#admin-delete from the admin tool to the moo server.
445 *
446 * @param done - 0/1 integer denoting whether the delete task has finished
447 * @param message - progress/status messages, lines delimited with ">>!<<"
448 */
449 public void sendUserDeleteResult(int done, String message) {
450 String cmd = new String("USER_DEL_RES " + done + " {" + message + "}");
451 sendMsg(cmd);
452 }
453
454 /**
455 * This sends the Admin Tool the latest room & floor data
456 */
457 private void sendMapDataToAdminTool() {
458 CVWMap m = jcvw.getMapWindow("org.mitre.cvw.CVWMapWin");
459 CVWMapWin map;
460 if (m != null && m instanceof CVWMapWin)
461 map = (CVWMapWin)m;
462 else return;
463
464 String[] temp;
465 String msg;
466 int a;
467 int floorCount, roomCount;
468
469 debugMsg("In sendMapDataToAdminTool(), map is "+map.toString());
470
471 floorCount = map.howManyFloors();
472 roomCount = map.howManyRooms();
473
474 temp = new String[floorCount];
475 temp = map.getFloorObjs();
476 msg = "FLOOR_OBJS {";
477 for (a=0; a < floorCount; a++) {
478 msg = msg + " " + (a+1) + " " + temp[a];
479 }
480 System.err.println("msg is: " + msg);
481 sendMsg(msg + "}");
482
483 temp = map.getFloorNames();
484 msg = "FLOOR_NAMES {";
485 for (a=0; a < floorCount; a++) {
486 msg = msg + " " + (a+1) + " {" + temp[a] + "}";
487 }
488 System.err.println("msg is: " + msg);
489 sendMsg(msg + "}");
490
491 temp = new String[roomCount];
492 temp = map.getRoomObjs();
493 msg = "ROOM_OBJS {";
494 for (a=0; a < roomCount; a++) {
495 msg = msg + " " + (a+1) + " " + temp[a];
496 }
497 System.err.println("msg is: " + msg);
498 sendMsg(msg + "}");
499
500 temp = map.getRoomNames();
501 msg = "ROOM_NAMES {";
502 for (a=0; a < roomCount; a++) {
503 msg = msg + " " + (a+1) + " {" + temp[a] + "}";
504 }
505 System.err.println("msg is: " + msg);
506 sendMsg(msg + "}");
507
508 /*
509 msg = "ROOM_FULL_NAMES [array get roomFullName]";
510 sendMsg(msg);
511
512 */
513
514 msg = "ROOM_TALLIES " + roomCount + " " + floorCount + " " + map.roomsPerFloor;
515 sendMsg(msg);
516 }
517
518 /**
519 * This returns the result of a floor creation attempt. It is sent in
520 * response to a #$#admin-create from the admin tool to the moo server.
521 *
522 * @param problem - 0/1 integer denoting whether an error occured
523 */
524 public void sendFloorCreateResult(int problem) {
525 String cmd = new String("ROOM_CREATE_RES " + problem);
526 sendMsg(cmd);
527 }
528
529 /**
530 * This returns the information for modifying a room, i.e. the room's
531 * full name and description. It is sent in response to a
532 * #$#change-description from the admin tool to the moo server.
533 *
534 * @param objnum - the object number the room to modify, in string form
535 * @param name - the current full name of the room to modify
536 * @param desc - the current description of the room to modify
537 */
538 public void sendRoomModifyInfo(String objnum, String name, String desc) {
539 String cmd = new String("ROOM_MOD_INFO " + objnum + " {" + name +"} {" + desc + "}");
540 sendMsg(cmd);
541 }
542
543 /**
544 * This returns the result of a floor modification attempt. It is sent in
545 * response to a #$#admin-modify from the admin tool to the moo server.
546 *
547 * @param problem - 0/1 integer denoting whether an error occured
548 */
549 public void sendFloorModifyResult(int problem) {
550 String cmd = new String("ROOM_MOD_RES " + problem);
551 sendMsg(cmd);
552 }
553
554 /**
555 * This returns the result of a floor delete attempt. It is sent in
556 * response to a #$#admin-delete from the admin tool to the moo server.
557 *
558 * @param done - 0/1 integer denoting whether the delete task has finished
559 * @param message - progress/status messages, lines delimited with ">>!<<"
560 */
561 public void sendFloorDeleteResult(int done, String message) {
562 String cmd = new String("ROOM_DEL_RES " + done + " {" + message + "}");
563 sendMsg(cmd);
564 }
565
566 /**
567 * This returns the result of a recorder create attempt. It is sent in
568 * response to a #$#admin-create from the admin tool to the moo server.
569 *
570 * @param prob - a keyword denoting what problem occured, if any
571 * @param name - the name of the room the recorder is for
572 */
573 public void sendRecorderCreateResult(String prob, String name) {
574 String cmd = new String("RECORDER_RES " + prob + " {" + name + "}");
575 sendMsg(cmd);
576 }
577
578 /**
579 * This function sends the system prefs to the admin tool. It is sent in
580 * response to a #$#get-admin-prefs from the admin tool to the moo server.
581 *
582 * @param keys - enumeration of all the mcp keywords
583 * @param elements - corresponding enumeration of mcp keyword values
584 */
585 public void sendSystemPrefs(Enumeration keys, Enumeration elements) {
586 String pairList = "";
587
588 while (keys.hasMoreElements()) {
589 // keys & elements are the same length, by definition
590 pairList = new String(pairList + " \"" + keys.nextElement() + "\" \"" + elements.nextElement() + "\"");
591 }
592
593 String cmd = new String("SYSTEM_PREFS {"+ pairList.trim() + "}");
594 sendMsg(cmd);
595 }
596
597 /**
598 * This function sends the MOTD to the admin tool. It is sent in
599 * response to a #$#get-motd from the admin tool to the moo server.
600 *
601 * @param motd - the MOTD in string form, lines delimited with ">>!<<"
602 */
603 public void sendMOTD(String motd) {
604 String cmd = new String("MOTD {" + motd + "}");
605 sendMsg(cmd);
606 }
607
608 }