Skip navigation links
SAP NetWeaver 7.50 SP 13 KMC

Package com.sapportals.wcm.repository.variants

This package contains the API for Variant-Resources.

See: Description

Package com.sapportals.wcm.repository.variants Description

This package contains the API for Variant-Resources.


API for Variant-Resources

TOC

Introduction

The API defined in this package enables applications to handle variant resources via specialized resource types/interfaces. A variant resource is a type of resource whose content and properties can vary depending on the resource context. The content and properties are not arbitrary but a defined set of "variants" of a resource exist. For example, a document content can be available in different languages.

Each variant is tagged with a property for each dimension for which the resources can vary. The property values are used to uniquely identify each variant. For example, each document may be available in two languages and two formats, so each variant will have two properties named "language" and "format" with two possible values each: [english, german] and [html, pdf]. The allowed dimensions - that means the property names, types and possible values - are managed by the repository.

When an application is looking up a resource the repository will select one of the available variants. This is done by matching the set of properties (names and values) provided by the application via the resource context against the properties identifying the variants. How these properties are put together is completely application-specific - but usually they are associated with a portal user (e.g. "preferred language").

Using the API in this package variants are available for plain resources, collections and links. With collections and links only the properties may vary (not the collections' children or the links' target). Variant resources may also be versioned: Each variant has its own version history.

Terms and Definitions

Logical Resource (LR)

A LR is related to one ore more physical resources. An instance of a LR provides access to the content and properties of one if its physical resources. The "visible" PR is selected by the context resolution algorithm which has to be done by the repository whenever a resource instance is created.

LR-RID

The RID of a LR.

Physical Resource (PR)

A PR instance provides access to one of the possible variants of a LR. All changes to content and properties of a variant resource are persistet at a PR. PRs can be versioned.

PR-RID:

The RID of a PR. The "parent" of the RID and the LR-RID might be different. In general, the PR-RID is constructed internally by the repository and therefore no assumptions must be made how it might be "calculated" from the LR-RID - or vice versa.

Context Properties

The properties which are used by the repository to select the "visible" PR. A context property is defined by its name, type and possible values. Each variant-enabled repository has a fixed set of available context properties.

Context properties are persistet at PRs. For each LR all PRs must have a unique set of context property values. A repository may allow incomplete sets of context properties to be persisted for PRs - this can make sense e.g. if the repository provides a feature to add context property definitions to an already existing repsitory instance.

Variant Context (VC)

Contains values for the context-properties of all variant-enabled repositories in the system. The variant-context is attached to the resource-context. A variant-enabled repository must be able to use a default value (internally for context resolution) for each property in case it is missing in the VC.

Context Resolution

The algorithm by which a repository selects a single PR to be "visible" for a given VC. The input consists of: The LR, all PRs and the variant context. The algorithm itself is repository-specific, that means the repository might take additional input parameters into account. The result is one of the PRs. The result may be null if no PR is visible, which means that the LR is not visible for the given VC.

Invariant Properties

Invariant properties are persisted at the LR and can only be retrieved or modified with methods available at the new LR interface (not the IResource methods). The LastModified(By) property values will indicate the last change of the invariant properties of the LR (or the last namespace operation on the children - if the PR is a collection) - it will not indicate changes of PRs.

New Resource Interfaces

A variant resource provides additional interfaces. The resources isA() and as() methods must be used to access these interfaces. A resource can be cast to a LR or PR using the following line of code (replace OtherType with the interface names):
OtherType ot = (OtherType)resource.as(OtherType.class);
But not all resources in a variant-enabled repository might be variants, that means it depends on the repository whether the result of the as() method may be null.

ILogicalVariantResource

This interface represents a LR. It contains methods to access the associated PR, modify invariant properties, create and delete PRs, and to search for PRs by using context properties as the search condition.

IPhysicalVariantResource

This interface represents a PR. With this interface it is possible to access the LR that the PR belongs to. The only methods in the KM API which may return instances of PRs are some of the new ILogicalariantResource methods and ResourceFactory.getResource()/getResources() (if the RID is a PR-RID). All other methods will always return LR instances.

Existing Resource Interfaces

This chapter provides a list of some of the existing resource interfaces and methods of the KM API (IResource, ICollection, IContent, etc.) and explains what must be considered if the resources type is LR or PR. The overall behaviour of the API methods depends on the repository implementation in the following ways:

Namespace

MethodLRPR
ICollection.getChildren The context resolution has been applied by the repository to each child. The returned resource list will always contain only LRs. Not supported
IResource.getParentColletion - Returns null
ICollection.createResource/createLink/createCollection A new LR and a initial PR is created. The property map should contain all context properties required by the repository. Whether it is required to specify all context properties or not depends on the repository implementation. If no context properties are specified the default context will be used. Not supported
IResource.setTargetURL/setLinkType - Not supported
IResource.delete All the PRs are also deleted. PR will be deleted if there is at least one other PR (LR must always have one remaining PR). If the PR is a collection, no children will be deleted because a PR has no children (see also getChildren() method).
IResource.rename/move - not supported
IResource.copy The LR and all of its PRs are copied. The PR is copied to a new LR with an initial PR.
IResource.search Executes a property query for properties. It is not possible to search using invariant properties in the query expression. not supported

Content and Properties

MethodLRPR
getProperty/getProperties Returns the properties of the associated PR. -
setProperty/setProperties/deleteProperty The properties of the associated PR are changed. Context properties can not be updated or deleted (exception is thrown). The properties of the PR are changed. Context properties can not be updated or deleted (exception is thrown).
updateContent: The content of the associated PR is updated. -

Locking

Plain resources and links:
If a LR is locked, the lock request applies to the associated PR. The lock will be "visible" at the LR and the PR, that means IResource.getLocks() and getLockByToken() will return a lock info object. The lock will affect the namespace of the LR: The LR cannot be deleted if one of its PRs is locked. But the lock does not affect the invariant properties of a LR - it is not possible to lock the invariant properties of plain resources. Locking a PR directly is equivalent to locking the LR that is associated with that PR.

Collections:
If a LR of a collection is locked, the lock request applies to the LR itself because the lock affects the namespace and the children of collections are not variant. The lock will protect the children of the collection and the invariant properties. Of course it is possible to lock PRs of collections directly.

Versioning

Each PR can have version control enabled. Versioning cannot be enabled for logical resources. As a consequence versioning is not available for invariant properties and link target. Versioning for link targets is not possible because the link target RID/URL cannot vary (it is persisted at the logical resource which does not support versioning).

MethodLRPR
IResource.isRevision Returns false Returns false
IResource.enableVersioning
IVersionController.enable/disable
IResource.getVersionHistory
IResource.checkOut/undoCheckOut/checkIn
Will affect the PR resource associated with the LR. -

Links

As the target RID/URL of a link resource is not variant, versioning is also not supported for link targets (only for properties).

Security

PRs will inherit their effective ACLs from their LR.

Eventing

The Repository Framework generates events for LRs which extend the conventional resource events. Events of this type are generated when a logical or physical variant resource is modified via the IResource, ICollection or ILogicalVariantResource interfaces. This means, that the resource attached to the event is always the logical resource and it can be accessed by calling IResourceEvent.getResource() and casting it: (ILogicalVariantResource)event.getResource().as(ILogicalVariantResource.class).
The new interface IVariantResourceEvent provides additional information to variant-enabled event receivers on the physical resource that was created, modified or deleted (directly or implicitly by a method called for the logical resource). Because of this extension-mechanism the new event types are compatible with normal resource events to support event receivers which are not aware of variants.

Logical Resource

When a LR is created, modified or deleted there is always exactly one PR affected (only exception: modification of invariant properties). The following table summarizes the information contained in the new event type.

Method Event Type Event Sub-Type IVariantResourceEvent.getPhysicalResource()
ICollection.createXXX CREATE_XXX - The new and first PR
IResource.updateContent SET UPDATE_CONTENT The modified PR
IResource.setProperty/setProperties
IResource.deleteProperty
PROPERTY_SET/PROPERTY_DELETE - The modified PR
IResource.delete DELETE - null (All PRs are deleted when the LR is deleted)
ILogicalVariantResource.createPhysicalResource SET CREATE The new PR
ILogicalVariantResource.set/deleteInvariantProperty PROPERTY_SET/PROPERTY_DELETE - null

Physical Resource

When a PR is modified an event is sent that has the LR attached. This is because the LR is conceptually a logical view on ALL of its PRs and from an event receivers point of view the LR has changed (the change might only be "visible" for some of the context values).

Method Event Type Event Sub-Type IVariantResourceEvent.getPhysicalResource()
IResource.updateContent SET UPDATE_CONTENT The modified PR
IResource.setProperty/setProperties
IResource.deleteProperty
PROPERTY_SET/PROPERTY_DELETE - The modified PR
IResource.delete SET DELETE The deleted PR

Code Examples

Create Variant Context for lookup

IPropertyMap variantContext = new MutablePropertyMap();
variantContext.put(new Property(propertyName, value));
IResourceContext ctxt = ResourceContext.getInstance(..., variantContext);
 
IResource resource = ResourceFactory.getInstace().getResource(rid, ctxt);

Casting to new resource interfaces

The following example shows how the PR is accessed:
ILogicalVariantResource lr = (ILogicalVariantResource)resource.as(ILogicalVariantResource.class)
if (lr == null) ...
IPhysicalVariantResource pr = lr.getPhysicalResource();
In this example the LR is accessed at the PR:
IPhysicalVariantResource pr = (IPhysicalVariantResource)resource.as(IPhysicalVariantResource.class)
if (pr == null) ...
ILogicalVariantResource lr = pr.getLogicalResource();

Read all Context Properties of a PR

The following examples works for both, LR and PR resources:
IPropertyNameList cpNameList = ((IVariantContextInfo)resource.getRepositoryManager()).listNames();
IPropertyMap cpMap = resource.getProperties(cpNameList);
Note: The context properties that are retrieved might be different (number of properties and values) from those in the variant context that was used to lookup the resource because the context resolution algorithm does not only do exact matches but may use all kinds of fallbacks or defaults.

Checking the existence of a certain PR

With the lookup method it is not possible to check if a PR variant exists using a LR-RID and a complete set of context properties. That is because the repository might always return a default/fallback resource. This task can be performed with the following code assuming that the variant context contains the complete set of properties that we want to look for. The findPhysicalResources() method will return one PR or an empty list because the complete set of context property values is used like a unique key.
IPropertyMap fullVariantContext = ...
IResourceContext ctxt = ResourceContext.getInstance(..., fullVariantContext);
ILogicalVariantResource lr = (ILogicalVariantResource)
  ResourceFactory.getInstace().getResource(rid, ctxt).as(ILogicalVariantResource.class);
IResourceList list = lr.findPhysicalResources(fullVariantContext);
IResource result = (list.size() > 0) ? list.get(0) : null;
Skip navigation links
SAP NetWeaver 7.50 SP 13 KMC

Copyright 2018 SAP AG Complete Copyright Notice