Description |
In this exercise you will:
Overview
Create a Java Swing application named ixzip which is able to
print and extract the contents of ZIP files and directories, and synchronize
them.
The program's usage from the command line is ixzip [views] , where
views is an optional number between 2 and 9, with a default value
of 3. The program opens a window which contains one text box for entering user
commands, one "Ok" button for executing the entered command, one label to
display messages about the last action performed, and a set of views (whose
number is determined by the views command-line argument), which can
contain multiple lines of text.
Viewing Directories and ZIP Files
The views are numbered 1 to 9 from left to right. The following commands are
used to open and display views:
-
open N as [directory or zip file] - This
command opens the given zip file or directory, and prints its contents inside
view number N . Printing is done exactly as done in xzip
from exercise 1. A directory and its files are printed exactly as if they were a
zip file with the same name containing the same files.
On success, the text "opened [directory/zip file name] in view N "
should appear in the message bar.
-
close N - This command closes view number
N , clearing its display, and canceling any previous copy or
sync commands in which it is mentioned (these two commands will be
explained below). When the program starts, all views are closed.
On success, the text "closed view N " should appear in the message
bar.
Calling close on a view that is already closed is legal. Calling
open on an already open view is legal, and is equivalent to closing
that view and then reopening it. For example, the following two sequences of
commands are equivalent:
open 1 as c:\web ; close 1 ;
open 1 as d:\my.zip
open 1 as c:\web ; open 1 as d:\my.zip
-
display <short/long> - This command toggles
whether views are displayed in short or long format, as defined for the -s
and -l command-line arguments of xzip respectively.
Executing this command changes the display of all open views to reflect the new
setting immidiately. When the program start, short display is active.
On success, the text "[short/long] display is active " should appear
in the message bar.
In case of error, the message bar should contained an informative message
describing it. Quitting the program is done by pressing the X button on its
window's upper right corner, and this naturally closes all views.
Copying and Synchronizing Views
The main function of ixzip is not to display zip files
and directories, but rather to make copies and synchronize them. Selecting what
will be copied where is done using the copy command:
-
copy X to Y - Select all the files and
directories (recursively) in view number X to be copied into view
number Y . If the same file name already exists in view Y ,
it will be overwritten. The display of view Y should be immediately
modified to reflect how it will appear after the copy operation. Each file or
directory that will be copied from a different view should prefix its name with
that view number in parentheses.
On success, the text Marked view X to be copied to view Y should
appear in the message bar.
For example, assume that the following views have been opened:
1
|
2
|
3
|
one.txt
two.txt
others
three.txt
|
one.txt
four.txt
|
one.txt
four.txt
others
five.txt
|
Then after executing the command copy 1 to 2 , the
display will be as follows:
1
|
2
|
3
|
one.txt
two.txt
others
three.txt
|
(1) one.txt
four.txt
(1) two.txt
(1) others
(1) three.txt
|
one.txt
four.txt
others
five.txt
|
The order of printed files in each view may be different in your program,
since the printing order of files within a directory is undefined. Note that the
copy command only marks files to be copied - actually making the
copy is only done via the commit command, as the next section will
explain. There are two special rules regarding the copy command:
For example, after executing the command copy 2 to 3
in the previous example, the display will show:
1
|
2
|
3
|
one.txt
two.txt
others
three.txt
|
(1) one.txt
four.txt
(1) two.txt
(1) others
(1) three.txt
|
(1) one.txt
(2) four.txt
(1) two.txt
others
five.txt
(1) three.txt
|
The second part of the rule of transitivity means that the order of
copy commands doesn't matter: Executing copy A to B
and then copy B to C has the same effect as executing copy B
to C and then copy A to B . In the above example, the display
would look the same if we executed copy 2 to 3 first and copy
1 to 2 afterwards.
-
Rule of cycles - Whenever a copy X to Y
command causes a cycle to be created between two or more views, then for every
file that exists in more than one of these views, the most up-to-date file (as
dictated by its last modification time) should be copied to all these views. If
two versions have the exact same last modification time, then the version from
the smallest view number should be copied to all these views.
For example, assume that the most up-to-date version of
one.txt is in the directory or zip file displayed in view 1, that the
most recent version of four.txt is in view 2, and that the most
recent version of others is in view 3. Then, after executing the
command copy 3 to 1 on the above table, the display will show the
following:
1
|
2
|
3
|
one.txt
(2) four.txt
two.txt
(3) others
(3) five.txt
three.txt
|
(1) one.txt
four.txt
(1) two.txt
(3) others
(3) five.txt
(1) three.txt
|
(1) one.txt
(2) four.txt
(1) two.txt
others
five.txt
(1) three.txt
|
The rule of cycles preserves the property that the order of
copy commands executed on a set of views doesn't matter, even when cycles
are created. Calling copy X to Y after X is already
copied to Y through some cycle (for example, calling copy 1
to 3 on the above table) is legal, and similarly calling copy X to Y twice is legal. Note that whenever a
cycle occurs, the list of files and directories as well as the source view for
each file will be the same in all views participating in the cycle. This has the
effect of synchronizing all the views in the cycle, and to make this common
operation easier for users, the following command is defined:
Whenever a view is closed, all copy and sync
operations involving it are discarded. For example, the following sequence of
commands:
open 1 as c:\web
open 2 as d:\web.zip
open 3 as e:\backups\web
copy 1 to 2
copy 2 to 3
copy 3 to 1
close 2
Is equivalent to this series of commands:
open 1 as c:\web
open 3 as e:\backups\web
copy 3 to 1
Commit and Rollback
While copy and sync enable a user to mark
files and directories for copying and view the results, actual changes to the
file system are only caused by this command:
-
commit - This command performs all the marked
copies in the actual file system. This can involve directory to directory,
directory to zip file, zip file to directory or zip file to zip file transfers.
After this operation all views should be refreshed, and all the previous
copy/sync commands are discarded.
On success, the text Copy operations were committed should appear
in the message bar.
For example, after executing commit on the display
from the end of the previous section, files will be copied and then the display
will show:
1
|
2
|
3
|
one.txt
four.txt
two.txt
others
five.txt
three.txt
|
one.txt
four.txt
two.txt
others
five.txt
three.txt
|
one.txt
four.txt
two.txt
others
five.txt
three.txt
|
The user can also decide not to perform actual copying of the marked files,
using this command:
-
rollback - This command discards all previous
copy/sync commands, and refreshes all views. This is equivalent to
closing and reopening all views in a single command.
On success, the text Copy operations were rolled back should appear
in the message bar.
For example, after executing rollback on the display
from the end of the previous section, no files will be copied and the display
will show:
1
|
2
|
3
|
one.txt
two.txt
others
three.txt
|
one.txt
four.txt
|
one.txt
four.txt
others
five.txt
|
Undo and Redo
The last two commands that ixzip should support are
the following:
-
undo - Undo the last command. The open ,
close , copy , sync and display
commands can be undone, and the result of undoing them should restore the
program to its exact state before the command was executed. On success, the text
Command [command name] was undone should appear in the message bar.
The commit and rollback commands cannot be undone, and
trying to undo them should result in an informative error message. The user can
undo an unlimited number of commands - that is, the entire history of commands
since program startup or the last commit or rollback
command should be kept.
redo - Redo the last command that was undone; or in
other words, undo the last undo operation. This command can only
be called if command preceding it was undo ; if undo
was called multiple times, then redo can be called multiple times
as well to redo all these undo commands. On success, the message
bar should contain the text of the relevant command that was redone.
As an example, the following table demonstrates a list of commands,
and the text that should appear in the message bar after each command:
Command: |
Message bar after the command: |
open 1 as c:\projects
|
Opened c:\projects in view 1
|
open 2 as d:\projects
|
Opened d:\projects in view 2
|
undo
|
Command open was undone
|
open 2 as d:\backup\projects.zip
|
Opened d:\backup\projects.zip in view 2
|
redo
|
Error: Cannot redo since last command was not undo
|
sync 1 and 2
|
Marked views 1 and 2 to be synchronized |
undo |
Command sync was undone |
redo |
Marked views 1 and 2 to be synchronized |
commit
|
Copy operations were committed
|
undo
|
Error: No commands to undo |
Performance and Testing Considerations
Although ixzip is an interactive program supporting at most nine views, in
its next version the same code is planned to be used as a synchronization
server, and will be required to handle up to thousands of concurrent
synchronizing client directories and zip files. This has two implications.
First, you should design this program as a performance-critical application:
Second, you should make it easy to reuse as much of the program's
code as possible in a different executable that will not have a Swing user
interface:
Such a separation is important in every application that contains a graphical
user interface for another reason: unit testing. Note that it is impossible to
directly unit-test a GUI, since you have no way to replace the human using the
keyboard and mouse. Unit tests only work on objects, and so you must maintain
the amount of code that you don't unit test (and only test manually, in this
exercise) to an absolute minimum.
Design
Answer the following questions about your design, in one or two paragraphs at
most:
- Explain how your code is divided into packages, and what is the
dependencies graph between packages. Explain the rationale behind this
division.
- Explain how your design handles a
copy/sync command in a time
that is proportional to the number of involved views, and not to the number of
all views.
- Explain how your design handles a
commit command in a time
that is proportional to the number of files and directories being copied, and
not to the total number of files and directories in the open views.
Then, for each of the following possible future requirements from ixzip ,
explain in 2-3 sentences how your design can be easily extended to implement
them.
- It may be required to add a
recursion <of/off> command, which
toggles whether copy and sync commands operate
recursively on directories or not. Note that the default, which you must code
and test in this exercise, is to copy directories recursively.
- It may be required to support
copy/sync of a subset of files
from one view to another. For example, a command such as copy *.java
from 1 to 2 would mean that only *.java files should be
copied from view 1 to view 2.
-
It may be required to support other commands on files displayed in
views, for example to rename a file or directory, delete
a file or directory, move a file from one view to another and so
on. Undo and redo functionality may be required for such commands as well.
Code & Unit Test
All the code & unit test guidelines from
Exercise 1 apply to this exercise as well. In addition, you are required to
use the code base and tests you developed for xzip , and you must
submit it as well. The submitted code, unit tests, UML diagrams and Ant build
file should include both xzip and ixzip in full. You
are allowed to make any changes in your xzip code to make it more
easily reusable for ixzip , but note that you will have to make sure
that xzip still works after these changes, and to maintain its unit
tests as well.
The time and effort required to complete this exercise highly depend on the
quality of your design. The recommended order in which to think about your
design is to design the required data structures first, the classes and
operations that use these data structures second, and the Swing UI and main
program flow last. Also, think in advance about how to partition your code into
packages, and provide separate test classes for each package.
|