Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
72:phase_freezes_prepare [2019/02/19 17:08] ext-bkkr72:phase_freezes_prepare [2019/02/19 17:26] ext-bkkr
Line 26: Line 26:
   * Frozen core process elements are separated from the core process because they will not be updated anymore when the current valid version and the working revision are merged into a new valid version.   * Frozen core process elements are separated from the core process because they will not be updated anymore when the current valid version and the working revision are merged into a new valid version.
   * The process freeze operation will lock the process including the working revision and the valid version as long as the operation is running to ensure a consistent freeze result. This also means that only one freeze operation can be executed at a time in a single workspace.   * The process freeze operation will lock the process including the working revision and the valid version as long as the operation is running to ensure a consistent freeze result. This also means that only one freeze operation can be executed at a time in a single workspace.
 +
 +==== Configure Phase Freeze Support in the Metamodel ====
 +
 +Phase Freeze needs to be enabled in the process metamodel in <font inherit/Courier New,Courier,monospace;;inherit;;inherit>PKitProcess</font>.<font inherit/Courier New,Courier,monospace;;inherit;;inherit>xml</font>. There you have to specify which subtypes of which element represent the entity to be frozen (phase root). In a typical case, you want to freeze a phase of your process, but not milestones which are also of type phase. Additionally, a Stages Script file needs to be configured to collect all dependent elements of the frozen phase taht should get frozen when the phase itself is frozen. (See example configuration below)
 +
 +<code>
 +<font inherit/Courier New,Courier,monospace;;inherit;;inherit><processtype ident="...">
 +[...]
 +<element ident="phase" subtypes="phase
 +milestone" **freezableSubtypes="phase" freezeScript="local/freeze/
 +moduleSpec.js">**
 +<model>
 +[...]
 +</model>
 +<view>
 +[...]
 +</view>
 +</element>
 +[...]
 +</processtype></font>
 +</code>
 +==== Freeze Script Programming ====
 +
 +The freeze script is used to determine the scope of the phase to freeze. It will call for an element of a freezable subtype and needs to collect all process elements that are part of that phase as well as all associations that need to get frozen. For all associations, it is possible to distinguish between freezing the association as is, or converting it to a comment. This is especially useful at the border of a phase or for associations of elements that are shared between phases. As shared elements are duplicated, freezing their associations as is would result in the target element to get associations to all copies, which might not be the desired behavior.
 +
 +^Variable^Type^Description|
 +|currentElement|IBaseElement|The phase root element.|
 +|moduleElementSet|Set|The result set to be filled with all elements to be frozen together with the current phase (currentElement).|
 +|moduleAssocSet|Set|The result set to be filled with all associations to be frozen together with the current phase (currentElement).|
 +|moduleAssocToCommentSet|Set|The result to be filed with all associations to be converted to comments when frozen together with the current phase (currentElement). It needs to be a subset of moduleAssocSet.|
 +|log|Logger|A means to log messages to the Stages log file.|
 +
 +**Example**
 +
 +The phase is here defined by the phase root element, its sequence associations and executed activities including their outputs. The responsible roles of the activities are converted to comments.
 +
 +<code>
 +<font inherit/Courier New,Courier,monospace;;inherit;;inherit>importPackage(Packages.java.util);
 +importPackage(Packages.de.methodpark.pkit.facade.impl);
 +function getSelfAndTransitiveChildren(self) {
 +var result = new Array();
 +result.push(self);
 +var children =
 +self.getEntities("hierarchy::hierarchic,targetrole=children");
 +for (var i = 0; i <children.length; ++i) {
 +result = result.concat(getSelfAndTransitiveChildren(children[i]));
 +}
 +return result;
 +}
 +function getAssociatedElementsCollectAssocs(source, assocType,
 +sourceRole, assocSet, remoteAssocSet) {
 +var assocSpec;
 +if (sourceRole === null) {
 +assocSpec = assocType;
 +} else {
 +assocSpec = assocType + ",sourcerole=" + sourceRole;
 +}
 +var assocsForward = source.getAssociations(assocSpec);
 +var targets = new Array();
 +for (var j = 0; j <assocsForward.length; j++) {
 +var forwardAssoc = assocsForward[j];
 +assocSet.add(forwardAssoc);
 +var isRemoteAssoc = forwardAssoc.isRemote();
 +//remote associations are converted to comments
 +if (isRemoteAssoc) {
 +remoteAssocSet.add(forwardAssoc);
 +}
 +var assocTarget = forwardAssoc.getTarget();
 +if (!(assocTarget instanceof MockElement)) {
 +// do not collect remote elements
 +if (!isRemoteAssoc) {
 +targets.push(assocTarget);
 +}
 +assocSet.add(forwardAssoc.getOpponentAssociation());
 +}
 +}
 +return targets;
 +}
 +function convertToComment(source, assocType, sourceRole, assocSet,
 +commentAssocSet) {
 +var assocSpec= assocType;
 +if (sourceRole !== null) {
 +assocSpec = assocSpec + ",sourcerole=" + sourceRole;
 +}
 +var assocsForward = source.getAssociations(assocSpec);
 +for (var j = 0; j <assocsForward.length; j++) {
 +var forwardAssoc = assocsForward[j];
 +assocSet.add(forwardAssoc);
 +commentAssocSet.add(forwardAssoc);
 +}
 +}
 +//start of script execution ----------------------------------
 +//freeze all children of the phase
 +var phases = getSelfAndTransitiveChildren(currentElement);
 +Collections.addAll(moduleElementSet, phases);
 +//freeze the predecessor and successor associations but not the
 +associated phases themselves
 +getAssociatedElementsCollectAssocs(currentElement, "sequence",
 +"predecessor", moduleAssocSet, moduleAssocToCommentSet);
 +getAssociatedElementsCollectAssocs(currentElement, "sequence",
 +"successor", moduleAssocSet, moduleAssocToCommentSet);
 +//freeze all the activities associated to one of the frozen phase
 +elements
 +var allActivities = new Array();
 +for (var k = 0; k <phases.length; k++) {
 +//Add associated 'execute' activities:
 +var associatedActivities = getAssociatedElementsCollectAssocs(phases[k],
 +"execute", null, moduleAssocSet, moduleAssocToCommentSet);
 +allActivities = allActivities.concat(associatedActivities);
 +}
 +Collections.addAll(moduleElementSet, allActivities);
 +var allOutputs = new Array();
 +for (var l = 0; l <allActivities.length; l++) {
 +//Freeze the output artifacts of the activities:
 +var outputs = getAssociatedElementsCollectAssocs(allActivities[l],
 +"output", null, moduleAssocSet, moduleAssocToCommentSet);
 +allOutputs = allOutputs.concat(outputs);
 +//convert responsible roles to comments
 +convertToComment(allActivities[l], "responsible", null, moduleAssocSet,
 +moduleAssocToCommentSet);
 +}
 +Collections.addAll(moduleElementSet, allOutputs);</font>
 +</code>
 +
 +\\