<commit_before>package org.useware.kernel.model.scopes;

import org.useware.kernel.model.mapping.Node;
import org.useware.kernel.model.structure.Container;
import org.useware.kernel.model.structure.InteractionUnit;
import org.useware.kernel.model.structure.builder.InteractionUnitVisitor;

import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

import static org.useware.kernel.model.structure.TemporalOperator.Choice;
import static org.useware.kernel.model.structure.TemporalOperator.Deactivation;

/**
 * Assign scopes interaction units to scopes. Relies on a shim tree of the structure model.
 * @param <S>
 *
 * @author <NAME>
 */
public class ScopeAssignment<S extends Enum<S>> implements InteractionUnitVisitor<S> {

    private final InterfaceStructureShim<Integer> scopeShim;
    private final Set<Integer> contextIds = new HashSet<Integer>();
    private Stack<Scope> stack = new Stack<Scope>();

    private int scopeIdx = 0;

    public ScopeAssignment() {
        this.scopeShim = new InterfaceStructureShim<Integer>();
    }

    private Integer createContextId() {
        int contextId = ++scopeIdx;
        contextIds.add(contextId);
        return contextId;
    }

    public Set<Integer> getContextIds() {
        return contextIds;
    }

    @Override
    public void startVisit(Container container) {

        Node<Integer> containerNode = null;

        if(stack.isEmpty())
        {
            // top level: create new root node
            final Node<Integer> rootNode = new Node<Integer>(container.getId());
            rootNode.setData(createContextId());
            scopeShim.setRootElement(rootNode);
            stack.push(new Scope(rootNode) {
                @Override
                Integer getContextId() {
                    return rootNode.getData();
                }
            });

            containerNode = rootNode;
        }
        else
        {
            // child level: add new child & re-assign current container
            containerNode = stack.peek().getNode().addChild(container.getId());
        }

        if(container.getTemporalOperator().isScopeBoundary())
        {
            // distinct context, new UUID
            stack.push(new Scope(containerNode, stack.peek().getContextId()) {
                @Override
                Integer getContextId() {
                    return createContextId();
                }
            });

        }
        else
        {
            // re-use parent context id
            final Integer sharedContextId = stack.peek().getContextId();
            stack.push(new Scope(containerNode) {

                @Override
                Integer getContextId() {
                    return sharedContextId;
                }
            });

        }

    }

    @Override
    public void visit(InteractionUnit<S> interactionUnit) {
        Scope scope = stack.peek();
        Node<Integer> node = scope.getNode().addChild(interactionUnit.getId());
        node.setData(stack.peek().getContextId());
    }

    @Override
    public void endVisit(Container container) {

        Scope scope = stack.pop();

        if(scope.getPreviousContext()!=null)
            scope.getNode().setData(scope.getPreviousContext());
        else
            scope.getNode().setData(scope.getContextId());

    }

    public InterfaceStructureShim<Integer> getShim() {
        return scopeShim;
    }
}<commit_msg>document scope assignment strategy<commit_after>package org.useware.kernel.model.scopes;

import org.useware.kernel.model.mapping.Node;
import org.useware.kernel.model.structure.Container;
import org.useware.kernel.model.structure.InteractionUnit;
import org.useware.kernel.model.structure.builder.InteractionUnitVisitor;

import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

import static org.useware.kernel.model.structure.TemporalOperator.Choice;
import static org.useware.kernel.model.structure.TemporalOperator.Deactivation;

/**
 * Assign scopes interaction units to scopes.Creates a shim tree of the structure model.
 * <p/>
 * Scopes are assigned by interpretation of {@link org.useware.kernel.model.structure.TemporalOperator}'s.
 * If an operator acts as a scope boundary then a new scope id wil be assigned.
 * Atomic units inherit the scoped of their parents.
 *
 * @param <S> the supported stereotypes
 *
 * @see org.useware.kernel.model.structure.TemporalOperator#isScopeBoundary()
 *
 * @author <NAME>
 */
public class ScopeAssignment<S extends Enum<S>> implements InteractionUnitVisitor<S> {

    private final InterfaceStructureShim<Integer> scopeShim;
    private final Set<Integer> contextIds = new HashSet<Integer>();
    private Stack<Scope> stack = new Stack<Scope>();

    private int scopeIdx = 0;

    public ScopeAssignment() {
        this.scopeShim = new InterfaceStructureShim<Integer>();
    }

    private Integer createContextId() {
        int contextId = ++scopeIdx;
        contextIds.add(contextId);
        return contextId;
    }

    public Set<Integer> getContextIds() {
        return contextIds;
    }

    @Override
    public void startVisit(Container container) {

        Node<Integer> containerNode = null;

        if(stack.isEmpty())
        {
            // top level: create new root node
            final Node<Integer> rootNode = new Node<Integer>(container.getId());
            rootNode.setData(createContextId());
            scopeShim.setRootElement(rootNode);
            stack.push(new Scope(rootNode) {
                @Override
                Integer getContextId() {
                    return rootNode.getData();
                }
            });

            containerNode = rootNode;
        }
        else
        {
            // child level: add new child & re-assign current container
            containerNode = stack.peek().getNode().addChild(container.getId());
        }

        if(container.getTemporalOperator().isScopeBoundary())
        {
            // scope boundary, assign new scope id
            stack.push(new Scope(containerNode, stack.peek().getContextId()) {
                @Override
                Integer getContextId() {
                    return createContextId();
                }
            });

        }
        else
        {
            // re-use parent context id
            final Integer sharedContextId = stack.peek().getContextId();
            stack.push(new Scope(containerNode) {

                @Override
                Integer getContextId() {
                    return sharedContextId;
                }
            });

        }

    }

    @Override
    public void visit(InteractionUnit<S> interactionUnit) {

        // atomic units inherit the scope from their parents

        Scope scope = stack.peek();
        Node<Integer> node = scope.getNode().addChild(interactionUnit.getId());
        node.setData(stack.peek().getContextId());
    }

    @Override
    public void endVisit(Container container) {

        Scope scope = stack.pop();

        if(scope.getPreviousContext()!=null)
            scope.getNode().setData(scope.getPreviousContext());
        else
            scope.getNode().setData(scope.getContextId());

    }

    public InterfaceStructureShim<Integer> getShim() {
        return scopeShim;
    }
}
{'fraction_non_alphanumeric': 0.10203240867893436, 'fraction_numerical': 0.00027464982147761604, 'mean_word_length': 2.264455401165397, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2893838', 'n_tokens_mistral': 1950, 'n_tokens_neox': 1894, 'n_words': 421}