blob: 59d3df322275c54558f23da7ef0f994a4e2c30e2 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2017 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* CEA LIST - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.moka.composites.profiling.Semantics.CompositeStructures.StructuredClasses;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.papyrus.moka.composites.Semantics.impl.CompositeStructures.InvocationActions.CS_RequestPropagationStrategy;
import org.eclipse.papyrus.moka.composites.interfaces.Semantics.CompositeStructures.StructuredClasses.ICS_InteractionPoint;
import org.eclipse.papyrus.moka.composites.interfaces.Semantics.CompositeStructures.StructuredClasses.ICS_Link;
import org.eclipse.papyrus.moka.composites.interfaces.Semantics.CompositeStructures.StructuredClasses.ICS_Object;
import org.eclipse.papyrus.moka.composites.interfaces.extensions.Semantics.CompositeStructures.StructuredClasses.ICS_ConnectorLink;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IReference;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.Communications.IEventOccurrence;
import org.eclipse.papyrus.moka.fuml.Semantics.impl.Actions.BasicActions.SendSignalActionActivation;
import org.eclipse.papyrus.moka.fuml.profiling.Semantics.Loci.SemanticVisitorProfiler;
import org.eclipse.uml2.uml.ConnectorKind;
import org.eclipse.uml2.uml.Operation;
public aspect CS_ObjectProfiler extends SemanticVisitorProfiler {
public CS_ObjectProfiler() {
super();
}
// Listen to any call on a CS_Object that results in sendIn(...)
pointcut sendIn(ICS_Object object, IEventOccurrence eventOccurrence, ICS_InteractionPoint interactionPoint) :
target(object) &&
args(eventOccurrence, interactionPoint) &&
call(* ICS_Object.sendIn(IEventOccurrence, ICS_InteractionPoint));
// Listen to any call on a CS_Object that results in sendOut(...)
pointcut sendOut(ICS_Object object, IEventOccurrence eventOccurrence, ICS_InteractionPoint interactionPoint) :
target(object) &&
args(eventOccurrence, interactionPoint) &&
call(* ICS_Object.sendOut(IEventOccurrence, ICS_InteractionPoint));
before(ICS_Object object, IEventOccurrence eventOccurrence, ICS_InteractionPoint interactionPoint) :
sendIn(object, eventOccurrence, interactionPoint){
// Each time a sendIn(...) is performed this implies the event occurrence is
// propagated through the interaction point to an internal target. This target
// is always an interaction point. At this point, the interaction point from which the
// event occurrence flows and the outgoing links are visited. This implies that
// any service listening to the node visited events will get notified about the
// the visit of the interaction points as well as its outgoing links.
this.visit(new CS_InteractionPointWrapper(interactionPoint));
Iterator<ICS_ConnectorLink> linkIterator = this
.getTraversedLinkWhenSentIn(object, eventOccurrence, interactionPoint).iterator();
while (linkIterator.hasNext()) {
this.visit(new CS_ConnectorLinkWrapper(linkIterator.next()));
}
}
before(ICS_Object object, IEventOccurrence eventOccurrence, ICS_InteractionPoint interactionPoint) :
sendOut(object, eventOccurrence, interactionPoint){
// Each time a sendOut(...) is performed this implies the event occurrences is
// propagated through the interaction point to the environment of the object.
// The target of the propagation always is an interaction point. At this point, the
// interaction point from which the event occurs flows and the outgoing links
// are visited. This implies that any service listening to the node visited events
// will get notified about the the visit of the interaction points as well as its
// outgoing links.
this.visit(new CS_InteractionPointWrapper(interactionPoint));
Iterator<ICS_ConnectorLink> linkIterator = this
.getTraversedLinkWhenSentOut(object, eventOccurrence, interactionPoint).iterator();
while (linkIterator.hasNext()) {
this.visit(new CS_ConnectorLinkWrapper(linkIterator.next()));
}
}
public List<ICS_ConnectorLink> getTraversedLinkWhenSentIn(ICS_Object object, IEventOccurrence eventOccurrence,
ICS_InteractionPoint interactionPoint) {
// Find out all links (i.e., runtime manifestation of connectors) that can be
// traversed
// to propagate the event occurrence when sent to the internals the object.
Iterator<ICS_Link> linkIterator = object.getLinks(interactionPoint).iterator();
List<ICS_ConnectorLink> traversedLink = new ArrayList<ICS_ConnectorLink>();
while (linkIterator.hasNext()) {
ICS_Link link = linkIterator.next();
List<IReference> targets = object.selectTargetsForSending(link, interactionPoint,
ConnectorKind.DELEGATION_LITERAL, true);
if (!targets.isEmpty()) {
traversedLink.add((ICS_ConnectorLink) link);
}
}
return traversedLink;
}
public List<ICS_ConnectorLink> getTraversedLinkWhenSentOut(ICS_Object object, IEventOccurrence eventOccurrence,
ICS_InteractionPoint interactionPoint) {
// Find out all links (i.e., runtime manifestation of connectors) that can be
// traversed to propagate the event occurrence when sent to the object environment.
// Note: in order to accurately notify the services about which links have been
// traversed, it is required to rely on a RequestPropagationStrategy that when executed two
// times on the same target list produces the exact same results.
List<IReference> allPotentialTargets = new ArrayList<IReference>();
List<ICS_ConnectorLink> referencedLink = new ArrayList<ICS_ConnectorLink>();
List<ICS_ConnectorLink> traversedLink = new ArrayList<ICS_ConnectorLink>();
Iterator<ICS_Link> linkIterator = object.getLinks(interactionPoint).iterator();
while (linkIterator.hasNext()) {
boolean referenceLink = false;
ICS_Link link = linkIterator.next();
Iterator<IReference> referenceIterator = object
.selectTargetsForSending(link, interactionPoint, ConnectorKind.ASSEMBLY_LITERAL, false).iterator();
while (referenceIterator.hasNext()) {
if (!referenceLink) {
referenceLink = true;
}
allPotentialTargets.add(referenceIterator.next());
}
referenceIterator = object
.selectTargetsForSending(link, interactionPoint, ConnectorKind.DELEGATION_LITERAL, false)
.iterator();
while (referenceIterator.hasNext()) {
if (!referenceLink) {
referenceLink = true;
}
allPotentialTargets.add(referenceIterator.next());
}
if (referenceLink) {
referencedLink.add((ICS_ConnectorLink) link);
}
}
CS_RequestPropagationStrategy strategy = (CS_RequestPropagationStrategy) object.getLocus().getFactory()
.getStrategy("requestPropagation");
List<IReference> selectedTargets = strategy.select(allPotentialTargets, new SendSignalActionActivation());
for (IReference target : selectedTargets) {
for (ICS_ConnectorLink connectorLink : referencedLink) {
if (connectorLink.hasValueForAFeature(target)) {
traversedLink.add((ICS_ConnectorLink) connectorLink);
}
}
}
return traversedLink;
}
// Listen to any call on CS_Object that results in dispatchIn(...)
pointcut dispatchIn(ICS_Object object, Operation operation, ICS_InteractionPoint interactionPoint):
target(object) &&
args(operation, interactionPoint) &&
call(* ICS_Object.dispatchIn(Operation, ICS_InteractionPoint));
// Listen to any call on CS_Object that results in dispatchOut(...)
pointcut dispatchOut(ICS_Object object, Operation operation, ICS_InteractionPoint interactionPoint):
target(object) &&
args(operation, interactionPoint) &&
call(* ICS_Object.dispatchOut(Operation, ICS_InteractionPoint));
before(ICS_Object object, Operation operation, ICS_InteractionPoint interactionPoint) :
// Each time a dispatchIn(...) is performed this implies the operation call is
// propagated through the interaction point to an internal target. This target
// is not always an interaction point. At this point, the interaction point from which the
// operation call flows and the outgoing links are visited.
dispatchIn(object, operation, interactionPoint){
this.visit(new CS_InteractionPointWrapper(interactionPoint));
Iterator<ICS_ConnectorLink> linkIterator = this
.getTraversedLinkWhenDispatchIn(object, interactionPoint, operation).iterator();
while (linkIterator.hasNext()) {
this.visit(new CS_ConnectorLinkWrapper(linkIterator.next()));
}
}
before(ICS_Object object, Operation operation, ICS_InteractionPoint interactionPoint) :
// Each time a dispatchIn(...) is performed this implies the operation call is
// propagated through the interaction point to an environment target. This target
// is not always an interaction point. At this point, the interaction point from which the
// operation call flows and the outgoing links are visited.
dispatchOut(object, operation, interactionPoint){
this.visit(new CS_InteractionPointWrapper(interactionPoint));
Iterator<ICS_ConnectorLink> linkIterator = this
.getTraversedLinkWhenDispatchOut(object, interactionPoint, operation).iterator();
while (linkIterator.hasNext()) {
this.visit(new CS_ConnectorLinkWrapper(linkIterator.next()));
}
}
public List<ICS_ConnectorLink> getTraversedLinkWhenDispatchIn(ICS_Object object,
ICS_InteractionPoint interactionPoint, Operation operation) {
// Find out all links (i.e., runtime manifestation of connectors) that can be
// traversed to propagate the operation call when sent to the internals the object.
Iterator<ICS_Link> linkIterator = object.getLinks(interactionPoint).iterator();
List<ICS_ConnectorLink> traversedLink = new ArrayList<ICS_ConnectorLink>();
while (linkIterator.hasNext()) {
ICS_Link link = linkIterator.next();
List<IReference> targets = object.selectTargetsForDispatching(link, interactionPoint,
ConnectorKind.DELEGATION_LITERAL, operation, true);
if (!targets.isEmpty()) {
traversedLink.add((ICS_ConnectorLink) link);
}
}
return traversedLink;
}
public List<ICS_ConnectorLink> getTraversedLinkWhenDispatchOut(ICS_Object object,
ICS_InteractionPoint interactionPoint, Operation operation) {
// Find out all links (i.e., runtime manifestation of connectors) that can be
// traversed to propagate the operation call when sent to the object environment.
// Note: in order to accurately notify the services about which links have been
// traversed, it is required to rely on a RequestPropagationStrategy that when
// executed two times on the same target list produces the exact same results.
List<IReference> allPotentialTargets = new ArrayList<IReference>();
List<ICS_ConnectorLink> referencedLink = new ArrayList<ICS_ConnectorLink>();
List<ICS_ConnectorLink> traversedLink = new ArrayList<ICS_ConnectorLink>();
Iterator<ICS_Link> linkIterator = object.getLinks(interactionPoint).iterator();
while (linkIterator.hasNext()) {
boolean referenceLink = false;
ICS_Link link = linkIterator.next();
Iterator<IReference> referenceIterator = object
.selectTargetsForDispatching(link, interactionPoint, ConnectorKind.ASSEMBLY_LITERAL, operation, false).iterator();
while (referenceIterator.hasNext()) {
if (!referenceLink) {
referenceLink = true;
}
allPotentialTargets.add(referenceIterator.next());
}
referenceIterator = object
.selectTargetsForDispatching(link, interactionPoint, ConnectorKind.DELEGATION_LITERAL, operation, false)
.iterator();
while (referenceIterator.hasNext()) {
if (!referenceLink) {
referenceLink = true;
}
allPotentialTargets.add(referenceIterator.next());
}
if (referenceLink) {
referencedLink.add((ICS_ConnectorLink) link);
}
}
CS_RequestPropagationStrategy strategy = (CS_RequestPropagationStrategy) object.getLocus().getFactory()
.getStrategy("requestPropagation");
List<IReference> selectedTargets = strategy.select(allPotentialTargets, new SendSignalActionActivation());
for (IReference target : selectedTargets) {
for (ICS_ConnectorLink connectorLink : referencedLink) {
if (connectorLink.hasValueForAFeature(target)) {
traversedLink.add((ICS_ConnectorLink) connectorLink);
}
}
}
return traversedLink;
}
}