WebDAV Working Group | Jim Amsden, Geoff Clemm |
INTERNET DRAFT | IBM, Rational |
<draft-ietf-webdav-versionmodel-00.html> | February 1, 1999 |
Expires August, 1999 |
This document is an Internet-Draft. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or made obsolete by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress."
To view the list Internet-Draft Shadow Directories, see http://www.ietf.org/shadow.html.Distribution of this document is unlimited. Please send comments to the Distributed Authoring and Versioning (WebDAV) working group at ietf-dav-versioning@w3.org, which may be joined by sending a message with subject "subscribe" to ietf-dav-versioning-request@w3.org. The main WebDAV mailing list at w3c-dist-auth@w3.org may also be used for comments. It may be joined by sending a message with subject "subscribe" to w3c-dist-auth-request@w3c.org.
Discussions of the WebDAV versioning working group are archived at http://lists.w3.org/Archives/Public/ietf-dav-versioning/. Discussions of the WebDAV working group are archived at http://www.w3.org/pub/WWW/Archives/Public/w3c-dist-auth.
Distributed authoring for the web requires support for versioning resources, parallel development, and management of configurations of related resources. This document presents a high-level model of WebDAV versioning that realizes the requirements and use cases presented in the "Goals for Web Versioning" available at http://www.ietf.org/internet-drafts/draft-ietf-webdav-versionreqs-00.html.
Status of this Memo | 1 |
Abstract | |
Contents | |
Introduction | |
WebDAV Versioning Semantics Overview | |
Versioning Model | |
Rationale | |
Security Considerations | |
References |
This document provides a model of the versioning extensions to WebDAV including parallel development and configuration management. This model will hopefully provide a framework in which the WebDAV versioning Working Group can specify and evaluate the semantics of various alternatives as they are being explored. The model provides a more formal definition of the elements manipulated by WebDAV, and the behaviors that are supported. By using this model, the working group can concentrate on the semantics of the versioning and configuration management operations without getting bogged down in the details of how it might be represented in a particular protocol or specific implementations. Once the objects and methods have been identified, the protocol can be specified so that these methods can be executed remotely by a WebDAV compliant server.
Various use cases were captured in the goals document, and explored by developing collaboration or object interaction diagrams that describe the sequence of events and how each participating object responds. This can be used to completely formalize the accepted versioning semantics of WebDAV and can be used as an adjunct to the published protocol specification. Such a model will be vary useful for fleshing out the exact semantics and for documenting those semantics in a form that is very useful to server implementers.
Finally, this model provides a tentative specification for a high-level API that could be used to simplify client access to the WebDAV versioning protocol.
In defining the semantics for WebDAV versioning, it is helpful to adhere to some guidelines. The purpose of these guidelines is to help select from various alternatives, and to ensure the result provides the required functions but is as simple as possible so that servers can easily implement the protocol on a variety of repository and configuration management systems, and clients can easily be written and used by web application authors.
Start from where we are in WebDAV Level 2 and add support for versioning, parallel development, and configuration management.
Add the new functions while minimizing the number of new concepts, methods, etc. required to support them. This will hopefully keep the protocol simple making it more accessible to the broader authoring community typical of Web applications.
Define new semantics whenever possible by using semantics already defined by WebDAV. This enforces existing semantics, facilitates support for back-level clients, makes it easier to layer new optional functionality, and provides for simpler, more regular semantics.
Avoid overloading semantics of existing methods to mean different things. Introduce new methods for different behavior.
Specify the semantics of versioning and configuration management in an implementation independent way. This will ensure maximum possible flexibility for implementing servers and integrating existing version management schemes.
Try to avoid choices that require or imply a specific implementation, that require clients or servers to retain and communicate ancillary state in order for methods to work, or that limit flexibility for future expansion.
In the rules below, the word "effectively" is used to formally and completely describe the effective semantic results of an operation without specifying any particular implementation. Servers are free to supply any implementation desired as long as it has has the same effective semantics.
The protocol should be sufficiently high level to not constrain server implementations but at a sufficiently low level that it does not constrain supportable policies.
This section provides an overview of the WebDAV versioning semantics. Subsequent sections provide detailed methods and semantic rules.
A resource is any potentially statefull entity that can be accessed on the web through a URL. The model below defines an interface, Resource that abstracts a web resource and its behavior. It also defines a specialization of Resource called ResourceCollection that adds containment or grouping behavior for Resources and other ResourceCollections using the Composite pattern.
A resource may or may not be versioned. When a resource is first created by using a WebDAV PUT or MKCOL method, or Resource.setContents(), it is created as an un-versioned resource. A resource may be checked in to make it a versioned resource, and to create the initial or first revision. A checked in revision cannot be modified by anyone at any time.
Each revision of a versioned resource must be distinguished from any other revision. Revision names are used to distinguish revisions and consist of either a revision id or any number of revision labels. A revision of a versioned resource is given a system assigned revision id when it is checked in. This revision id acts as an immutable identifier distinguishing this revision from all others of the same versioned resource. The revision id cannot be changed, assigned to another revision, or reused.
A user may assign other revision names called revision labels to a revision in order to distinguish it from other revisions using more meaningful names. The revision labels must be unique for any given versioned resource, but may be reassigned to any revision of the versioned resource at any time. Revisions of different versioned resources may have the same label. There is a distinguished, floating label called "latest" which always refers to the latest revision in a given activity.
Subsequently, a client may checkOut the resource which creates a working resource. A working resource is identical to an un-versioned resource in all respects other than that it has one or more successors. It may be edited by setting its properties or contents any number of times. When the client is satisfied that the working resource is in a state that should be retained in the version history, the client does a Resource.checkIn() to create a new revision of the resource.
Users can use checkout/checkin to register intent to modify a versioned resource similar to the way lock and unlock are used in DAV level 2. The sense is reversed though. A checked in revision cannot be changed without checking it out first.
The resource may be checked in as either mutable or immutable. An immutable revision cannot be changed and provides a stable environment for history management, change recovery, merging, and configuration management. A mutable revision is more suitable for situations where versioning is treated more informally, and it is not necessary or desirable to maintain strict version histories, or to be guaranteed that it is always possible to backtrack to a previous point in time and recover. This form of versioning is typical of modern document management systems. If the revision is mutable, a subsequent checkout makes the revision a working resource, and allows the revision to be updated in place without creating a new revision. Any previous contents of the revision are lost. A mutable revision can also be checked out creating a new revision if the user wants to retain the previous revision. If the revision is immutable, a checkout must create a new revision. Servers may choose to not allow revisions to be checked in as mutable, or they may not allow a revision to be checked out without creating a new revision.
When a revision of a versioned resource is already checked out, another user cannot check it out again and therefore cannot make any changes. In order to increase resource availability, avoid serializing work, and allow multiple users to make changes simultaneously, a server may support parallel development. Parallel development allows users to choose to do work on a resource that is checked out by someone else in a different context, and to merge those changes together at some later time.
Resources are checked out in the context of an activity. An activity abstracts a set of related changes a user is making to revisions of versioned resources. Each activity represents a parallel thread of development. Servers that don't support parallel development only support one activity. A revision that is already checked out in an activity cannot be checked out again in the same activity. If parallel development is desired, a user can checkout the revision in another activity and merge them later.
Resources, working resources, and revisions of versioned resources are all accessed using a URL. Specific revisions of a versioned resource can be accessed by specifying the resource URL and a version label. However, versioned resources are usually accessed using a simple URL. The revision selected when a specific revision name is not specified is resolved through a workspace. A workspace is a resource that provides a context defining a mapping between URLs for versioned resources, and specific revisions. This allows versioned resources and un-versioned resources to be accessed the same way supporting relative ULRs and DAV level-2 clients that are not versioning aware.
A workspace contains a revision selection rule. A revision selection rule can specify any number of entries consisting of revision labels, activities, configurations, or the special floating labels "checkedout" or "latest". The rules are applied in order until the first match is found. A label matches a revision having the matching label. Activity specifies the latest revision that was modified in an activity. Configurations specify a revision contained in the configuration. Checkedout specifies any revision that is currently checked out. Finally, latest refers to the latest revision. Any potential matches after the first match are ignored. Revisions are selected by iterating over the entries in the revision selection rule in order until a matching revision is found. If there is no matching revision, then a resource not found status is returned. This rule is applied to collections to select the revision that determines their member versioned resources, and to other resource to determine the revision containing their contents.
The first three entries of the revision selection rule are defined by the server, and are fixed. These entries are: "checkedout", the current activity, and the merge activity. The result is that revisions are selected using the following rules in order: 1) if there is a checked out revision, then it is selected. else 2) if there is a revision that is checked in under the current activity, then it is selected, else 3) if the resource is a member of any activity in the process of being merged into this workspace, then it is selected, else 4) finally, other entries in the workspace revision selection rule are applied to select the revision. The revision selection rule can only contain one or two activities, the current activity and optionally the merge activity. This is required to prevent non-deterministic merge conflicts.
If a request is made and no workspace is specified, a default workspace containing "checkedout", activity named "mainline", no merge activity, and "latest" in the version selection rule is used.
A workspace represents a volatile set of revisions. Any new checkouts, changes to the current activity, merging operations, changing labels, or changes to the revision selection rule may result in the selection of different revisions. A configuration is a resource that represents a set of immutable revisions. A configuration contains a specific revision of each member versioned resource. A configuration cannot contain a mutable revision because the semantics of configurations cannot be guaranteed. A workspace whose version selection rule contains a configuration will always return the same revisions as long as there are no revisions checked out and nothing in the current activity.
Configurations are convenient for defining a persistent set of revisions that relate to each other in some specific way at some point in time. This can be useful for publishing consistent versions of resources to publish or deploy an application, or for recovering to a specific version state for legal or maintenance reasons.
Collections, activities, and configurations are all related in that they have members. The members of a collection are the versioned resources it contains, without specifying any particular revision. The members of an activity are the revisions that have been changed. The members of a configuration are particular revisions. So while they are similar, each has it's own special semantics.
A collection contains a set of members. For versioned collections, the members are versioned resources, not particular revisions. To add or remove members from a revision of a versioned collection, it must be checked out just like any other resource. Creating a new revision of a member, or modifying a member has no effect on the collection. Deleting a versioned resource that is an internal member from a collection does not delete the versioned resource, it only deletes the member from that version of the collection. The resource may still be a member of a previous or subsequent revision of the collection. The URL for a collection without a particular revision name is resolved to a particular revision using the workspace the same as any other resource. If the collection is part of a URL for some other resource, then its members are determined from the selected revision.
When a revision of a collection is added to a configuration, then recursively, so are all its members. This is similar to COPY and MOVE which must specify infinite depth.
A revision may have more than one predecessor and more than one successor. A predecessor of a revision is a revision that this revision was derived from. A successor of a revision is a revision derived from this revision. Each revision has a line-of-descent that consists of a path from the initial revision of the resource to the selected revision along the successor/predecessor relationships. A line-of-descent specifies a portion of the overall history of the versioned resource.
Each revision has a predecessor relationship with the revision it was checked out or merged from, and a successor relationship with revisions that were checked out from it. Revisions are related to their predecessor through a is-derived-from or merged-from relationships. The revision history of a versioned resource includes these relationships.
Each activity represents a separate parallel thread of development. Users make their changes in the context of an activity. Changes to the same revision must be done in separate activities. At some point, a user may want to merge changes made to the same revision together to create a new revision containing the combined updates. In order to do a merge, it is first necessary to determine what must be merged. A merge conflict report lists the resources that have been modified in parallel in different activities. The merge conflict report is generated using the following rules: 1) if the merge source specifies a predecessor of the revision selected by the workspace, then the workspace revision is selected, else 2) if the merge source specifies a successor of the revision selected by the workspace, then the merge source revision is selected, else 3) the merge source and the current workspace specify revisions that are on different lines-of-descent which results in a merge conflict that is included in the merge conflict report.
A user can request the differences between two revisions of a resource (servers may provide a differences report, but they must at least indicate if they are the same or not). A user can request conflicts between an activity and the current workspace to generate a merge conflict report. A user can also request the differences between a configuration and the current workspace which lists at least the activities that are contained in the configuration but not in the workspace and vice versa. So differences are detected at different levels: content differences for resources, revision differences for activities, and activity differences for configurations.
Once the merge conflicts are known, a user resolves the conflicts by merging the source activity with the workspace. This enters the merge source into the workspace, and sets the current conflicts that must be resolved. The conflicts are resolved by merging the revisions from the merge source into the revision selected by the workspace to create a new working resource. Servers may perform some default auto merging, but at a minimum, the merge is done by checking out the revision in the current activity (if it is not already checked out) and noting the merge from the merge source. This creates an additional successor/predecessor relationship between the merge source and workspace revisions called merged-from. The conflict is now removed because the working resource is now a successor of both the source and target revisions. It is the user's responsibility to apply the differences in the two revisions in an appropriate manner. The merge is complete when all the conflicts are resolved, all differences have been merged, and the resources are all checked back in. The merge source can now be removed from the workspace as all of its changes are now included in the current activity. Only one activity can be merged at a time in order to provide deterministic, manageable conflict reports.
When merging mutable revisions, the merge conflict report may be inaccurate as the source revision may change without the system being aware. Users are responsible for applying any changes to ancestor revisions to their descendants as appropriate. The system cannot determine if there are any changes that need to be applied other than by looking a the last-modified dates of the revisions.
Locking a versioned resource prevents any revision from being checked out in any activity. Locking a revision of a versioned resource prevents just that revision from being checked out in any activity.
The following sections define the model in more detail, and provide the semantic rules for versioning, branching, and configuration management.
A Repository represents a central point of control and a source for resources managed by the repository. It is introduced to support methods that apply to all resources contained in the repository. A repository corresponds to the root collection of the resources contained in it.
Repository | |
getDefaultActivity() : Activity | Get the default activity for this repository. If the default activity was never set, an activity called "mainline" is returned. |
setDefaultActivity(defaultActivity : Activity) | Set the default activity for this repository to the given value. |
getActivities() : Activity[] | Get a list of all the activities that currently exist in this repository. |
getWorkspaces() : Workspace[] | Get a list of all the workspaces that currently exist in this repository. |
Interface Resource represents anything on the Web that is accessible through a URL, i.e., a WebDAV resource. Resource provides a number of methods that abstract resource behavior as specified by WebDAV including:
The following table gives the methods of Resource concerning versioning and configuration management, and a brief description of their semantics. Not all of these methods will correspond directly to WebDAV protocol. Many of them are client convenience methods to make the semantics clearer and easier to use. These methods should be considered to be implemented in terms of other more primitive methods that do correspond directly to methods of the protocol.
Note that in the model above, all the types are interfaces even though associations are shown. This is just to simplify the model for exploratory purposes. The model also does not imply any particular implementation of these interfaces. The model should include implementation classes that use the State pattern to factor out the differences in behavior that arise as a resource goes through its lifetime. A Resource implementation delegates state-dependent methods to its current state object where they can be implemented in a state-specific way. ResourceState is an abstract super-class of all Resource states. Its methods include all the methods of Resource that are state dependent. For example, setContents() is a state-dependent method. It's behavior changes depending on the lock state of the resource. Similarly, many of the methods that update a resource or its properties depend on the versioning and mutability states of the resource. Likely candidates for Resource states (subclasses of ResourceState) are:
This approach provides a simple way of modeling state-specific behavior without complicating the model with many more interfaces, classes, multiple-inheritance, etc. Also, many versioning methods can be equally well implemented on un-versioned resources. For example, getPredecessor() could just return NULL for an un-versioned resource as it doesn't have a predecessor. Neither does the root revision. Taking this approach simplifies both the model and the versioning semantics.
Resource |
|
Resource.create(url : String, label : String = NULL) : Resource | Instantiate a Resource with the given URL and label. If label is specified, the Resource corresponds to the instance with the given label. This method does not actually access the server, but creates a Resource instance that can be used to call other methods like exists(), getContents(), etc. That is, it sets the context of the resource and its URL and revision label. |
Resource.create(url : String, workspace : Resource = NULL) : Resource | Instantiate a Resource with the given URL in the context of the given workspace. If workspace is specified, the Resource corresponds to the revision selected by the workspace. This method does not actually access the server, but creates a Resource instance that can be used to call other methods like exists(), getContents(), etc. That is, it sets the context of the resource and its URL and workspace to use for resolving that URL to a specific revision. |
checkIn(isMutable : boolean = false) | Checkin a resource creating a new revision and releasing the
resource in the current activity so others may check it out. If isMutable is true, the revision is marked as a mutable revision and can be checked out in-place at some future time. A server may refuse to check in a resource as mutable. If isMutable is false and the predecessor is mutable, the predecessor is set to the closest immutable ancestor. This is required to ensure accurate merge conflict reports. |
checkOut(inPlace : boolean = false) : Resource | Check out a resource in order to create a new working
resource. A resource is checked out in the context of the workspace current activity, and
can only be checked out once in a given activity. If inPlace is true, and the revision is mutable, then the revision itself becomes a working resource and all updates are in place, destroying any previous contents. CheckOut fails is the resource is not a versioned resource, is already checked out in the current activity, or is locked. |
cancelCheckOut() | Cancel the checkout of this working resource, delete the working resource, and remove any predecessor/successor relationships created by checkout or merge. An exception is raised if the resource is not currently checked out. |
getVersioningOptions() : Element | Get the versioning options for this resource. Versioning
options are established by the server and include:
|
isAutomaticallyVersioned() : boolean | Return true if this resource is automatically versioned on each method that updates its state (content or properties). Automatic versioning is used to support updates by non-versioning aware clients. |
getMutableProperties() : String[] | Return a list of the names of mutable live properties for this resource. These are properties that may change even when the resource is checked in. |
isVersioned() : boolean | Return true if this resource is a versioned resource. A versioned resource has multiple revisions and a revision history. |
getRevisionHistory() : Document | Get the revision history for a versioned resource. The revision history lists the revisions of a resource and their predecessors and successors. The format of the document is given in section Revision History. The document will not contain any revisions if the resource is not versioned. |
getRevisionId() : String | Get the system-assigned revision id for this revision. This
revision name cannot be changed, and cannot be reused if this revision is deleted. Returns
NULL if the resource is not versioned. The revision id must be unique for the revision across all time. Servers may choose to use an opaque identifier consisting of a time stamp similar to UUIDs for lock tokens. |
addLabel(label : String) | Add a label to this revision of a versioned resource. The
versioned resource must not already have the label on any revision, and the label cannot
be the same as any revision id. The label must be removed from one revision before it can
be added to a different revision. The operation will fail if the resource is not a
versioned resource. Labels are used to provide meaningful names that distinguish revisions of a versioned resources. They can be used in the revision selection rule of the workspace to specify what revision should be used in that workspace. Revisions may also be accessed by a specific label overriding the workspace. A revision does not need to be checked out to add a label. |
removeLabel(label : String) | Remove a label from a revision. An exception is raised if the
revision does not have this label. A revision does not need to be checked out to remove a label. |
getLabels() : String[] | Return all the labels on this revision, not including its revision id. |
isLabeledWith(label : String) | Return true if any revision of this versioned resource is labeled with the given label. |
getRevisionDescription() : Element | Get the description of this revision. The description is an XML element in order to support extensible description formats. This operation is valid for un-versioned resources. |
setRevisionDescription(description : Element) | Provide a description of this revision. The description is an XML element in order to support extensible description formats. This operation is valid for un-versioned resources. |
getPredecessor() : Resource | Get the predecessor of this revision, that is, the revision from which this revision was checked out. Returns NULL if the Resource has no predecessor. |
getMergePredecessors() : Resource[] | Get the predecessors of this revision that were established by merging changes from another activity. The list may be empty. |
getSuccessors() : Resource[] | Get the immediate successors of this revision, that is, revisions that were created by checking out this revision in some activity. The list may be empty. |
getActivity() : Activity | Get the activity this revision was created in. Returns NULL for un-versioned resources. |
isCheckedOutIn(activity : Activity) : boolean | Return true if this revision is checked out in the given activity. |
mergeWith(mergeSource : Resource) : Resource | Merge the given revision with this working resource or this
revision in this workspace by setting the merge predecessor. If this resource is not a
working resource, then perform the merge by checking out a new revision in the current
activity, and adding a merge predecessor relationship with the new working resource. The
result is a checked out working resource that the user agent must update to actually merge
the changes. The merge source can be a mutable revision, but once the merge has been done, any in-place changes to the merge source will not result in a new merge conflict. |
mergeCandidates() : Activity[] | Return a list of activities on different lines of descent for this revision that are candidates for merging. Returns NULL if the resource is not a versioned resource. |
differencesWith(resource : Resource) : Document | Return an XML document describing the differences between two revisions, both contents and properties. |
isMutable() : boolean | Return true if this revision is mutable, that is, it was
checked in as a mutable revision. Mutable revisions may be checked out in place in order
to make updates that do not require a new revision. An immutable revision can never be made mutable, but a new revision can be. A mutable revision can be made immutable by checking it out in place and checking it back is as immutable. |
ResourceCollection is a specialization of Resource that aggregates Resources and ResourceCollections using the Composite pattern. It provides methods for creating collections and accessing their members, as well as methods that add a depth parameter for controlling the behavior of Resource methods when they operate on collections. Depth specifies if the method applies to the collection, the collection and its immediate members, or the collection and recursively all its members.
The most significant new behavior is the ability to add, remove, and get members of the collection. Other Resource methods are overridden or specialized to support specific collection semantics or the depth parameter. Versioning adds a number of new methods:
ResourceCollection |
|
addLabel(label : String, depth : String = ThisResource) | Add a label to this revision of a versioned resource and
potential recursively all its members. Any effected revision must not already have the
label, and the label cannot be the same as the revision id. The operation will fail if the
collection is not a versioned resource. Labels are used to provide meaningful names that distinguish revisions of a versioned resources. They can be used in the revision selection rule of the workspace to specify what revision should be used in that workspace. Revisions may also be accessed by a specific label overriding the workspace. |
removeLabel(label : String, depth : String = ThisResource) | Remove a label from a revision and potential recursively all its members. An exception is raised if the revision does not have this label. |
getCheckedOutMembers() : Resource[] | Returns a list of the members of this collection that are checked out in the current activity. |
A versioned resource represents all revisions of a particular resource. A versioned resource corresponds to the root or initial version of all the revisions of a resource.
VersionedResource |
|
getVersioningOptions() : Element | Get the versioning options for this resource. Versioning
options include.
|
isAutomaticallyVersioned() : boolean | Return true if this resource is automatically versioned on each method that updates its state (content or properties). Automatic versioning is used to support updates by non-versioning aware clients. |
getMutableProperties() : String[] | Return a list of the names of mutable properties for this resource. These are properties that may change even when the resource is checked in. |
getRevisionHistory() : Document | Get the revision history for a versioned resource. The revision history list the revisions of a resource and their predecessors and successors. The format of the document is given in section Revision History. The document will not contain any revisions if the resource is not versioned. |
delete() | Delete this versioned resource. The versioned resource and all its revisions are removed from the repository. Any workspaces resolving to a revision of this versioned resource will return resource not found status. Configurations containing a revision of this resource will result in resource not found status when used in the revision selection rule for a workspace. |
An activity represents a named set of revisions to versioned resources. A revision of a resource is checked out in the context of the current activity of the workspace. Edits are made in the context of that activity, and the association is maintained when the resource is checked back in. The same resource can be checked out in many different activities at the same time if the server supports parallel development on that resource. These activities may be merged into other workspaces at some later time to combine the changes. Activities may be used to manage units of work required to update a set of resources in some related way.
Activity |
|
getMembers() : Resource[] | Returns a list of revisions that were made in this activity. |
contains(resource : Resource) : boolean | Returns true if the resource is, or was modified (i.e., checked out) in this activity. |
addLabel(label : String) | Add a label to the latest revision of all versioned resources modified in this activity. Any effected revision must not already have the label, and the label cannot be the same as the revision id. The operation will fail if the resource is not a versioned resource. |
removeLabel(label : String) | Remove a label from the latest revision of all versioned resources modified in this activity. An exception is raised if the revision does not have this label. |
A Configuration represents a persistent, named set of specific revisions of resources. A configuration can be used to collect together consistent versions of resources that correspond to some release or other unit of work. Configuration specializes ResourceCollection in order to add these new semantics. When a collection is added to a configuration, its members are also recursively added to the configuration. Each member of a configuration must specify a particular version label. The configuration member is identified by its URL and revision id.
Configuration |
|
add(revision : Resource) | Add a revision of a resource to a configuration. The revision must be immutable. An exception is raised if the configuration already contains a revision of the resource. This is equivalent to copying a link to a revision into the configuration collection with the additional semantics given below. |
add(url : String, label : String = null) | Add the labeled revision of a resource to a configuration. The revision must be immutable. An exception is raised if the configuration already contains a revision of the resource. This is equivalent to copying a link to a revision into the configuration collection with the additional semantics given below. |
add(url : String, workspace : Workspace) | Add the revision of a resource selected by the workspace to a
configuration. The revision must be immutable. An exception is raised if the configuration already contains a revision of the resource. This is equivalent to copying a link to a revision into the configuration collection with the additional semantics given below. |
add(activity : Activity) | Add the latest revision of all resources modified by the given activity to
the configuration. All revisions in the activity must be checked in and immutable. An exception is raised if the configuration already contains any revision of a resource in modified by the activity. |
remove(revision : Revision) | Remove a member revision from a configuration. An exception is raised if the configuration does not contain the revision. This operation is equivalent to deleting a resource from the configuration collection. |
contains(revision : Revision) : boolean | Return true if this configuration contains the given resource. |
differencesWith(configuration : Configuration) : Activity[] | Return a list of differences in activities between this configuration and the given configuration. The differences in activities between configurations gives a high level view of the differences between the configurations. |
A workspace is a resource that provides a means to map URLs of versioned resources to particular revisions. A workspace contains a current activity which encapsulates changes made to resources in that workspace. A workspace also contains a revision selection rule that is used to select a revision of a versioned resource. The revision selection rule contains a number of entries that specify implicitly or explicitly a revision. Each entry is examined in order until the first matching entry is found. A matching entry is one that refers to an existing revision of a versioned resource.
When an activity is merged into the workspace, revisions of the same resource that were modified in different activities will conflict. The conflict report is defined by:
<!ELEMENT ConflictReport (ConflictEntry*)> <!ELEMENT ConflictEntry EMPTY> <!ATTLIST ConflictEntry source CDATA #REQUIRED target CDATA #REQUIRED >The revision selection rule for a workspace is defined by:
<!ELEMENT selectionrule (checkedout activity activity?(configuration | label | latest)*)> <!ELEMENT configuration (#PCDATA)> <!ELEMENT activity (label | latest)> <!ELEMENT label (#PCDATA)> <!ELEMENT checkedout EMPTY> <!ELEMENT latest EMPTY>Workspace |
|
getSelectionRule() : Element | Get the current revision selection rule. The rule is an XML element whose content contains the selection entries. |
setSelectionRule(element : Element) | Set the current revision selection rule. The element must be a DAV:selectionrule element. |
getCurrentActivity() : Activity | Get the current activity for this workspace. All checkouts are done in the context of the current activity. The workspace can only have one current activity at a time. |
setCurrentActivity(currentActivity : Activity) | Set the current activity for this workspace. |
createActivity(url : String) : Activity | Create an activity that represents a set of related changes to resources. |
Resource getResource(url : String) | Resolve a resource URL in the context of this workspace. |
mergeWith(mergeSource : Activity) | Merge the mergeSource activity with the current workspace. This results in
potentially selecting different revisions, and the creation of merge conflicts that must
be resolved. Until the conflicts are resolved, the revision returned is the revision that
would have been returned before the merge. This method returns a warning if the mergeSource includes mutable revisions. This is because the merge conflicts are not reliable. |
differencesWith(configuration : Configuration) : Activity[] | Return a list of differences in activities between this workspace and the given configuration. The differences in activities between a workspace and a configuration gives a high level view of the differences between the configurations. |
getMergeConflicts() : Document | Return an XML document containing the current merge conflicts in the workspace. If there are no merge conflicts, the merge activity is removed from the workspace. |
Method Resource.getRevisionHistory() returns an XML Document describing the complete version history of a versioned resource including all lines of descent, and all revision ids and labels. DASL or other searching techniques may be used to query the history for specific information, or DOM may be used by applications to access history details.
For example, consider a resource named http://hostname/webdav/versioning.htm (this document). Its revision history might look like:
The XML Document for this version graph can be created by doing a preorder traversal of the graph. Note that XML uses containment associations where the UML data model above uses a many-to-many association with an associated object. So a straight forward preorder traversal wouldn't look that good in XML and would require a lot of links. For the example graph above, a reasonable compromise might look like:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE versionhistory SYSTEM "versionhistory.dtd"> <D:revisionhistory xmlns:D="DAV:" href="http://hostname/webdav/versioning.htm"> <D:revision id="1"> <D:label>initialVersion</D:label> <D:label>root</D:label> <D:comment>This is the first version of the WebDAV versioning document</D:comment> </D:revision> <D:revision id="2"> <D:label>workingGroupUpdates</D:label> <D:comment>First updates, and complete specification for versioning</D:comment> <D:branch id="CM"> <D:comment>The CM branch adds configuration management to WebDAV versioning</D:comment> <D:revision id="CM1.1"> <D:comment>This is the first version for the CM branch</D:comment> </D:revision> <D:revision id="CM1.2"> <D:comment>This is the second version for the CM branch</D:comment> </D:revision> <D:revision id="CM1.3"> <D:label>webDAVCM</D:label> <D:comment>This is the final version for the CM branch before merging with the parent document</D:comment> </D:revision> </D:branch> <D:branch id="TCCM"> <D:comment>This branch adds configuration management to WebDAV versioning using the TeamConnection model</D:comment> <D:revision id="TCCM1.1"> <D:comment>This is the first version for the TCCM branch</D:comment> </D:revision> <D:revision id="TCCM1.1"> <D:label>webDAVTCCM</D:label> <D:comment>This is the final version for the TCCM branch before merging with the parent document</D:comment> </D:revision> </D:branch> </D:revision> <D:revision id="3"> <D:comment>This is the third version of the WebDAV versioning document</D:comment> </D:revision> <D:revision id="4"> <D:label>initialVersion</D:label> <D:label>root</D:label> <D:comment>This is the fourth version of the WebDAV versioning document</D:comment> </D:revision> <D:revision id="5"> <D:label>initialVersion</D:label> <D:label>root</D:label> <D:comment>This is the fifth version of the WebDAV versioning document</D:comment> </D:revision> <D:revision id="6"> <D:predecessor href="CM2.3"/> <D:label>CMVersion</D:label> <D:label>CM</D:label> <D:comment>This version includes configuration management</D:comment> </D:revision> </D:revisionhistory>
The revisionhistory element contains an implied branch off the null element containing the main line of descent.
The DTD for the version history document is:
<?xml version="1.0" encoding="UTF-8"?> <!-- WebDAV Version History DTD --> <!ELEMENT revisionhistory (revision*)> <!ATTLIST revisionhistory href CDATA #REQUIRED <!-- the URL for the versioned resource --> > <!ELEMENT revision (label*, comment?, branch*)> <!ATTLIST revision id ID #REQUIRED <!-- the revision id --> > <!ELEMENT branch (comment?, revision*)> <!ATTLIST branch id ID #REQUIRED <!-- the branch name --> > <!ELEMENT comment (#PCDATA)>
Versioning in the context of the world-wide web offers a variety of benefits:
These non-goals enumerate functionality which the working group has explicitly agreed to exclude from this document; they are documented here for explanatory purposes.
To be written. It is likely that implementing features to meet the goals described here will present few or no new security risks beyond those of base DAV. One possible exception is that it may become more difficult to hide the contents of a resource when there may exist other versions with different access control lists.
[WEBDAV-VERSION-GOALS] J. Stracke, J. Amsden, "Goals for Web Versioning",
Internet-Draft, draft-ietf-webdav-versionreqs-00.html,
Jan., 1999.
[WEBDAV]Y.Y. Goland, E.J. Whitehead, Jr., A. Faizi, S.R. Carter, D. Jensen,
"Extensions for Distributed Authoring on the World Wide Web -- WEBDAV",
Internet-Draft draft-ietf-webdav-protocol-10.
Nov., 1998
[WEBDAV-GOALS] J. Slein, F. Vitali, J. Whitehead, D.
Durand, "Requirements for a Distributed Authoring and Versioning Protocol for the
World Wide Web", RFC-2291.
February 1998.
[WEBDAV-ACP] J. Slein, J. Davis, A. Babich, J. Whitehead,
"WebDAV Advanced Collections Protocol", Internet-Draft draft-ietf-webdav-collection-protocol-02.txt.
Nov., 1998.
[DASL] S. Reddy, D. Jensen, S. Reddy, R. Henderson, J. Davis, A.
Babich, "DAV Searching & Locating", Internet-Draft draft-reddy-dasl-protocol-04.txt.
Nov., 1998.
[CVS] http://www.cyclic.com/cyclic-pages/books.html
[BONSAI] Mozilla.org, http://www.mozilla.org/bonsai.html