Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
72:phase_freezes_prepare [2019/02/19 17:08] ext-bkkr72:phase_freezes_prepare [2024/02/15 00:00] (current) – external edit 127.0.0.1
Line 6: Line 6:
  
    * Process updates need to preserve the element identities. Do not use the "adopt elements" option when importing a core process.    * Process updates need to preserve the element identities. Do not use the "adopt elements" option when importing a core process.
-  * The scrope of the phase to freeze needs to be defined.+  * The scope of the phase to freeze needs to be defined.
   * Children of a process element are paths of their parent and therefore must be part of the same phase as the parent element.   * Children of a process element are paths of their parent and therefore must be part of the same phase as the parent element.
   * Metrics cannot be frozen, as they can have arbitrary data sources.   * Metrics cannot be frozen, as they can have arbitrary data sources.
Line 23: Line 23:
       * If an association is not frozen, the source element might get additional associations or it might lose some even if it is frozen itself.       * If an association is not frozen, the source element might get additional associations or it might lose some even if it is frozen itself.
   * Process elements that are part of multiple phases will get duplicated when one of those phases is frozen, as each phase needs a different version of the element. The duplicate is moved to an element folder called "Duplicaes for <phase name>".   * Process elements that are part of multiple phases will get duplicated when one of those phases is frozen, as each phase needs a different version of the element. The duplicate is moved to an element folder called "Duplicaes for <phase name>".
-  * Frozen process elements are marked by a little check mark taht provides a link to the owning phase.+  * Frozen process elements are marked by a little check mark that provides a link to the owning phase.
   * 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 Process.xml. 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 that should get frozen when the phase itself is frozen. (See example configuration below)
 +
 +<code>
 +<processtype ident="...">
 +[...]
 +<element ident="phase" subtypes="phase
 +milestone" **freezableSubtypes="phase" freezeScript="local/freeze/
 +moduleSpec.js">**
 +<model>
 +[...]
 +</model>
 +<view>
 +[...]
 +</view>
 +</element>
 +[...]
 +</processtype>
 +</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>
 +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);
 +</code>
 +
 +\\