001 /*
002
003 $Id: UserInterface.java,v 1.19 2003/05/08 18:58:28 ndulgheru Exp $
004
005 */
006
007 package sharpster.client.userinterface;
008
009 import sharpster.client.daemoncommunication.*;
010 import sharpster.client.localplugin.*;
011 import sharpster.common.*;
012
013 import java.util.LinkedList;
014
015 /**
016 * Class responsible for user interaction. It is used by the user of the
017 * local client, but none of the modules knows of the class.
018 */
019
020 public class UserInterface {
021
022 private DaemonCommunication daemonCommunication;
023 private LocalPluginManager localPluginManager;
024
025 private LinkedList remArgs;
026 private ResponseCollection response;
027
028 /**
029 * Constructs a user interface object
030 */
031 public UserInterface(DaemonCommunication dc,
032 LocalPluginManager lpm) {
033 daemonCommunication = dc;
034 localPluginManager = lpm;
035 remArgs = null;
036 response = null;
037 }
038
039 /**
040 * Functions prints a usage message to user, in case of erroneous input.
041 */
042 private void printUsage() {
043 System.out.println("Usage for sharpster:");
044 System.out.println("share --file <files> --user <users> --rights r|w|d [--part <name> pluginparams]");
045 System.out.println("unshare --file <files> --user <users>");
046 System.out.println("");
047 System.out.println("checkout --file <files> --user <user> [--role <role>]");
048 System.out.println("commit --file <files> --user <user> [--role <role>]");
049 System.out.println("update --file <files> --user <user>");
050 System.out.println("");
051 System.out.println("group --command <command>");
052 System.out.println("");
053 System.out.println("list [--local-shares] [--remote-shares] [--remote-users]");
054 System.out.println("cvs cvs-commands");
055 System.out.println("sync directory");
056 }
057
058 /**
059 * Utility function to compare two strings without regarding case.
060 */
061 private boolean compareStrings(String lhs,
062 String rhs) {
063 return lhs.equalsIgnoreCase(rhs);
064 }
065
066 /**
067 * Parses user input and and delegates the handling of
068 * each command to the correct private method
069 */
070 public void parseUserInput(String[] argv) {
071 int length = argv.length;
072 remArgs = new LinkedList();
073
074 /* do we have a first argument? */
075 if (length < 1) {
076 System.out.println("Error : To few arguments");
077 printUsage();
078 return;
079 }
080
081 /* build linked list (easier to manipulate) of arguments. */
082 for (int i = 1; i<length; i++) {
083 remArgs.add(argv[i]);
084 }
085
086
087 if (argv[0].equalsIgnoreCase("share")) {
088 parseShare();
089 } else if(argv[0].equalsIgnoreCase("unshare")) {
090 parseUnshare();
091 } else if (argv[0].equalsIgnoreCase("checkout")) {
092 parseCheckout();
093 } else if (argv[0].equalsIgnoreCase("update")) {
094 parseUpdate();
095 } else if (argv[0].equalsIgnoreCase("commit")) {
096 parseCommit();
097 } else if (argv[0].equalsIgnoreCase("group")) {
098 parseGroup();
099 } else if (argv[0].equalsIgnoreCase("remove")) {
100 parseRemove();
101 } else if (argv[0].equalsIgnoreCase("list")) {
102 parseList();
103 } else if (argv[0].equalsIgnoreCase("cvs")) {
104 parseCVS();
105 } else if (argv[0].equalsIgnoreCase("sync")) {
106 parseSync();
107 } else {
108 System.out.println("Unknown command "+argv[0]);
109 printUsage();
110 }
111 if (null != response) {
112 printResponse();
113 }
114 }
115
116 /**
117 * Function prints response that comes back from daemon.
118 */
119 private void printResponse() {
120 Response res = null;
121 System.out.println("Responses from the daemon:\n");
122 for (int i=0; i < response.getResponseCount(); i++) {
123 res = response.getResponse(i);
124 if(res != null) {
125 System.out.println(res.toString());
126 }
127 }
128 }
129
130 /**
131 * utility function: compare first argument of linked list to string cmp
132 */
133 private boolean cmpFirstArg(String cmp) {
134 boolean retval = false;
135 try {
136 String first = (String) remArgs.getFirst();
137 retval = first.equalsIgnoreCase(cmp);
138 } catch (Exception e) {
139 retval = false;
140 }
141 return retval;
142 }
143
144 /**
145 * utility function: compare without case first argument
146 * of linked list to string cmp
147 */
148 private boolean cmpFirstArgCase(String cmp) {
149 boolean retval = false;
150 try {
151 String first = (String) remArgs.getFirst();
152 retval = first.equals(cmp);
153 } catch (Exception e) {
154 retval = false;
155 }
156 return retval;
157 }
158
159 /**
160 * utility function: compare with no case first arg with a prefix
161 */
162 private boolean cmpFirstArgToPrefix(String cmp) {
163 boolean retval = false;
164 try {
165 String first = (String) remArgs.getFirst();
166 retval = first.startsWith(cmp);
167 } catch (Exception e) {
168 retval = false;
169 }
170 return retval;
171 }
172
173 /**
174 * utility function: removes first argument of linked list.
175 */
176 private void removeFirstArg() {
177 try {
178 remArgs.removeFirst();
179 } catch (Exception e) { }
180 }
181
182 /**
183 * utility function: checks that first argument of linked list exists.
184 */
185 private boolean firstArgExists() {
186 return (remArgs.size() > 0);
187 }
188
189 /**
190 * utility function: returns true if next argument is a parameter, that is
191 * it starts with a dash
192 */
193 private boolean firstArgIsParam() {
194 return cmpFirstArgToPrefix("-");
195 }
196
197
198 /**
199 * parseParam* returns true if it was there and parsed correctly.
200 * These functions remove their corresponding arguments from the
201 * linked list remArgs.
202 */
203
204 /**
205 * Fills in FileCollection files, removes its
206 * according parameters from remArgs
207 */
208 private boolean parseParamFile(FileCollection files) {
209 if (!firstArgExists())
210 return false;
211 if (!(cmpFirstArg("--file") ||
212 cmpFirstArgCase("-f")))
213 return false;
214
215 /* Eat --file or -f */
216 removeFirstArg();
217
218 /* a list with arguments after --file that belongs to me */
219 LinkedList myargs = new LinkedList();
220 while (firstArgExists() && !firstArgIsParam()) {
221 myargs.add(remArgs.getFirst());
222 removeFirstArg();
223 }
224
225 /* If file argument was given, but no files return false */
226 if (myargs.size() < 1)
227 return false;
228
229 while (myargs.size() > 0) {
230 SharedFile afile = new SharedFile();
231 afile.setFileName((String) myargs.getFirst());
232 /* TODO : set other necessary stuff. */
233 files.addFile(afile);
234 myargs.removeFirst();
235 }
236
237 return true;
238 }
239
240 /**
241 * returns true if user exists on commandline and
242 * there exists at least one user
243 */
244 private boolean parseParamUsers(FileCollection files) {
245 if (!firstArgExists())
246 return false;
247
248 if (!(cmpFirstArg("--user") ||
249 cmpFirstArgCase("-u")))
250 return false;
251
252 /* Eat --user or -u */
253 removeFirstArg();
254
255 /* a list with arguments after --file that belongs to me */
256 LinkedList myargs = new LinkedList();
257 while (firstArgExists() && !firstArgIsParam()) {
258 myargs.add(remArgs.getFirst());
259 removeFirstArg();
260 }
261
262 /* If user argument was given, but no users return false */
263 if (myargs.size() < 1)
264 return false;
265
266 for (int i=0; i<files.getFileCount(); i++) {
267 SharedFile afile = (SharedFile) files.getFile(i);
268 if (null == afile)
269 return false;
270 for (int j=0; j<myargs.size(); j++) {
271 String user = (String) myargs.get(j);
272 // afile.addSharedToUser((String) myargs.get(j));
273 afile.addSharedToUser(user);
274 /* TODO : set other necessary stuff. */
275 }
276 }
277 return true;
278 }
279
280 /**
281 * returns null if false, otherwise the user to check out from
282 */
283 private String parseParamUser() {
284 if (!firstArgExists())
285 return null;
286
287 if (!(cmpFirstArg("--user") ||
288 cmpFirstArgCase("-u")))
289 return null;
290
291 /* Eat --user or -u */
292 removeFirstArg();
293
294 if (!firstArgExists())
295 return null;
296
297 String user = null;
298 try {
299 user = new String((String) remArgs.getFirst());
300 removeFirstArg();
301 } catch (Exception e) {
302 user = null;
303 }
304 return user;
305 }
306
307 /**
308 * Returns true if the parameter "--rights" or "-r" exists
309 * on commandline and it parses correctly.
310 */
311 private boolean parseParamRights(FileCollection files) {
312 if (!firstArgExists())
313 return false;
314
315 if (!(cmpFirstArg("--rights") ||
316 cmpFirstArgCase("-r")))
317 return false;
318
319 /* Eat --rights or -r */
320 removeFirstArg();
321
322 if (!firstArgExists())
323 return false;
324
325 String acc = (String) remArgs.getFirst();
326 removeFirstArg();
327
328 boolean read = acc.indexOf("r") == -1 ? false : true;
329 boolean write = acc.indexOf("w") == -1 ? false : true;
330 boolean delete = acc.indexOf("d") == -1 ? false : true;
331
332 for (int i=0; i<files.getFileCount(); i++) {
333 SharedFile afile = files.getFile(i);
334 if (null == afile)
335 return false;
336 if (read)
337 afile.setAccessRead();
338 if (write)
339 afile.setAccessWrite();
340 if (delete)
341 afile.setAccessDelete();
342 }
343
344 return true;
345 }
346
347 /**
348 * returns true if part exists on commandline and
349 * plugin manager parses the rest ok.
350 */
351 private boolean parseParamPart(FileCollection files) {
352 if(!firstArgExists()) {
353 for(int i=0;i<files.getFileCount();i++) {
354 SharedFile file = files.getFile(i);
355 PluginData data = localPluginManager.parseArguments(null);
356 if(data == null) {
357 System.out.println("Fatal error: no default plugin loaded");
358 System.exit(1);
359 }
360 file.setPluginData(data);
361 }
362 return true;
363 }
364 if(cmpFirstArg("--part") ||
365 cmpFirstArgCase("-p")) {
366 removeFirstArg();
367
368 PluginData data = localPluginManager.parseArguments(remArgs);
369 if(data == null) {
370 System.out.println("Fatal error: unable to parse plug-in arguments");
371 System.exit(1);
372 }
373
374 for(int i=0;i<files.getFileCount();i++) {
375 SharedFile file = files.getFile(i);
376 file.setPluginData(data);
377 }
378
379 return true;
380 }
381 return false;
382 }
383
384 /**
385 * returns true if recursive parameter exists in command
386 */
387 private boolean parseParamRecursive() {
388 if (!firstArgExists())
389 return false;
390 if (cmpFirstArg("--recursive") ||
391 cmpFirstArgCase("-R")) {
392 removeFirstArg();
393 return true;
394 }
395 return false;
396 }
397
398 /**
399 * parseShare/Unshare/Checkout/...
400 * parses one command, responsible for checking necessary,
401 * optional parameters.
402 */
403
404 /**
405 * parseShare parses share command for correct and
406 * necessary parameters.
407 */
408 private void parseShare() {
409 FileCollection files = new FileCollection();
410 boolean recursive = false;
411 if (!parseParamFile(files)) {
412 System.out.println("Missing files for share!");
413 printUsage();
414 return;
415 }
416 if (!parseParamUsers(files)) {
417 System.out.println("Missing users for share!");
418 printUsage();
419 return;
420 }
421 recursive = parseParamRecursive();
422 if (!parseParamRights(files)) {
423 System.out.println("Missing rights for share!");
424 printUsage();
425 return;
426 }
427 parseParamPart(files);
428 /* TODO: what to do with recursive boolean parameter??
429 overloaded function in daemoncommunication */
430 response = daemonCommunication.shareFiles(files);
431 }
432
433 /**
434 * parseUnshare parses unshare command for correct and
435 * necessary parameters.
436 */
437 private void parseUnshare() {
438 FileCollection files = new FileCollection();
439 boolean recursive = false;
440 if (!parseParamFile(files)) {
441 System.out.println("Missing files for unshare!");
442 printUsage();
443 return;
444 }
445 if (!parseParamUsers(files)) {
446 System.out.println("Missing users for unshare!");
447 printUsage();
448 return;
449 }
450 recursive = parseParamRecursive();
451 /* TODO: recursive parameter */
452 response = daemonCommunication.unShareFiles(files);
453 }
454
455 /**
456 * parseCheckout parses checkout command for correct and
457 * necessary parameters.
458 */
459 private void parseCheckout() {
460 FileCollection files = new FileCollection();
461 boolean recursive = false;
462 if (!parseParamFile(files)) {
463 System.out.println("Missing files for checkout!");
464 printUsage();
465 return;
466 }
467 String user = parseParamUser();
468 if (null == user) {
469 System.out.println("Missing user for checkout!");
470 printUsage();
471 return;
472 }
473
474 String role = parseParamRole();
475
476 recursive = parseParamRecursive();
477 /* TODO: recursive parameter, username, workingdirectory */
478 response = daemonCommunication.remoteCheckoutFiles(files, user, role);
479 }
480
481 /**
482 * parseCheckout parses checkout command for correct and
483 * necessary parameters.
484 */
485 private void parseUpdate() {
486 System.out.println("asdasdasdas");
487
488 FileCollection files = new FileCollection();
489 boolean recursive = false;
490 if (!parseParamFile(files)) {
491 System.out.println("Missing files for update!");
492 printUsage();
493 return;
494 }
495 String user = parseParamUser();
496 if (null == user) {
497 System.out.println("Missing user for update!");
498 printUsage();
499 return;
500 }
501 recursive = parseParamRecursive();
502 /* TODO: recursive parameter, username, workingdirectory */
503 response = daemonCommunication.remoteUpdateFiles(files, user);
504 }
505
506 /**
507 * parseCommit parses commit command for correct and
508 * necessary parameters.
509 */
510 private void parseCommit() {
511 FileCollection files = new FileCollection();
512 boolean recursive = false;
513 if (!parseParamFile(files)) {
514 System.out.println("Missing files for commit!");
515 printUsage();
516 return;
517 }
518 String user = parseParamUser();
519 if (null == user) {
520 System.out.println("Missing user for commit!");
521 printUsage();
522 return;
523 }
524
525 String role = parseParamRole();
526
527 recursive = parseParamRecursive();
528 /* TODO: recursive parameter, username, workingdirectory */
529 response = daemonCommunication.remoteCommitFiles(files, user, role);
530 }
531
532
533 private void parseGroup() {
534 String command = parseParamCommand();
535 if (null == command) {
536 System.out.println("Missing command for group!");
537 printUsage();
538 return;
539 }
540
541 GroupCommand gc = new GroupCommand();
542
543 if(command.equalsIgnoreCase("ADD-USER")) {
544
545 String user = parseParamUser();
546 if (null == user) {
547 System.out.println("Missing username in group command!");
548 printUsage();
549 return;
550 }
551 String group = parseParamGroup();
552 if (null == group) {
553 System.out.println("Missing groupname in group command!");
554 printUsage();
555 return;
556 }
557
558 gc.command = SubCommand.ADD_USER;
559 gc.user = user;
560 gc.group = group;
561
562 } else if(command.equalsIgnoreCase("REMOVE-USER")) {
563
564 String user = parseParamUser();
565 if (null == user) {
566 System.out.println("Missing username in group command!");
567 printUsage();
568 return;
569 }
570 String group = parseParamGroup();
571 if (null == group) {
572 System.out.println("Missing groupname in group command!");
573 printUsage();
574 return;
575 }
576
577 gc.command = SubCommand.REMOVE_USER;
578 gc.user = user;
579 gc.group = group;
580
581 } else if(command.equalsIgnoreCase("LIST-GROUPS")) {
582
583 gc.command = SubCommand.LIST_GROUPS;
584
585 } else if(command.equalsIgnoreCase("LIST-ALL")) {
586
587 gc.command = SubCommand.LIST_ALL;
588
589 } else if(command.equalsIgnoreCase("LIST-USERS-IN-GROUP")) {
590
591 String group = parseParamGroup();
592 if (null == group) {
593 System.out.println("Missing groupname in group command!");
594 printUsage();
595 return;
596 }
597
598 gc.command = SubCommand.LIST_USERS_IN_GROUP;
599 gc.group = group;
600
601 } else if(command.equalsIgnoreCase("ADD-GROUP")) {
602
603 String group = parseParamGroup();
604 if (null == group) {
605 System.out.println("Missing groupname in group command!");
606 printUsage();
607 return;
608 }
609
610 gc.command = SubCommand.ADD_GROUP;
611 gc.group = group;
612
613 } else if(command.equalsIgnoreCase("REMOVE-GROUP")) {
614
615 String group = parseParamGroup();
616 if (null == group) {
617 System.out.println("Missing groupname in group command!");
618 printUsage();
619 return;
620 }
621
622 gc.command = SubCommand.REMOVE_GROUP;
623 gc.group = group;
624
625 } else {
626 System.out.println("Unknown command in group");
627 printUsage();
628 return;
629 }
630
631 response = daemonCommunication.groupCommand(gc);
632
633 }
634
635 /**
636 * returns null if false, otherwise the command to do.
637 */
638 private String parseParamCommand() {
639 if (!firstArgExists())
640 return null;
641
642 if (! (cmpFirstArg("--command") ||
643 cmpFirstArgCase("-c")))
644 return null;
645
646 /* Eat --command or -c */
647 removeFirstArg();
648
649 if (!firstArgExists())
650 return null;
651
652 String command = null;
653 try {
654 command = new String( (String) remArgs.getFirst());
655 removeFirstArg();
656 }
657 catch (Exception e) {
658 command = null;
659 }
660 return command;
661
662 }
663
664 /**
665 * returns null if false, otherwise the group name.
666 */
667 private String parseParamGroup() {
668 if (!firstArgExists())
669 return null;
670
671 if (! (cmpFirstArg("--group") ||
672 cmpFirstArgCase("-g")))
673 return null;
674
675 /* Eat --group or -g */
676 removeFirstArg();
677
678 if (!firstArgExists())
679 return null;
680
681 String group = null;
682 try {
683 group = new String( (String) remArgs.getFirst());
684 removeFirstArg();
685 }
686 catch (Exception e) {
687 group = null;
688 }
689 return group;
690
691 }
692
693 /**
694 * returns null if false, otherwise the role to use.
695 */
696 private String parseParamRole() {
697 if (!firstArgExists())
698 return null;
699
700 if (! (cmpFirstArg("--role") ||
701 cmpFirstArgCase("-r")))
702 return null;
703
704 /* Eat --role or -r */
705 removeFirstArg();
706
707 if (!firstArgExists())
708 return null;
709
710 String role = null;
711 try {
712 role = new String( (String) remArgs.getFirst());
713 removeFirstArg();
714 }
715 catch (Exception e) {
716 role = null;
717 }
718 return role;
719 }
720
721 /**
722 * parseRemove parses remove command for correct and
723 * necessary parameters.
724 */
725 private void parseRemove() {
726 FileCollection files = new FileCollection();
727 boolean recursive = false;
728 if (!parseParamFile(files)) {
729 System.out.println("Missing files for commit!");
730 printUsage();
731 return;
732 }
733 String user = parseParamUser();
734 if (null == user) {
735 System.out.println("Missing user for commit!");
736 printUsage();
737 return;
738 }
739 recursive = parseParamRecursive();
740 /* TODO: recursive parameter, username, workingdirectory */
741 response = daemonCommunication.remoteRemoveFiles(files, user);
742 }
743
744 /**
745 * parseList parses list command for correct and
746 * necessary parameters.
747 */
748 private void parseList() {
749 boolean atLeastOneArg = false;
750 while (firstArgExists()) {
751 atLeastOneArg = true;
752 if (cmpFirstArg("--local-shares")||
753 cmpFirstArgCase("-ls")) {
754 removeFirstArg();
755 response = daemonCommunication.viewFileSharing();
756 if (null != response) {
757 printResponse();
758 response = null;
759 }
760 } else if (cmpFirstArg("--remote-shares")||
761 cmpFirstArgCase("-rs")) {
762 removeFirstArg();
763 response = daemonCommunication.viewFileAccess();
764 if (null != response) {
765 printResponse();
766 response = null;
767 }
768 } else if (cmpFirstArg("--remote-users")||
769 cmpFirstArgCase("-ru")) {
770 removeFirstArg();
771 response = daemonCommunication.viewUsers();
772 if (null != response) {
773 printResponse();
774 response = null;
775 }
776 } else {
777 System.out.println("Missing or misspelled argument for list argument!");
778 printUsage();
779 return;
780 }
781
782 }
783
784 if (!atLeastOneArg) {
785 System.out.println("Missing atleast one argument for list!");
786 printUsage();
787 }
788 }
789
790 /**
791 * parseSync parses sync command for correct and
792 * necessary parameters.
793 */
794 private void parseSync() {
795 response = daemonCommunication.synchronizeCVS();
796 }
797
798 /**
799 * parseCVS parses cvs command for correct and
800 * necessary parameters.
801 */
802 private void parseCVS() {
803 if (!firstArgExists()) {
804 System.out.println("Missing command-string for cvs command");
805 printUsage();
806 return;
807 }
808 String cmd = new String();
809 while (firstArgExists()) {
810 cmd = cmd + " " + (String) remArgs.getFirst();
811 removeFirstArg();
812 }
813 response = daemonCommunication.localDoCVS(cmd);
814 }
815
816 }
817
818
819
820
821
822
823
824
825