240 likes | 322 Views
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. Juno (Chapters 6, 7, ...). We have a (J)File system
E N D
CS110 Lecture 17Thursday, April 1, 2004 • Announcements • hw7 due tonight • pass/fail, withdraw deadline April 8 • Agenda • Questions • Juno • JFile system internals next week Lecture 17
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
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
> java Juno Welcome to mars running Juno version 6 help, register, <username>, exit Juno login: register bill Bill Campbell Juno login: register eb Ethan Bolker Juno login: bill mars> mkdirempty mars> help shell commands type: display contents of a TextFile help: display ShellCommands mkdir: create a subdirectory of current directory newfile: create a new TextFile mars> newfile memo I am a one-line file mars> type memo I am a one-line file mars> logout goodbye Juno login: exit > Sample Juno session Lecture 17
Juno classes Lecture 17
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
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
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
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
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
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
“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 restof the StringTokenizer Lecture 17
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
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
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
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
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
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
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
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
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
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) Dispatch table vs if-else if-else if Lecture 17