Package wt.vc.config

See:
          Description

Interface Summary
ConfigService This service helps obtain Iterated objects from Mastered objects (or a QuerySpec) and a ConfigSpec.
ConfigSpec Implementations of this interface are used by the ConfigService to convert Mastered objects into Iterated objects based on some existing QuerySpec.
GetConfigSpecForDelegate

Supported API: false

Extendable: false
InUseDelegate The InUseDelegate can be used to determine if a given iteration is undergoing change.
PersistableConfigSpec Implementations of this interface are used as other side objects in various associations of the wt.viewmarkup package.
SQLFunctionConfigSpec

Supported API: false

Extendable: false
 

Class Summary
BaselineConfigSpec The BaselineConfigSpec can be applied to Baselineables to filter those elements based on membership in a baseline.
CabinetBasedInUseDelegate InUseDelegate for Iterated, CabinetBased elements.
ConfigHelper This helper for the ConfigService provides convenience APIs useful for converting lists of links into lists of masters or iterations and for filtering lists.
ConfigServiceFwd This service helps obtain Iterated objects from Mastered objects (or a QuerySpec) and a ConfigSpec.
ConfigSpecProcessor Form processor which handles the display of the forms used to set a Configuration Specification.
ConfigSpecProcessor.ListEntry Helper class for maintaining both the OID of an object and its display value.
DefaultGetConfigSpecForDelegate

Supported API: false

Extendable: false
EffectivityConfigSpec The EffectivityConfigSpec can be used to filter elements to return only those that are effective, given a date/unit value and (possibly) a configuration item.
InUseConfigSpec The InUseConfigSpec uses the InUseDelegate mechanism to filter out elements that are in use by other principals.
InUseDelegateFactory Factory for InUseDelegates.
IteratedFolderedConfigSpec The IteratedFolderedConfigSpec can be used to filter IteratedFoldered elements based on folder location.
IteratedInUseDelegate Default delegate for Iterated elements.
LatestConfigSpec Returns, in priority order, the latest iteration for a master owned by the current principal, the latest iteration by comparing the iterationIdentifier's series value if not owned by the current principal, or the latest by create Timestamp if the series values are equivalent.
LifeCycleConfigSpec The LifeCycleConfigSpec can be applied to LifeCycleManaged elements to filter them based on life cycle state.
LockableInUseDelegate InUseDelegate for Iterated, Lockable elements.
MultipleLatestConfigSpec Returns all latest iterations for a master except those latest iterations not owned by the current principal (either checked-out to another user or stored in a personal cabinet).
MultipleOwnershipIndependentLatestConfigSpec This MultipleOwnershipIndependentLatestConfigSpec is similiar to the MultipleLatestConfigSpec, except that it does not take ownership into account.
OwnableInUseDelegate InUseDelegate for Iterated, Ownable elements.
OwnershipIndependentLatestConfigSpec This OwnershipIndependentLatestConfigSpec is similiar to the LatestConfigSpec, except that it does not take ownership into account.
SessionEditedIterationInUseDelegate

Supported API: true

Extendable: false
SetConfigSpecDelegate Form action delegate which handles creating a Configuration Specification from given Form data.
SetProductInstanceConfigSpecDelegate Form action delegate which handles creating a Configuration Specification from given Form data.
StandardConfigService This is a straight forward implementation of ConfigService that has no listeners.
ViewConfigSpec The ViewConfigSpec can be used to filter ViewManageable elements based on view membership.
WorkableInUseDelegate InUseDelegate for Iterated, Workable elements.
 

Exception Summary
ConfigException Exception thrown when the config package's APIs encounter invalid conditions specific to those APIs.
 

Package wt.vc.config Description

vc package - Configuration Specification Service

Engineers working with iterated and versioned data do so within a context, the same way software engineers using source control tools work in a branch. The engineer specifies the context to the system and the system uses it to calculate the appropriate representation. For example, a software engineer in the "Release 2" branch would work against a different version of the file ConfigSpec.java than would the software engineer maintaining "Release 1.0".

The wt.vc.config package provides the functionality needed to define a context and calculate appropriate versions based on the context; however, the versioning model must be understood before the config package can be understood. The Windchill version control model creates versions when masters are created or when existing versions are revised, branched, or checked out (check-out creates a temporary working version). The checkout/checkin process causes existing iterations to be superseded. While a version is conceptually the latest iteration, superseded iterations are also stored as versions in the implementation model because the version/iteration concepts have been joined at the datastore into a single table. VC's iterationsOf and versionsOf serve to highlight the distinction; versionsOf returns only latest iterations. However, the conceptual version is not always a latest iteration. A user specifying a baseline context, for example, wants the version in the baseline, which need not equate to a latest iteration. The config package calculates appropriate versions, without assuming that only latest iterations are versions.

The figure below illustrates the fundamental wt.vc.config classes and methods.

Fundamental wt.vc.config Classes and Methods

The config package encapsulates the concept of a context as the ConfigSpec interface. The concept of calculating the appropriate representation (versions) is a process by which a master or set of masters is converted into versions. This process is encapsulated in the filteredIterationsOf APIs defined in the ConfigService. The filteredIterationsOf API is composed of three phases.

The first establishes a QuerySpec based on the masters (passed as an argument) and a ConfigSpec; the QuerySpec's target class is Iterated or a subclass of it. The ConfigSpec's appendSearchCriteria is called during this phase, allowing the ConfigSpec to add any search criteria it needs to prefilter as a part of the query. Note that, because config does not assume that a version has to be a latest iteration, a query that does not include a "latest = true" condition will result in every iteration for each master to be returned.

The second phase is the query phase. The QuerySpec that was built is passed to the PersistenceHelper's find API (the resulting versions are, therefore, subject to access control).

The third and final phase allows the ConfigSpec to further filter the results of the query using an algorithm it defines in its process API if the query criteria it appended was not sufficient to guarantee the appropriate results. The following out-of-the-box ConfigSpecs illustrate the use of appendSearchCondition and process.

Basic ConfigSpecs

wt.vc.config.MultipleLatestConfigSpec

This ConfigSpec is very similar to VC's allVersionsOf, except that versions not owned by the current principal are not returned. It is useful when a user wants to see every version of a master to obtain a global sense of the evolution of the object, or simply wants to find these versions to do comparisons. The appendSearchCriteria API is implemented to append a "latest = true" condition in the same manner as versions are defined by VC. The process API removes those versions that are not owned by the current principal (that is, checked out to another user). Note that the appendSearchCriteria API could append conditions for ownership that would allow it to determine the valid versions without processing, but this can be done only when the target class itself is Ownable. Even so, a process is necessary because the target class may not be Ownable and have children that are.

wt.vc.config.LatestConfigSpec

Similar to the MultipleLatestConfigSpec, this ConfigSpec takes all those versions that would be valid in the MultipleLatesteConfigSpec and processes them down to a single version per master. Here, the bulk of the work is done in the process, where the latest version is determined by comparing versions (for example, A.A is later than A and A.2 is later than A.1). Since most contexts are intended to find one version, this ConfigSpec is often incorporated into other ConfigSpecs.

Clients working with versioned data may use the config's functionality to return all versions (via the MultipleLatestConfigSpec) or to return the current principal's working copy, if one exists. The wt.part package makes heavy use of the ConfigSpec in the Product Information Explorer to present a coherent picture of parts and their structures. The following ConfigSpecs have been defined for use by the part package.

wt.part PackageConfigSpecs

wt.part.WTPartStandardConfigSpec

This ConfigSpec is specifically written against parts (although it would work for any ViewManageable, Workable, and LifeCycleManaged Iterated class). It combines the state a part is in and the view it may be assigned to in order to produce a context that is based on state and view for latest iterations. If the lifeCycleState value is assigned, the version must be in that particular state (multiple states are not supported). If the view value is assigned, the version must be assigned to that view (or one of its parents if no version has been assigned to the view) or view independent. There is also a workingIncluded that, if false, removes anything that is owned, even if it is owned by the current principal. This ConfigSpec allows a user to state, for example, that he works in the Engineering view and would like to see the Released product. Note that the LatestConfigSpec is used to both append to the QuerySpec and process to a single version per master.

wt.part.WTPartBaselineConfigSpec

This ConfigSpec (which could be used with any Baselineable Iterated class) is the only out-of-the-box ConfigSpec to not follow VC's definition of a version as the latest iteration. It returns only those iterations that are assigned to the specified baseline.

wt.part.WTPartEffectivityConfigSpec

This ConfigSpec works with the effectivity package and ConfigurationItems to return only those versions that are effective given an effective date/unit and possibly a ConfigurationItem and View. This ConfigSpec handles the view setting in the same manner as WTPartStandardConfigSpec.

The following figure illustrates WTPartConfigSpec.

WTPartConfigSpec

The WTPartStandardConfigSpec, WTPartBaselineConfigSpec, and WTPartEffectivityConfigSpec are aggregated into the WTPartConfigSpec. This ConfigSpec establishes an active zone and simply forwards the appendSearchCondition and process commands to the active ConfigSpec.

The preceding examples are not the only ways contexts could be established. Other potential ways to establish a context are by project or cabinet/folder membership. These can all be created via simple customizations by implementing ConfigSpec and its APIs. The following illustrates the possible implementation of a ProjectConfigSpec with a project attribute of type Project. (Note that this should serve as an example only; it has not been tested and is not supported by Windchill as code.)

ProjectConfigSpec Example

After modeling the ProjectConfigSpec and generating its code, the appendSearchCriteria will be implemented to add SearchConditions for the value of the project attribute and for ownership if the target class is Ownable. Note the use of LatestConfigSpec.

public QuerySpec appendSearchCriteria( QuerySpec querySpec ) throws WTException, QueryException {
   //##begin appendSearchCriteria% [ ]36484C990290.body preserve=yes

   //We want only iterations, use LatestConfigSpec’s
   //appendSearchCondition
   //to append a "latest = true" search condition.
   QuerySpec qs = (new LatestConfigSpec()).appendSearchCriteria(querySpec);

   //Add the condition for project.
   qs.appendAnd();
   qs.appendSearchCondition(new SearchCondition(qs.getTargetClass(),
      ProjectManaged.PROJECT_ID +"."+ ObjectReference.KEY,
      SearchCondition.EQUAL,
      PersistenceHelper.getObjectIdentifier(project)));

   //If the target class is Ownable, make sure it’s either owned by
   // me or not owned at all (in a vault).
   if (qs.getTargetClass() instanceof Ownable) {
      qs.appendAnd();
      qs.appendOpenParen();
      qs.appendSearchCondition(OwnershipHelper.getSearchCondition(
         qs.getTargetClass(), SessionHelper.manager.getPrincipal(),
         true));
      qs.appendOr();
      qs.appendSearchCondition(OwnershipHelper.getSearchCondition(
      qs.getTargetClass(), false));
      qs.appendCloseParen();
   }

   return qs;
   //##end appendSearchCriteria% [ ]36484C990290.body
}

The process API is simple, although it does require some implementation. The target class might not have been Ownable and yet may have had Ownable children, so ownership needs to be processed. Also, this ConfigSpec should return a single version per master, so multiple versions will need to be processed down to one. Fortunately, the LatestConfigSpec does all of these things, so this implementation will simply return the result of executing its process API. The code would look similar to the following:

public QueryResult process( QueryResult results ) throws WTException {
   //##begin process% [ ]353B588501C5.body preserve=yes
   //We can not simply return the results, children of the target
   //class may have been Ownable, even though the target class was not.
   //Let LatestConfigSpec handle this case because its process API
   //accounts for that.
   return (new LatestConfigSpec()).process(results);;
   //##end process% [ ]353B588501C5.body
}

The config package, via a ConfigSpec and the ConfigService's filteredIterationsOf APIs, is fundamentally capable of converting masters to iterations. The ConfigHelper has APIs to extend its usefulness beyond simply taking masters and returning iterations.

ConfigHelper

The mastersOf APIs allow the conversion of a QueryResult of links to masters or Persistable[]'s in which masters can be found at a certain position. The conversion returns a QueryResult of masters that can then be applied to filteredIterationsOf. Similarly, iterationsOf converts to QueryResults of iterations that can then be processed by a ConfigSpec (useful for links to iterations). If no versions for a particular master match once it has been processed, it is possible to recover the master so it can be displayed in place of the version or versions (to indicate that no version matched, but there is data). This can be done via the recoverMissingMasters API. If iterations drop out as a result of being processed, links to those iterations can be removed by calling the removeExtraLinks API.

The Product Information Explorer navigates WTPartUsageLinks from part versions to part versions. The WTPartUsageLink (a type of IteratedUsageLink from wt.vc.struct) is defined between a WTPart and a WTPartMaster. No link is defined as being between WTPart and WTPart; however, the requirement for such a link comes primarily (as is the case for the Product Information Explorer) from display. The buildConfigResultsFromLinks API allows iteration-to-master associations to be represented as iteration-to-iteration associations by a client. It does this by pairing the master (on the master role) with its corresponding version and returning a QueryResult a Persistable's. Each element, a Persistable's, is of length 2 and contains the link in the 0th position and the version in the 1st position. The client then takes the real link's information (such as Quantity) and simply displays the version instead of the master. The following code illustrates the use of the ConfigSpec, ConfigService, and ConfigHelper to navigate an IteratedUsageLink to return either the other side (versions) or the links (and versions):

public QueryResult navigateSomeIteratedUsageLinkAlongTheUsesRole(Iterated someIteration, boolean onlyOtherSide, ConfigSpec someConfigSpec )
   throws WTException {
   //Navigate the link to its masters.
   QueryResult uses = PersistenceHelper.manager.navigate(someIteration, SomeIteratedUsageLink.USES_ROLE, SomeIteratedUsageLink.class, onlyOtherSide);

   //If the navigation returns links, convert those links to masters.
   QueryResult usesMasters = (onlyOtherSide) - uses :
   ConfigHelper.mastersOf(uses, IteratedUsageLink.USES_ROLE);

   //Get the iterations for these masters. If masters are lost because
   //no matching iterations were found, recover those masters for
   //display.
   QueryResult iterations =
      ConfigHelper.recoverMissingMasters(usesMasters,
         ConfigHelper.service.filteredIterationsOf(usesMasters, someConfigSpec));

   //If the user wants only the other side objects, return the
   //iterations. Otherwise, pair up the links with the versions
   //for those links.
   if (onlyOtherSide)
      return iterations;
   else
      return ConfigHelper.buildConfigResultFromLinks(uses, IteratedUsageLink.USES_ROLE, iterations);
}