17.ppt

advertisement
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
Lecture 17
1
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
Lecture 17
2
Command prompt interface to
windows file system
Lecture 17
3
Lecture 17
4
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,
Lecture 17
5
Sample Juno
session
Lecture 17
6
Juno
classes
Lecture 17
7
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)
Lecture 17
8
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)
Lecture 17
9
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: " ));
}
}
read a line from the console, interpret it,
loop until interpret returns false
Lecture 17
10
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
Lecture 17
11
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|
Lecture 17
12
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(“”)
Lecture 17
13
“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
Lecture 17
14
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
Lecture 17
15
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
Lecture 17
16
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”)
Lecture 17
17
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!
Lecture 17
18
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
Lecture 17
19
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());
}
Lecture 17
20
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)
Lecture 17
21
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
Lecture 17
22
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
Lecture 17
23
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)
Lecture 17
24
Download