blob: cebbde06de3f5df8c7d8e2e1e8e2e21f1d284759 [file] [log] [blame]
/*------------------------------------------------------------------------------
-
- Copyright (c) 2015-2016 University of Padova, ITALY - Intecs SpA
- 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:
-
- Alessandro Zovi azovi@math.unipd.it
- Stefano Puri stefano.puri@intecs.it
- Laura Baracchi laura.baracchi@intecs.it
- Nicholas Pacini nicholas.pacini@intecs.it
-
- Initial API and implementation and/or initial documentation
------------------------------------------------------------------------------*/package org.polarsys.chess.multicore.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.BehavioralFeature;
import org.eclipse.uml2.uml.CallOperationAction;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.InstanceValue;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Slot;
import org.polarsys.chess.chessmlprofile.Core.IdentifSlot;
import org.polarsys.chess.chessmlprofile.Predictability.RTComponentModel.CHRtPortSlot;
import org.polarsys.chess.chessmlprofile.Predictability.RTComponentModel.CHRtSpecification;
import org.polarsys.chess.core.profiles.CHESSProfileManager;
import org.polarsys.chess.core.util.uml.ModelError;
import org.polarsys.chess.core.util.uml.UMLUtils;
/**
* The Class InstanceQuery.
*/
public class InstanceQuery {
/**
* Gets the instance spec package.
*
* @param umlModel the uml model
* @return the instance spec package
*/
public static Package getInstanceSpecPackage(Model umlModel){
Package cmpv = CHESSProfileManager.getViewByStereotype(
(Model) umlModel, CHESSProfileManager.COMPONENT_VIEW);
cmpv = QueryUtils.getOneResourcePlatformPackage(cmpv);
return cmpv;
}
/**
* Checks if is deferred.
*
* @param usedCH the used CH
* @return true, if is deferred
*/
static boolean isDeferred(CHRtSpecification usedCH) {
String occKind = usedCH.getOccKind();
return occKind!=null;
}
/**
* Gets the CH from slot.
*
* @param usedPiSlot the used pi slot
* @param operation the operation
* @return the CH from slot
*/
static CHRtSpecification getCHFromSlot(Slot usedPiSlot,
Operation operation) {
if(usedPiSlot == null){
return null;
}
CHRtPortSlot ch = UMLUtils.getStereotypeApplication(usedPiSlot, CHRtPortSlot.class);
if(ch==null)
return null;
for (CHRtSpecification i : ch.getCH_RtSpecification()) {
if (i.getContext().equals(operation)) {
return i;
}
if(UMLUtils.areOperationsEqual((Operation) i.getContext(), operation, null)){
return i;
}
}
assert false;
return null;
}
/**
* Gets the ri pi links.
*
* @param slot the slot
* @return the ri pi links
*/
private static EList<InstanceSpecification> getRiPiLinks(Slot slot){
EList<InstanceSpecification> riPiLinks = new BasicEList<InstanceSpecification>();
EList<Element> allOwnedElements = slot.getOwner().getOwner().allOwnedElements();
for (Element e : allOwnedElements) {
if (e instanceof InstanceSpecification) {
InstanceSpecification f = (InstanceSpecification) e;
boolean b = f.getClassifiers().size() == 0;
if(b){
riPiLinks.add(f);
}
}
}
return riPiLinks;
}
/**
* Gets the opposite slot.
*
* @param slot the slot
* @return the opposite slot
* @throws ModelError the model error
*/
/*identical of getCorrespondingSLot of QVTO transformation*/
static Slot getOppositeSlot(Slot slot) throws ModelError {
EList<InstanceSpecification> riPiLinks = getRiPiLinks(slot);
for (InstanceSpecification l : riPiLinks) {
EList<InstanceValue> ends = getEnds(l);
if(ends.size()!=2) throw new ModelError("A connector must have exactly 2 ends");
for (int i = 0; i < 2; i++) {
//1st step: i=0 j=1
//2nd step: i=1 j=0
int j = (i+1)%2;
InstanceValue first = ends.get(i);
boolean b = first.getInstance().equals(slot.getOwningInstance());
b = b && ((Slot)first.getOwner()).getDefiningFeature().equals(slot.getDefiningFeature());
if(b){
InstanceValue instanceValue = ends.get(j);
InstanceSpecification instance = instanceValue.getInstance();
Element owner = instanceValue.getOwner();
if (owner instanceof Slot) {
Slot sOwner = (Slot) owner;
for (Slot s : instance.getSlots()) {
if(s.getDefiningFeature().equals(sOwner.getDefiningFeature()))
return s;
}
}
}
}
/*checkingIV = ends.get(1);
b = checkingIV.getInstance().equals(slot.getOwningInstance());
b = b && ((Slot)checkingIV.getOwner()).getDefiningFeature().equals(slot.getDefiningFeature());
if(b){
InstanceSpecification instance = ends.get(0).getInstance();
for (Slot s : instance.getSlots()) {
if(s.getDefiningFeature().equals(((Slot)s.getOwner()).getDefiningFeature()))
return s;
}
}*/
}
return null;
}
/**
* Gets the ends.
*
* @param l the l
* @return the ends
*/
private static EList<InstanceValue> getEnds(InstanceSpecification l) {
EList<InstanceValue> ends = new BasicEList<InstanceValue>();
for (Element element : l.allOwnedElements()) {
if (element instanceof InstanceValue) {
InstanceValue iv = (InstanceValue) element;
ends.add(iv);
}
}
return ends;
}
/**
* Gets the slot from port.
*
* @param callOp the call op
* @param owningInstance the owning instance
* @return the slot from port
*/
static EList<Slot> getSlotFromPort(CallOperationAction callOp,
InstanceSpecification owningInstance) {
BehavioralFeature specification = callOp.getActivity().getSpecification();
Operation op = (Operation)specification;
Constraint c = null;
for (Constraint rule : op.getClass_().getOwnedRules()) {
for (Element cE :rule.getConstrainedElements()) {
if (cE instanceof CallOperationAction) {
CallOperationAction cCE = (CallOperationAction) cE;
if(cCE.equals(callOp))
c = rule;
break;
}
}
}
EList<Slot> result = new BasicEList<Slot>();
if(c==null){
for (Slot slot : owningInstance.getSlots()) {
if(slot.getDefiningFeature().equals(callOp.getOnPort())){
result.add(slot);
}
}
} else {
result = portToSlotsByRule(owningInstance, callOp.getOnPort(), c);
}
return result;
}
/**
* Gets the CH rt port slot.
*
* @param instPkg the inst pkg
* @param dOp the d op
* @return the CH rt port slot
* @throws ModelError the model error
*/
static CHRtPortSlot getCHRtPortSlot(Package instPkg, CHRtSpecification dOp) throws ModelError {
for (Element e : instPkg.allOwnedElements()) {
if(!(e instanceof Slot))
continue;
CHRtPortSlot pSlot = UMLUtils.getStereotypeApplication(e, CHRtPortSlot.class);
if(pSlot==null)
continue;
for (CHRtSpecification chSPec : pSlot.getCH_RtSpecification()) {
if(chSPec.equals(dOp)){
return pSlot;
}
}
}
throw new ModelError("Slot for %s does not exist in the instance package", dOp.getContext().getName());
}
/**
* Gets the CH rt commentsfrom port.
*
* @param piPort the pi port
* @param operation the operation
* @return the CH rt commentsfrom port
*/
private static void getCHRtCommentsfromPort(Port piPort, Operation operation) {
EList<Comment> ownedComments = piPort.getOwner().getOwner().getOwnedComments();
for (Comment comment : ownedComments) {
CHRtSpecification stereotypeApplication = UMLUtils.getStereotypeApplication(comment, CHRtSpecification.class);
if(stereotypeApplication !=null){
Operation context = (Operation) stereotypeApplication.getContext();
UMLUtils.isOperationEquals(context, operation);
}
}
}
/**
* Gets the opposite port.
*
* @param riPort the ri port
* @return the opposite port
*/
private static Port getOppositePort(Port riPort) {
EList<ConnectorEnd> ends = riPort.getEnds();
assert(ends.size()==1);
for (ConnectorEnd end : ends) {
Connector connector = (Connector)end.getOwner();
ConnectorEnd oppositeEnd = getOppositeEnd(connector, end);
Port oppositePort = (Port)oppositeEnd.getRole();
return oppositePort;
}
return null;
}
/**
* Gets the opposite end.
*
* @param connector the connector
* @param currentEnd the current end
* @return the opposite end
*/
private static ConnectorEnd getOppositeEnd(Connector connector, ConnectorEnd currentEnd) {
EList<ConnectorEnd> array = connector.getEnds();
assert(array.size()==2);
for (ConnectorEnd end : array) {
if(!end.equals(currentEnd))
return (ConnectorEnd) end;
}
return null;
}
/**
* Gets the method.
*
* @param dOp the d op
* @return the method
*/
static Activity getMethod(CHRtSpecification dOp) {
try {
return (Activity) dOp.getContext().getMethods().get(0);
} catch (Exception e) {
}
return null;
}
/**
* Port to slots by rule.
*
* @param self the self
* @param onPort the on port
* @param rule the rule
* @return the e list
*/
private static EList<Slot> portToSlotsByRule(InstanceSpecification self, Port onPort, Constraint rule) {
EList<Slot> list = new BasicEList<Slot>();
String values[] = rule.getSpecification().stringValue().trim().split(" ");
ArrayList<int[]> boundsList = new ArrayList<int[]>();
for (String value : values) {
boundsList.add(VSLUtils.getBounds(value));
}
for (Slot slot : self.getSlots()) {
IdentifSlot id = UMLUtils.getStereotypeApplication(slot, IdentifSlot.class);
if (id != null && slot.getDefiningFeature() == onPort && VSLUtils.isInBounds(id.getId(), boundsList)) {
list.add(slot);
}
else if (slot.getDefiningFeature() == onPort) {
list.add(slot);
}
}
return list;
}
}