Project: stp

Package com.ibm.rational.wvcm.stp

Extensions to the generic interfaces and infrastructure of the Workspace Versioning and Configuration Management (WVCM) API used in all domains.

See:
          Description

Interface Summary
StpAccessControlEntry The interface for an entry in a resource's access control list.
StpAccessControlledResource The interface implemented by resources that support access control lists
StpActivity StpActivity is an interface for a proxy which may represent one of these three cases: A UCM-enabled CQ record not bound to a UCM activity, or A UCM activity not bound to a CQ record, or A UCM-enabled CQ record-UCM activity pair (bound together) It serves two purposes: It provides access to properties which are common to all of the above three cases It provides a means to access the CcActivity and/or CqRecord proxies for the persistent UCM activity or CQ record resources involved in the above three cases Although this interface extends StpResource, it is an abstraction.
StpErrorMessageException.ErrorMessageData The interface for the data implementation object for this type of exception
StpException.Data The specification for the data implementation object associated with this exception.
StpLocation An extension of the javax.wvcm Location interface that provides a programmatic representation for the location of a resource.
StpLocation.ExtendedNamespace An object containing additional information associated with certain Namespace enumerators.
StpPartialResultsException.PartialResultsData The interface for the data implementation object for this type of exception
StpPrincipal A mixin indicating that a resource can act as an access control principal
StpProperty<T> A property is a named collection of metadata associated with a resource.
StpPropertyException.PropertyData The interface specification for the implementation data object associated with this exception
StpProvider StpProvider is an extension to the WVCM Provider interface.
StpProvider.NotifyAuthenticatedOption If the Callback object provided to an StpProvider implements this interface, the callback will be notified when an Authentication object returned by the Callback's getAuthentication() method is successfully verified to be valid.
StpProvider.NotifyBusyOption If the Callback object provided to an StpProvider implements this interface, the callback will be notified when the server reports that it is too busy to respond to a request.
StpProvider.StpCallback An extended version of javax.wvcm.ProviderFactory.Callback whose getAuthentication method provides additional information to the client when being asked for credentials.
StpProvider.StpProductInfo Version information about the code that implements a portion of this product.
StpReleasable A interface for objects that hold resources that can (and in some cases really should) be released prior to garbage collection.
StpRepository A client proxy for a repository resource.
StpResource A proxy for a resource persisted in a repository or in a file area.
 

Class Summary
StpProperty.List<S extends StpProperty> A List of Properties.
StpProperty.MetaPropertyName<V> An object representing the name of a meta-property.
 

Enum Summary
StpAccessControlEntry.AccessRight An enumeration of the possible access rights that can be applied to a controlled resource.
StpAccessControlEntry.EntryType An enumeration of the type of permission being reported
StpActivity.CqUcmIntegrationState  
StpException.StpReasonCode An encoding of exception conditions specific to this API.
StpLocation.Namespace This class enumerates the namespaces that may appear in a location specification.
StpProperty.Type An enumeration of the possible property types.
StpProvider.Domain The type of a subprovider.
 

Exception Summary
StpErrorMessageException An StpException used to pass an error message string generated by the domain application through the CM API without further adornment.
StpException An extension of javax.wvcm.WvcmException used throughout this API.
StpPartialResultsException An exception used to convey information about an operation that failed on some, but not necessarily all, resources processed by the operation.
StpPropertyException The base exception class for errors associated with the reading or writing of resource properties and meta-properties.
StpReleasable.ReleaseException A distinguished unchecked exception for use by implementations of Releasable.
 

Annotation Types Summary
StpResource.UnsupportedProperty An annotation used on property getters or setters of a proxy interface to indicate that a property defined in a super interface is not supported by that proxy.
 

Package com.ibm.rational.wvcm.stp Description

Extensions to the generic interfaces and infrastructure of the Workspace Versioning and Configuration Management (WVCM) API used in all domains.

The following classes and interfaces represent the significant extensions to WVCM defined by this API.

Topics

Provider

To access services through this API, the client invokes javax.wvcm.ProviderFactory.createProvider to instantiate one of the provider classes named in the StpProvider, CqProvider, or CcProvider interfaces.

In this release one StpProvider class is available, PROVIDER_CLASS, which provides access to both ClearQuest databases and ClearCase CM Servers through the properly installed and licensed IBM Rational products for these resource repositories. Note that this provider does not implement the CqProvider or CcProvider interfaces, but it does contain links to component objects that do.

Two CcProvider classes are available: NETWORK_PROVIDER_CLASS which provides access to web views hosted on ClearCase CCRC WAN servers, and LOCAL_PROVIDER_CLASS which provides access to dynamic views hosted on the local ClearCase machine.

One CqProvider class is available, CQ_ONLY_PROVIDER_CLASS, which provides access only to ClearQuest databases via an instance of IBM Rational ClearQuest installed on the same machine.

At the time of instantiation, the client provides a Callback object, which will be invoked each time the API needs to authenticate access to a repository addressed by the client. The user credentials are used as needed to verify that the user on whose behalf the client is performing operations and accessing data has the permissions necessary to carry out those tasks. Having sufficient permissions to perform an operation is always a precondition for that operation and the operation will fail by the mechanisms described in the error handling section if the user does not have the required permissions.

StpProvider.StpCallback extends the WVCM Callback interface to provide more information to the callback when it is called. CcProvider.CcAuthentication extends the standard ProviderFactory.Callback.Authentication object so that the client may provide ClearCase user group information during the login process.

Each Provider instance maintains a mapping from each authentication realm it encounters to the user credentials for that realm obtained from the Callback. The API implementation takes care of authorizing the credentials as it moves from realm to realm on the server, requesting new credentials the first time each new realm is encountered.

The client may pre-populate this realm authentication map with credentials to avoid the need to process callbacks. See StpProvider.setAuthentication(com.ibm.rational.wvcm.stp.StpProvider.Domain, java.lang.String, javax.wvcm.ProviderFactory.Callback.Authentication, boolean) for details.

For more information see the StpProvider class documentation.

Location and StpLocation Objects

Each resource has a location, which is fundamentally a string that uniquely identifies the resource to the server at a given point in time. Locations are composed of name segments as in a typical file path name and thus impart a hierarchical structure to the namespace for resources on the server.

A new resource is always created by providing to a type-specific creation method a location for the parent of the resource in this naming hierarchy and a proposed simple name for the resource, itself. The creation method may alter the proposed simple name to suit its purposes, but the parent location of the created resource will always reference the parent resource provided to the creation method.

The location of a resource on the server or in a file area is represented by an StpLocation object in this API. Locations can also be specified as a String whose content obeys a specific syntax. This syntax is an extension of the ClearCase syntax for pnames and object selectors. The StpProvider interface defines methods for parsing such string specifications into StpLocation objects and the StpLocation interface defines methods for examining the constituent parts of the parsed specification, namely domain, namespace, name, and repository. Using an StpLocation instance, API clients can examine location specifications provided by the end user to determine if they are appropriate for the context in which they are being used. Based on this analysis, using a StpLocation object, a client could fill in parts of the specification elided by the end-user if the context defined those missing parts unambiguously.

The StpLocation.forClass(Class) method facilitates this process by attempting to fill in missing location fields based on provider-defined defaults and the given Class, which identifies which interface will be used to access the resource at the given location. (see StpProvider.setDefaultRepository(com.ibm.rational.wvcm.stp.StpRepository), et. al.}

A Location object represents a syntactically correct resource address and, as such, can be used to construct a proxy (using one of the proxy factory methods of Provider or one of its extentions). As a general rule, the proxy constructed using a given Location must be for the same type of resource as the actual resource addressed by the Location. However, the type of resource addressed by a Location cannot always be determined from the address specification alone, so this rule cannot always be enforced at the time the proxy is constructed.

All resources have an immutable, but often ineffable, form of location that may be safely used to store resource identities on the client between client sessions. This immutable location might not be the location used to create the resource, however. The server creates this immutable location for the user at resource creation time and is always available as the unchanging StpResource.STABLE_LOCATION property of the resource.

Many resources also have a more effable location that is suitable for display to users. This is the value of the StpResource.USER_FRIENDLY_LOCATION. Segments of the USER_FRIENDLY_LOCATION may often be renamable by users and USER_FRIENDLY_LOCATION values are not good candidates for persistent, client-side representations.

Clients must not assume that the location used in constructing the proxy returned by a server is in a specific form. Usually, the server will provide a location that is most efficient for getting back to that resource on the server. If a client needs a location of a specific form it must request the property that defines that form of address from the resource.

Resources

A resource is a named collection of properties that exists in a repository or in a client-side file area. Some resources can exist only in a repository. Some exist solely in a file area. Yet others may exist both in a repository and in a file area. An API provider may be used to create, modify, and ultimately destroy resources. After a resource is created, and until it is destroyed, it persists in its repository or in its file area between invocations of the API provider that modify it.

Resources are represented by proxy objects in the client library. A client cannot access a resource without having a proxy object for it. All proxy objects are obtained either by invoking a method on the provider or invoking a method on another proxy object. They cannot be constructed directly by the client.

Proxies are not designed to be long-lived caches of information about a resource. Their purpose is primarily to marshal the data needed to perform a resource operation prior to initiating it and to provide a container for returning the results of such an operation.

Proxies are simple, static data structures not designed to be thread safe. Clients with multiple threads must implement needed synchronization in client-specific code.

The resource proxy interfaces form a class hierarchy rooted in javax.wvcm.Resource. This is a rather rich hierarchy and is best viewed in this Javadoc document, the Eclipse Type Heirarchy View, or similar source browser. Note that, as a general rule, when the API implements/extends a WVCM interface, the simple name of the API class/interface ends in the simple name of the WVCM interface that it implements/extends and begins with the two- or three-letter name of the package in which it is defined. Where there is a difference between WVCM terminology and the traditional ClearCase terminology, the interfaces in the ClearCase domain use the traditional ClearCase terminology.

To access a resource given its location, the client passes the location to a Provider proxy factory method and, in return, obtains a proxy object for that resource. Methods on the proxy allow the client to create or delete a resource at the location indicated by the proxy, read property values from the resource at that location, write properties to the resource at that location, or perform any number of other operations on the resource as specified in the interface for the proxy.

If the client does not have the location for a resource, it must browse the resource hierarchy for it, perhaps with the interactive help of the user. Non-versioned resources are found primarily in domain-specific repositories and versioned resources are found in Workspaces. So, if the client wants to work on non-versioned objects, it begins its browsing by obtaining from the provider instance a list of proxies for the repositories of the type desired. (For versioned objects, it begins its browsing in a list of workspace folders.) The proxies in this list represent locations where repositories (or workspaces) may be found or constructed.

If the client already has one resource and wishes to create or locate another resource that is or will be related to it, the client can obtain from the resource in hand a list of folders where related resources of a given type can be found or created.

Using doReadMemberList on the folder proxies in the returned list, the client can obtain a list of proxies for the members of that folder. By repeated application of this method, the client can form a hierarchical list of all the repositories visible to the user. From this hierarchy, the user can select an appropriate repository for the task at hand or select a folder in which to create a new repository (if permitted by the domain).

Generally speaking, a new resource is constructed in the following steps…

The final deliver step is needed to make the new resource accessible to other users of the system. It is also the main trigger for business logic running on the server. For increased efficiency, variants of the create-resource operation exist that allow the delivery to be made in the same server interaction as the create.

Properties and Meta-Properties

Resources have properties. Each property has a name, a type, and a value, and may have other meta-properties associated with it (such as access rights or ownership). The value of a property is of a specific type, such as integer, string, date, time, or reference-to-resource. The property type depends on the property name and the resource class. Some properties are defined by WVCM, others are defined by this API as extensions to WVCM, and some may also be defined by the server or the API client.

In this API, these meta-properties are identified by a MetaPropertyName object. The MetaPropertyName may be used to access the corresponding meta-property once the meta-property has been read from the server.

The possible types of a property value are enumerated by the API. There is no mechanism for passing values of a type not in this enumeration. Clients must encode values in one of the supported types—such as string—if they need to pass values of a type not in the pre-defined enumeration.

The PROPERTY_NAME and VALUE meta-properties of a property are distinguished meta-properties. The PROPERTY_NAME value is used to request and access the property and any of its meta-properties. The VALUE is the meta-property requested if only the property-name is used in the request.

A set of property names is defined for each type of resource defined by the API. These property names are used to request properties from the server and to access the properties once they have been obtained from the server. For some types of resources—those supporting the CqRecord interface—the server may define additional properties. The API allows the client to obtain property names for these additional properties from a corresponding CqRecordType resource and use them to request the properties in the usual manner.

WVCM allows clients to define their own property names and use them to maintain arbitrary property data on the server. This release of the client library allows this in only limited contexts.

Reading Properties

To read properties from a resource on the server, the client assembles a list of property names that identify the properties to be read and passes the list to the proxy’s Resource.doReadProperties method. This method passes the resource location specified by the proxy and the list of desired properties to the server. The response from the server is assembled into a new proxy populated with the requested properties and this proxy is passed back to the client for examination.

Once a proxy is populated with properties, the value of these properties can be extracted from the proxy using either the property name (via Resource.getProperty) or by using one of the access methods defined on each proxy for the API-defined property names.

The PropertyNameList designating the properties wanted from the server can be augmented with MetaPropertyName elements, which allow the client to request specific meta-properties of a property (instead of, or in addition to its VALUE meta-property).

For those properties whose value is a reference to another resource, a NestedPropertyName element can be added to the wanted properties list, which requests specific properties of the referenced resource. Such indirect property requests may be nested arbitrarily deep. On the client, the value of such a property is a proxy for the referenced resource and that proxy contains the properties requested in the nested property request.

Similarly, for those properties whose value is a reference to another property, a NestedPropertyName element with a MetaPropertyName root can be added to the wanted properties list, which requests specific meta-properties of the referenced property, including its value. Such indirect meta-property requests may be nested arbitrarily deep and can commingle with nested property requests. The value of a property-valued property is a StpProperty object, which contains a collection of the requested meta-properties.

Thus a single request to read properties from the server may return a rich and deep hierarchy of proxies, properties, and meta-properties. For example, here is the declaration for RECORD_PROPS, a PropertyNameList that requests selected information about a targeted record and all of its fields. The CqRecord.ALL_FIELD_VALUES property is a list of all the fields of the record expressed as a list of Property objects. Hence, the VALUE meta-property is a list of references to other field properties of the record and through it, we can indirectly request meta-properties of those fields.

    static final PropertyRequest RECORD_PROPS =
        new PropertyPropertyRequest(new PropertyRequestItem[]{
            CqRecord.USER_FRIENDLY_LOCATION,
            CqRecord.ALL_FIELD_VALUES.nest(new PropertyRequestItem[]{
                    StpProperty.VALUE.nest(FIELD_META_PROPERTIES)})
        });
A ClearQuest record field's name, type, requiredness, and value are each defined as a meta-property of the field property. These are enumerated in the FIELD_META_PROPERTIES PropertyNameList below and used in the nest() method call above to request this information for display.
    /** The field meta-properties to be requested and displayed */
    static final MetaPropertyName[] fieldMetaProperties = 
            new MetaPropertyName[]{
                CqFieldValue.NAME, 
                CqFieldValue.REQUIREDNESS, 
                CqFieldValue.TYPE,
                CqFieldValue.VALUE.nest(VALUE_PROPERTIES)};
    static final PropertyRequest FIELD_META_PROPERTIES = 
        new PropertyRequest(fieldMetaProperties);
For field values that reference other database resources, additional information is needed to build a useful display. So, for the VALUE meta-property of a field we use a NestedPropertyName to request additional properties of the resource referenced by the value. For most references, the USER_FRIENDLY_LOCATION will provide a useful human-readable name for the resource. For an attachment field, the value is a reference to a folder. That folder resource has an ATTACHMENT_LIST property that contains a list of the attachment resources associated with that field. From each of those resources we want additional information about the attached file so we list them in a NestedPropertyName within the VALUE_PROPERTIES list.
    /** Additional information desired for attachments */
    static final PropertyNameList VALUE_PROPERTIES =
        new PropertyNameList(new PropertyName[]{
            CqResource.USER_FRIENDLY_LOCATION,
            CqAttachmentFolder.ATTACHMENT_LIST.nest(new PropertyName[]{
                CqAttachment.DISPLAY_NAME,
                CqAttachment.FILE_NAME,
                CqAttachment.FILE_SIZE,
                CqAttachment.DESCRIPTION})});
Unless the value of a field is a reference to a resource, the request for properties of the referenced value is meaningless and, hence, the request is simply ignored. If a field is a reference to another record resource, that resource will not define an ATTACHMENT_LIST property and the request for it will result in an error response from the server. This error is not fatal and, in fact, will not be raised unless we attempt to access the ATTACHMENT_LIST property from one of the Record resource proxies returned from this request. We can easily avoid this by looking at the type of each field before we attempt to process its value in any way.

Once these wanted properties lists are properly constructed, they can be passed to the doReadProperties() method of a CqRecord proxy that addresses the record resource to be displayed. When that request returns, the requested data can be extracted and displayed as illustrated here

    ...
        record = (CqRecord)record.doReadProperties(RECORD_PROPS);
        
    final StpProperty.List fields = record.getAllFieldValues();
    TableModel dataModel = new AbstractTableModel() {
        public int getColumnCount() { return fieldMetaProperties.length; }
        public int getRowCount() { return fields.size();}
        public Object getValueAt(int row, int col) 
            { 
                try {
                    Object val = ((StpProperty)fields.get(row))
                        .getMetaProperty(fieldMetaProperties[col]);
                    
                    if (val instanceof CqRecord)
                        return ((CqRecord)val).getUserFriendlyLocation();
                    else if (val instanceof CqAttachmentFolder)
                        return ((CqAttachmentFolder)val).getAttachmentList().size()
                            + " attachments";
                    else
                        return val;
                } catch(Throwable ex) {
                    return "!&*$#";
                }
            }
        public String getColumnName(int col)
            { return fieldMetaProperties[col].getName(); }
    };
    ...
Which produces output similar to this

Figure 1

All methods that contact the server accept a Feedback argument, which allows the client to provide a list of wanted properties for the targeted resources and for any resources indirectly modified by the operation invoked by the method. The client may also request in one call the properties of an arbitrary number of disparate resources. Using these mechanisms, the client may often be able to complete one task and set up for the next using only one or two round-trips to the server.

Writing Properties

Many resource properties are writable, or, said more pedantically, the value meta-property of many properties is writable. Other meta-properties of a property are not directly writable, but their value may be changed as a side-effect of changing a property value or performing some other operation on the resource.

To change a writable property value, the client constructs a proxy for the resource and then sets the new property value into that proxy using either the generic Resource.setProperty method or one of the property-specific setXXX methods. When that proxy is next used to interact with the server, the modified property value will be written to the server. Resource.doWriteProperties does nothing but write the modified property values from a proxy to the server, but the modified property values will also be written by any other operation that interacts with the server.

Common Properties

From any resource, a client may obtain the following information …

See javax.wvcm.Resource and ...stp.Resource for a complete list of properties and methods supported by all resources.

All of these properties, except for the resource’s location, must be explicitly requested from the server before they are available from a proxy.

Error Handling

All problems are reported via an StpException object. StpException is an extension of WvcmException and is the root of all checked exceptions thrown by this API. All implementations of WVCM-defined methods are documented to throw WvcmException. All public methods of this API that are extensions to WVCM are also documented to throw WvcmException. However, the implementations of all these methods consistently throw only StpExceptions – not WvcmExceptions.

So, the convention is

  1. "throws StpException" is never be used in any method declaration (public or otherwise). If a method throws an StpException it is declared as if it throws a WvcmException.
  2. A method never throws a new WvcmException. Even though the exception could be expressed as a WvcmException, it is always thrown as a new StpException() instead.

From an StpException, the client may obtain the following information …

Each operation defines a set of preconditions that must be met for the operation to succeed: a resource must exist to read its properties, a resource must not already exist with the same name for one to be created, a resource must be versioned and checked-in to be checked-out, etc. Violations of such preconditions cause the operation to throw an exception.

Operations can often be applied to a collection of resources. If the operation fails on any one of them, a StpPartialResultsException is thrown (with the successes reported in the list returned by StpPartialResultsException.resourceList()).

Generally speaking, problems encountered by the server while reading or writing the properties or meta-properties of a resource do not cause the API operation to actually throw the implied exception. Instead, the exception is associated with the property within the returned proxy. Only when the client attempts to extract that specific property value from the proxy will the exception be thrown. The client may also interrogate the proxy prior to extracting the property value to determine if there were problems and obtain the exception without it being thrown.

Properties, names, and access methods

Proxies contain the property values recently read from the resource and/or values that are about to be written to the resource. The name of a property is represented in the API by a PropertyNameList.PropertyName object. All of the PropertyName objects defined by the API are public constant objects and so are named by an uppercase identifier in which words are separated by underscores. Each PropertyName object is defined by the most general subclass of Resource where the property is available. For example, since all resources have the user-friendly-location property, the PropertyName for the user-friendly-location property is defined in StpResource as USER_FRIENDLY_LOCATION. Other examples are ControllableResource.CHECKED_IN, and Configuration.ROOT_FOLDER.

The Resource class provides generic methods for accessing the property values defined by a proxy using the property's PropertyName object. WVCM defines Resource.getProperty and Resource.setProperty. The getProperty method throws the exception StpPropertyException if the proxy doesn't contain a valid value for the property identified by the given PropertyName object. The StpReasonCode for this exception is PROPERTY_NOT_REQUESTED if the proxy contains no entry for the property (because it was not requested when the proxy was created or never set after the proxy was created). It will be PROPERTY_RETRIEVAL_FAILED if the property was requested but the server was unable to produce a value for it. In this latter case, the nested exception or cause of the thrown exception will be the exception reported by the server. The server-generated exception has one of the following reason codes to further explain the nature of the problem.

PROPERTY_NOT_DEFINED_FOR_RESOURCE
A permanent condition. The property is not defined for the type of resource found at the location referenced by the proxy. The PropertyName used is not defined by the API nor is it defined by the repository schema as a property that should be found on resources of the type referenced.
PROPERTY_NOT_SUPPORTED_BY_SERVER
A permanent condition. Even though the API specification or repository schema says the property is valid for the type of resource referenced by the proxy, the server does not support it. For properties the server intends to support in the a future release, the exception message will say “NOT YET IMPLEMENTED”.
PROPERTY_NOT_CURRENTLY_AVAILABLE
A transient condition. A potentially recoverable condition prevented the server from retrieving the property on the lastest request.
PROPERTY_NOT_AVAILABLE_LOCALLY
A permanent condition. The property value is maintained only on the server and so is not available locally.
The stack trace from this nested or causal exception will indicate the context in which the property value was requested from the server.

As an extension of WVCM, this API defines StpResource.lookupProperty, which never throws an exception. If the property value is defined, lookupProperty returns the same Object as getProperty. If the property value is undefined, lookupProperty returns the exception that would have been thrown by getProperty.

In addition to the generic access methods mentioned above, typed access methods are defined for each PropertyName defined by this API. These typed access methods are defined in the same class where the corresponding PropertyName object is defined. The name of the typed access method is derived from the name of the PropertyName object by prefixing the identifier for the PropertyName with "get" and changing the format to camel notation. Thus, for the USER_FRIENDLY_LOCATION property, the class Resource defines StpResource.getUserFriendlyLocation(). Similarly, this API defines ControllableResource.getCheckedOut() and Configuration.getRootFolder().

Similarly, for those properties that are settable by a client, the proxy class in which the PropertyName object is defined also defines a "set" method, following a naming convention analogous to that used for the property access methods. Thus, the Configuration interface does not define setRootFolder because it is not a setable property and ControllableResource defines setPredecessorList but not setDirtyPropertyList. These property set methods are often referred to as setters.

By the way, in a Proxy class, only the property access methods begin with "get." And only the property setter methods begin with "set". In a non-proxy class, the normal Java conventions are followed, in which field getters and setters are prefixed with "get" and "set", respectively. In a proxy class, non-property field setters and getters use camel case without a "get" or "set" prefix.

Generally speaking, for a property FOO of type Bar, the access method getFoo is equivalent to (Bar)getProperty(FOO). In particular, these access methods will throw an exception if the proxy does not define a value for the property with which the access method is associated. Also, setFoo(Bar val) is generally implemented as setProperty(FOO, val).

Also note that neither setProperty, getProperty, nor lookupProperty, attempt to verify that the given PropertyName is defined by the proxy class in hand. Instances of class Resource can be used to interact with any type of resource. Such interactions will fail only when they attempt to read or write values for properties that are not defined for the resource addressed by the proxy and the failures will occur only when the API Provider attempts to transfer such property values to or from the resource.

In addition to property values, property metadata can also be requested from the server and stored in a proxy. See the StpProperty class for more information.

Contacting the domain server

The proxy methods that begin with the prefix "do" (and only such methods) cause the API provider to interact with the repository to perform various operations on the resource addressed by the proxy's Location attribute. If the proxy addresses a file area resource, a server will be contacted only if the operation cannot be completed by interacting with the file area.

One should infer from this do-rule that property accessors and setters do not interact with the resource to get or set property values. The setters simply store their argument values in the proxy and the access methods only fetch property values already stored in the proxy. Values are actually read from a resource using a do-method such as Resource.doReadProperties. Actually, many do-methods take an optional ProperyNameList parameter in which the client can request which properties are to be read from the resource as part of executing that method. Furthermore, as a normal part of their interaction with the server, all do-methods write to the actual resource any property values that have been set into to the proxy since the last server interaction.

The names of the properties that are currently stored in a given proxy are returned by Resource.propertyNameList().

The names of the properties whose values have been set in the proxy but not yet written to the resource are returned by Resource.updatedPropertyNameList().

Finally, Resource.doGetPropertyNameList will contact the server and return the property names defined by the server for the given resource.

Returning resources and collections

The value of many properties is a reference to another resource. Several API methods also return references to resources. Such values are represented by proxies constructed by the API provider. At a minimum, such proxies have a valid Location attribute. Additional properties may be defined by the proxy depending on the method called and the parameters passed.

All API methods that return a proxy accept as an input parameter a Feedback object. Through such objects, the API client passes the names of properties whose values should be obtained from the resource while the method interacts with the server. The property values obtained by the method are stored in the proxy it returns (not in the proxy from which it was invoked).

If the value of a property is a reference to a resource, the PropertyRequest may contain a NestedPropertyName object in place of the PropertyName object for the desired property. In addition to specifying the name of the property, a NestedPropertyName also includes its own PropertyRequest. This nested PropertyRequest specifies the properties of the resource referenced by the property of the original resource whose values are to be obtained from the referenced resource.

The PropertyRequest nested within a NestedPropertyName may, itself, contain additional NestedPropertyName objects. So, in one interaction with the server, it is possible to read an arbitrary number of related resources and their properties.

As an example, examine the getCheckouts method shown in Example 1. In a single call to doReadProperties, this method fetches the WORKSPACE_CHECKOUT_LIST property of a Workspace or the ACTIVITY_CHECKOUT_LIST property of an Activity from the server and returns a list of ControllableResource proxies for the corresponding checked-out resources. Each ControllableResource proxy defines a number of properties including the CHECKED_OUT property and the ACTIVITY_LIST property. The value of the CHECKED_OUT property is a Version proxy whose VERSION_NAME property is defined. The value of the ACTIVITY_LIST property is a list of Activity proxies, each of which defines the USER_FRIENDLY_LOCATION property of the Activity.

    /**
     * Retrieve a list of the ControllableResources that are checked out
     * in a given Workspace or under a given Activity. In the returned 
     * proxies, include properties suitable for characterizing the state of 
     * the checked-out resources.
     * /
    public ResourceList
    getCheckouts(Resource res)
    {
        PropertyName checkoutProp;
        
        if (res instanceof Workspace) {
            checkoutProp = Workspace.WORKSPACE_CHECKOUT_LIST;
        } else if (res instanceof Activity) {
            checkoutProp = Activity.ACTIVITY_CHECKOUT_LIST;
        } else {
            throw new IllegalArgumentException(
                "Input must specify a workspace or an activity");
        }

        PropertyNameList wantedProps =
            new PropertyNameList(new PropertyName[] {
                checkoutProp.nest(RESOURCE_PROPERTIES)});

        res = (Resource)res.doReadProperties(wantedProps);
        
        return (ResourceList)res.getProperty(checkoutProp);
    }

    /** Properties to retrieve from the Activity of a checked-out resource * /
    private static final PropertyNameList ACTIVITY_PROPERTIES =
        new PropertyNameList(new PropertyName[] {
            Activity.USER_FRIENDLY_LOCATION});
    
    /** Properties to retrieve from a Version of a checked-out resource * /
    private static final PropertyNameList VERSION_PROPERTIES =
        new PropertyNameList(new PropertyName[] {
            Version.VERSION_NAME});

    /** Properties to retrieve from each checked out item * /
    private static final PropertyNameList RESOURCE_PROPERTIES =
        new PropertyNameList(
            new PropertyName[] {
                Resource.DISPLAY_NAME,
                ControllableResource.WORKSPACE_RELATIVE_PATH,
                ControllableResource.USER_FRIENDLY_LOCATION,
                ControllableResource.LAST_MODIFIED,
                ControllableResource.CONTENT_LENGTH,
                ControllableResource.COMMENT,
                ControllableResource.CHECKED_OUT.nest(VERSION_PROPERTIES),
                Version.ACTIVITY_LIST.nest(ACTIVITY_PROPERTIES)});

Example 1

Like the Workspace.WORKSPACE_CHECKOUT_LIST and Activity.ACTIVITY_CHECKOUT_LIST properties, the value of many properties is a list of references to resources. The value of such properties is represented by a ResourceList object, which is nothing more than a Collection of proxy objects with a number of additional methods for performing specific operations on the members of the list.

As illustrated in Example 1, ResourceList-valued properties can use NestedPropertyNames to request properties from the resources in the list.

Several API methods also return collections of resources. The resource collections may be returned as a ResourceList or as a ResourceList.ResponseIterator. The ResponseIterator represents a stream of proxy information coming more or less directly from the server one proxy at a time as the client progresses through the items of the ResponseIterator. Until it is explicitly released (via ResourceList.ResponseIterator.release()) or its end is reached, the ResponseIterator holds open a communication channel with the server. Since the communication channel is a scarce system resource, clients should examine the items in the iterator as quickly as possible and release the iterator as soon as it is no longer needed.

Proxies and threading

Resource proxies are not guaranteed to be thread-safe, except where otherwise noted. That is, if you wish to share a Resource proxy among multiple threads, and expect predictable behavior from property access and modification methods, then you will have to provide your own access synchronization. Consult the member documentation for more information.

Domains

Each of the separate application domains supported by this API is represented by its own unique
StpProvider.Domain. Each domain is represented by a separate package in this API. Each package defines proxy classes for the domain-specific resources of the domain as well as an extension of the Provider interface that provides the object factories for these domain-specific proxies.

The class named by StpProvider.GENERIC_PROVIDER_CLASS implements the StpProvider interface and once it is instantiated an object that implements one of the domain-specific Provider interfaces can be obtains using the appropriately-named method. Here, for example, is a simple application that creates a ClearCase activity from command line arguments.

...
import com.ibm.rational.wvcm.stp.cc.CcLocation;
import com.ibm.rational.wvcm.stp.cc.CcProvider;

...
public static void main(String[] args) throws Exception {
    String name = args[0];
    String headline = args[1];
    String stream = args[2];
    // Switch to a com.ibm.rational.wvcm.stp.cc.CcProvider to access the
    // ccActivity() and ccStream methods() needed to build proxies.
    CcProvider provider = Sample1.getProvider().ccProvider();
    Location location = provider.stpLocation(name);
    CcActivity activity = provider.ccActivity(location);
    
    activity.setHeadline(headline);
    activity.setStream(provider.ccStream(provider.stpLocation(stream)));
    activity.doCreateResource();
}

On the other hand, to successfully access a repository of a given type, the product that defines that repositiory must be properly installed and licensed on the client platform. Rather than generate an arbitrary diagnostic when this occurs in the middle of execution, a client may wish to test for proper installation immediately after instantiating a provider, using a test such as this:

Object msg = provider.getInstantiationErrors().get(Domain.CLEAR_CASE);

if (msg != null)
    System.err.println("ClearCase unavailable: " +  msg);

Also note that this particular example does not require such strict typing to implement. Since activity creation is a basic WVCM operation, it can be coded primarily against the Stp interfaces, dipping into the ClearCase package only for the ClearCase-specific properties that need to be set. It still requires that ClearCase is properly installed, however. Thus, we could write...

StpProvider provider = Sample1.getProvider();
Object msg = provider.getInstantiationErrors().get(Domain.CLEAR_CASE);

if (msg != null)
    System.err.println("ClearCase unavailable: " +  msg);

Location location = provider.stpLocation(name);
Activity activity = provider.activity(location);

activity.setProperty(CcActivity.HEADLINE, headline);
activity.setProperty(CcActivity.STREAM,
                                 provider.resource(provider.stpLocation(stream)));
activity.doCreateResource();

Packaging Overview

WVCM

The package javax.wvcm defines the following WVCM resource/proxy interfaces. Additionally, these supporting interfaces and classes are defined.

Stp

The Software Team Package com.ibm.rational.wvcm.stp (Stp) defines the following resource/proxy interfaces as extensions to the WVCM model and as foundation for the domain-specific proxies. Additionally, these supporting interfaces and classes are defined.

Clear Case

The package com.ibm.rational.wvcm.stp.cc defines interfaces for accessing ClearCase repositories based on the WVCM model. It defines the following resource/proxy interfaces. Additionally, these interfaces and classes are defined.

Clear Quest

The package com.ibm.rational.wvcm.stp.cq defines interfaces for accessing ClearQuest databases. It defines the following resource/proxy interfaces. Additionally, these interfaces are defined.


Generated Tue 29-Aug-2017 12:28 PM

Copyright © IBM 2017. All rights reserved.