Design Overview
Goals
The library has been written with the following goals in mind:- Ease of use. Third parties should be able to learn how to use the library very easily. The library is comprehensively javadoc'd and this document tries to explain how it fits together. The bundled CVS command line tool (i.e. e.g. java -jar org-netbeans-lib-cvsclient.jar -d :pserver:anoncvs@netbeans.org:/cvs co javacvs) also enables programmers to see how it works. It is hoped that the library provides enough abstraction to avoid the need for anything more than basic understanding of how the CVS protocol works.
- Extensibility. The library provides a framework for processing CVS commands. Should the protocol be extended or altered, it should be easy to modify the library to handle this.
- Compatibility. The command-line CVS implementation from
www.cvshome.org is by far the most common way of interacting with
CVS repositories. Full compatibility with that tool is required, and the user should be able to
switch between that tool and one using this library without either tool breaking. Any incompatibility
should be considered a bug in this library.
However, should a more efficient way of storing administrative files and information be developed for use by this library, it should be possible to specify easily an alternative implementation of various functions to improve performance at the expense of compatibility. - Quality. The library should be written with maintainability in mind. All code must adhere to the coding standards and all methods must have appropriate javadoc comments. Any significant changes must be discussed on the javacvs-dev mailing list before being committed to the repository.
Classes
UML diagrams
Thanks to Financial Finesse for donating the work of Myron Ahn, who created these UML diagrams that show the structure of the library:Making a connection
Making a connection with a server using standard CVS can be achieved in several ways, e.g. server, pserver, kserver and so on. Currently pserver and server are supported. The interfaceorg.netbeans.cvsclient.connection.Connection
provides a mechanism for getting input and output streams for communicating with the server, and for setting up those streams.
PServerConnection
adds extra calls to set up pserver-specific information, such as the port
number.
Passwords
Password scrambling could be done in different ways although the author is unaware of more than one scheme being in existence. However, for future expandability, aScrambler
interface exists,
and StandardScrambler
implements it, scrambling characters as described in the CVS protocol
document 1.10.
The storing of the password in a .cvspass
file is not part of the protocol hence is not
part of the library. It could be added to a utilities package, perhaps. A method exists in the test
harness to do this, though and this can be used freely.
Logging
The command-line CVS client has the facility to log data transmitted between client and server. The library provides the same facility. The log destination can be set using the property "cvsClientLog". Either set it to a file location (where it will write log information) or to the value "system" to make it send output to stderr. The filename, if specified, will have .out and .in appended to it for data transmitted to and received from the cvs server respectively.Communication with the server
Theorg.netbeans.lib.cvsclient.Client
class is responsible for the coordination of communcation with the server.
It accepts a org.netbeans.lib.cvsclient.connection.Connection
object to provide the channel for communication. Most of its work
is done by delegation. Once you have constructed a Client
you typically pass it
org.netbeans.lib.cvsclient.command.Command
instances to execute.
The CVS protocol is defined in terms of requests and responses. However, these do not map directly to anything that an average CVS user could relate to. A typical CVS command, such as update or commit requires using several requests and processing a variety of responses from the server. The request and response packages handle these protocol elements and are discussed later.
Issuing Commands
Theorg.netbeans.lib.cvsclient.command
package contains the commands that users of
the API use. To send a CVS command, the user constructs an object that extends Command
and sets some parameters on it (optionally) before passing the command to the Client
instance to execute. The commands implement all or nearly all of the options available in the CVS
command line client. Global options can be set using the GlobalOptions
class.
Currently implemented commands are:
- add
- checkout
- commit
- diff
- log
- remove
- status
- tag
- update
Command Details
The implementation of each command basically involves putting together a list of requests. Users of the library do not really require to know the details of this.Since many of the commands' request sequences are very similar, a generic implementation
of Command
is provided that many commands can easily subclass, BasicCommand
. The interface org.netbeans.lib.cvsclient.ClientServices
provides the command with any
facilities it might require to create the requests, such as getting information from the
administrative files (e.g. the Entries file).
Requests and Responses
Request classes essentially just format data and send it to the server over theOutputStream
.
Again, the user of the library is not concerned with the actual implementation of the Request
classes.
Responses read data from the server, and verify it is what is expected and perform various functions
depending on that data, for example writing files or updating administrative files. One issue with
the handling of responses is that the server intermingles the transmission of character data and
bytes (file transmissions). This means that Readers
and Writers
cannot be
used. This has caused problems with Japanese localisation - for more details see
this bug report.
Admin Files
The writing of the administrative details (commonly stored in a CVS subdirectory under each directory) is handled by anAdminHandler
. The Client
class delegates various things to
the installed handler. Currently there is only one handler supplied, the
StandardAdminHandler
(that provides compatibility with standard command-line CVS) but
it is hoped that this could be extended to provide a high-performance handler.
Events
The client application is informed of the changes a command has made by being sent a series of events. For example, if you perform an update and a file is changed, you are sent aFileUpdatedEvent
.
This is a list of events current fired:
FileAddedEvent
. Indicates that a file has been added (created).FileInfoEvent
. Fired when a structure containing data has been completed (see builders for details).FileRemovedEvent
. Indicates that a file has been removed (deleted).FileUpdatedEvent
. Indicates that an existing file has been updated.MessageEvent
. A message has been sent from the server that should be displayed to the user.EnhancedMessageEvent
. Messages that are generated by the library to help the cvs client software display extra information to the user. Tells the client about files being sent to the server and also files being merged.
FileInfoContainers
For commands that return a lot of structured data, such as Log, the library provides classes that parse the output of CVS commands and turn them into useful data structures. This saves the application programmer from writing a lot of event handling code.The classes that parse the output and turn it into a meaningful structure are known as builders. The structures themselves are known as FileInfoContainers. There are several subclasses that are of interest to the library user:
DefaultFileInfoContainer
. Contains generic information about files such as type (is it a directory?) and state (was it updated or merged?).CommitInformation
. Populated after execution of a commit command. Includes the revision of the file.LogInformation
. Populated after execution of a log command. Therefore contains a great deal of information!ModuleListInformation
. Contains the list of modules (e.g. after the equivalent of cvs co -c).PipedFileInformation
. When you pipe information using -p, the file is saved as a temp file and this class enables you to find out the details for that file.RemoveInformation
. Details of a file that has been removed.StatusInformation
. Populated after execution of a status command. Also contains quite a lot of information.AddInformation
. Populated after executing the add command. Allows you to determine if the file has been resurrected or if it was added for the first time.