Notes
Slide Show
Outline
1
CS110 Lecture 17
Thursday, April 1, 2004
  • Announcements
    • hw7 due tonight
    • pass/fail, withdraw deadline April  8
  • Agenda
    • Questions
    • Juno
    • JFile system internals next week
2
Juno (Chapters 6, 7, ...)
  • We have a (J)File system
  • Now we provide it with a command line interface, like the one the emacs shell or a command prompt gives you to windows
  • Use that interface to
    • create TextFiles and Directories
    • navigate in the Directory tree
3
Command prompt interface to windows file system
4
 
5
Juno (Chapters 6, 7, ...)
  • Simulates (models) that command line interface
  • “Juno” etymology: “Juno’s Unix not”             (developed under Unix)
  • Juno UI: nested do forever loops
    • login: login as user, register, help, exit
    • mars:\users\eb> help, logout, mkdir, newfile, type  ... cd, dir (various shell commands )
  • Like Bank
    • banker command: customer, open, report,  exit
    •  transaction: deposit, withdraw, …, quit,
6
Sample Juno session
7
Juno classes
8
Juno.java (version 6)
  • fields (attributes of a Juno operating system)
    • Map for users (line 30)
    • Terminal for console (line 31)
    • Directories: slash, userHomes (lines 33, 34)
    • ShellCommandTable (line 36)
  • main()
    • parse command line arguments (175-186)
    • create a Juno object (190)

9
Juno constructor (45)
  • new Terminal for console (line50)
  • new Map for users (line 51)
  • new table for ShellCommands (52)
  • file system and system administrator
    • lines 56-59
    • read them next week
  • create LoginInterpreter object to respond to user’s commands (64, 65)
  • send it a CLIlogin message (66)
10
LoginInterpreter
  • The object that listens for user responses to the login: prompt
  • public void CLIlogin( )  { // (line 55)
  •    welcome();
  •    boolean moreWork = true;
  •    while( moreWork ) {
  •       moreWork = interpret(                                                                                                                  console.readLine("Juno login: " ));
  •    }
  • }
11
interpret (line 69)
  • break command line into tokens (next slide)
  • put first token into String variable visitor (77)
  • use  if - else if - else if … logic
    • if “exit” return false!  // leave loop in CLIlogin
    • if “register”       // create account for new user
    • if “help”            // give help
    • else                    // input is a username
      • look up User object in map, with username as key
      • create a command shell for that User
12
StringTokenizer
  • Juno user might type
  •       Juno login: register bill Bill Campbell
  • We need to cut the blue String up into words
  • Like an Iterator
  • StringTokenizer st =
  •   new StringTokenizer(“register bill B C”);
  • while (st.hasMoreTokens())
  • System.out.println(“|”+st.nextToken()+“|”);
  • produces
  •    |register|
  •    |bill|
  •    |B|
  •    |C|
13
StringTokenizer
  • Can change default (whitespace) delimiters
  • StringTokenizer st = new S…T…(“x.b b*z”,“.*,”);
  • while (st.hasMoreTokens())
  • System.out.println(st.nextToken());
  • produces
  •    x
  •    b b
  •    z
  • Can change delimiters dynamically - for no delimiters at all use
  •      st.nextToken(“”)
14
“register bill Bill Campbell”
  • LoginInterpreter lines 72, 73: create a StringTokenizer st for this String
  • Line 74 checks for no tokens (blank line)
  • Line 77 gets the first token for the value of the variable visitor - in this case “register”
  • Test on 81is true so line 82 sends this LoginInterpreter a register message, passing it the rest of the StringTokenizer


15
register (line 100)
  • Next token is userName bill
  • Get next token using no delimiters at all - so the rest of the line. Send that String a trim message to strip off white space at beginning and end
  • Create a new Directory with no owner
  • Create a new User
  • Arrange for him to own his home Directory
16
back to interpret
  • In most common case, response to Juno login prompt is a Juno username
  • Then that’s the first (and only) token on the line, hence the value of the variable visitor
  • Then interpret method
    • (88) looks up User object in map, with value of visitor String as key
    • (89) creates a command shell for that User
17
Shell object
  • Constructor sets some fields
    • the Juno system that created this Shell (37)                (like issuing Bank in BankAccount)
    • the User and the console (38, 39)
    • the current Directory (the User’s home) (40)
  • Then invokes CLIShell (command line interface) which works just like LoginInterpreter
    • get an input line from the user (50)
    • invoke this Shell’s interpret method
    • done when interpret returns false for moreWork                             (user has typed “logout”)
18
Shell interpret method (60)
  • Create a StringTokenizer for the input line, after throwing away Juno comments (# …)
  • First token is the commandName (66)
  • If it’s “logout”, then done (return false)
  • Replace if else if … with dispatch table
    • (70,71) look up commandObject in command table   (commandName String is key)
    • (76) send commandObject a doIt() message
  • Polymorphism!
19
abstract class ShellCommand
  • Documentation managed here
    • helpString and argstring fields (19, 20)
    • initialized by protected constructor (31, 32)
  • doIt() method (54):
  • abstract public void doIt                      ( StringTokenizer args, Shell sh );
  • doIt is passed the rest of the text on the Juno command line, and the Shell it’s acting for
  • Each concrete ShellCommand implements its own doIt() - polymorphism


20
Creating a ShellCommand object
  • MkdirCommand extends ShellCommand (18)
  • Constructor (24)
    • super invokes ShellCommand constructor, telling it help string and argument string for mkdir
  • implement abstract method doIt (37)
    • next token on line is the name of the Directory to be made
    • tell Directory constructor the name, owner, parent
    • Directory constructor adds the new Directory to the parent
    • public void doIt( StringTokenizer args, Shell sh )
    • {
    •   String filename = args.nextToken();
    •   new Directory(filename, sh.getUser(), sh.getDot());
    • }
21
ShellCommandTable
  • Juno constructor creates a ShellCommandTable (Juno.java line 52)
  • ShellCommandTable.java
    • declare and initialize a TreeMap (line 23)
    • constructor (line 31) invokes fillTable (line 69)
    • fillTable creates one of each concrete ShellCommand objects, invokes install (line 61) to put it in the table
    • client (a Shell) invokes lookup (43), which wraps Map get method (and does the cast)
22
How the dispatch table works
  • In CLIShell loop:
    • get first token on the line: commandName
    • lookup commandObject with commandName key
    • send doIt() message
  • Each particular ShellCommand extends the abstract ShellCommand class, implementing doIt() in its own way
  • Polymorphism at work


23
How LoginInterpreter interpret works
  • get first token on the line
  • use  if - else if - else if … logic
    • if “exit” return false!  // leave loop in CLIlogin
    • if “register”       // create account for new user
    • if “help”            // give help
    • else                    // input is a username
24
Dispatch table vs if-else if-else if
  • To add new commands just add a table entry
  • Command semantics separate from syntax
  • Lots of design overhead, hard to understand
  • Good for large command sets that will grow    (Juno shell commands)
  • To add new commands must edit the main loop
  • Command semantics and syntax in same place
  • Quick and dirty, easy to understand and code
  • Good for small command sets that stay put      (Juno login loop)