1
|
- Announcements
- hw7 due tonight
- pass/fail, withdraw deadline April
8
- Agenda
- Questions
- Juno
- JFile system internals next week
|
2
|
- 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
|
|
4
|
|
5
|
- 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
|
|
7
|
|
8
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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
|
- 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)
|