/******************************************************************************* | |
* Copyright (C) 2020 | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v20.html | |
******************************************************************************/ | |
/*------------------------------------------------------------------------------ | |
- | |
- 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 v2.0 | |
- which accompanies this distribution, and is available at | |
- http://www.eclipse.org/legal/epl-v20.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; | |
} | |
} |