blob: 7bb68edba4980a75d0da44307d413f3750428f3c [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2018 Fondazione Bruno Kessler.
* 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:
* Alberto Debiasi - initial API and implementation
* Luca Cristoforetti - initial API and implementation
******************************************************************************/
package org.polarsys.chess.OSSImporter.core.utils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
import org.eclipse.papyrus.infra.services.navigation.service.ExtendedNavigableElement;
import org.eclipse.papyrus.infra.services.navigation.service.NavigableElement;
import org.eclipse.papyrus.infra.services.navigation.service.NavigationService;
import org.eclipse.papyrus.infra.services.viewersearch.impl.ViewerSearchService;
import org.eclipse.papyrus.sysml.portandflows.FlowDirection;
import org.eclipse.papyrus.sysml.portandflows.FlowPort;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.FunctionBehavior;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.polarsys.chess.contracts.profile.chesscontract.ContractProperty;
import org.polarsys.chess.contracts.profile.chesscontract.FormalProperty;
import org.polarsys.chess.contracts.profile.chesscontract.util.ContractEntityUtil;
import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
import org.polarsys.chess.service.core.model.ChessSystemModel;
public class ChessElementsUtil {
// Logger for messages
private static final Logger logger = Logger.getLogger(ChessElementsUtil.class);
private final ChessSystemModel chessSystemModel = ChessSystemModel.getInstance();
private final EntityUtil entityUtil = EntityUtil.getInstance();
private final ContractEntityUtil contractEntityUtil = ContractEntityUtil.getInstance();
private static ChessElementsUtil chessElementsUtilInstance;
/**
* Gets an instance of the class if already present, or a new one if not.
*
* @return the instance of this class
*/
public static ChessElementsUtil getInstance() {
if (chessElementsUtilInstance == null) {
chessElementsUtilInstance = new ChessElementsUtil();
}
return chessElementsUtilInstance;
}
public void updateUmlFunctionBehaviour(FunctionBehavior functionBehavior, EList<Type> inputTypes,EList<String[]> inputMultiplicities,
Type outputType,String[] outputMultiplicity, HashMap<String, Boolean> mapFunctionBehaviorsToKeep) {
// Get all the existing parameters of the functionBehavior
final EList<org.eclipse.uml2.uml.Parameter> existingFunctionBehaviorParameters = functionBehavior
.getOwnedParameters();
// Stategy here is a little different. Remove all the parameters
// and add them from scratch
final EList<org.eclipse.uml2.uml.Parameter> toRemoveFunctionBehaviorParameters = new BasicEList<org.eclipse.uml2.uml.Parameter>(
existingFunctionBehaviorParameters);
// Remove all the existing parameters
for (org.eclipse.uml2.uml.Parameter parameter : toRemoveFunctionBehaviorParameters) {
entityUtil.removeFunctionBehaviorParameter(existingFunctionBehaviorParameters,
parameter.getQualifiedName());
}
entityUtil.createUmlFunctionBehaviorParameters(functionBehavior, inputTypes, inputMultiplicities, outputType, outputMultiplicity);
// Old code that tries to solve it in a different manner
// // Prepare the map to mark existing parameters
// final HashMap<String, Boolean> mapFunctionBehaviorParameters
// =
// Maps.newHashMapWithExpectedSize(existingFunctionBehaviorParameters.size());
// for (org.eclipse.uml2.uml.Parameter parameter :
// existingFunctionBehaviorParameters) {
// mapFunctionBehaviorParameters.put(parameter.getQualifiedName(),
// null);
// }
//
// org.eclipse.uml2.uml.Parameter parameter = null;
//
// // Check the input parameters
// for (SimpleType parameterType : parameters) {
// if ((parameter =
// chessElementsUtil.getExistingFunctionBehaviorParameter(existingFunctionBehaviorParameters,
// parameterType, true)) != null) {
// mapFunctionBehaviorParameters.put(parameter.getQualifiedName(),
// Boolean.TRUE);
// logger.debug("functionBehavior input parameter already
// present");
// } else {
// logger.debug("functionBehavior input parameter is not
// present");
//
// // Create the input parameter
// chessElementsUtil.createFunctionBehaviorParameter(functionBehavior,
// parameterType, true);
// }
// }
//
// // Check the output parameter
// if ((parameter =
// chessElementsUtil.getExistingFunctionBehaviorParameter(existingFunctionBehaviorParameters,
// dslVariableType, false)) != null) {
// logger.debug("functionBehavior output parameter already
// present");
// mapFunctionBehaviorParameters.put(parameter.getQualifiedName(),
// Boolean.TRUE);
// } else {
// logger.debug("functionBehavior output parameter is not
// present");
//
// // Create the output parameter
// chessElementsUtil.createFunctionBehaviorParameter(functionBehavior,
// dslVariableType, false);
// }
//
// // Parameters cleanup time
// for (String qualifiedElement :
// mapFunctionBehaviorParameters.keySet()) {
// if (mapFunctionBehaviorParameters.get(qualifiedElement) ==
// null) {
// System.out.println("functionBehaviorParameter " +
// qualifiedElement + " should be removed");
// chessElementsUtil.removeFunctionBehaviorParameter(existingFunctionBehaviorParameters,
// qualifiedElement);
// }
// }
// Set the flag to signal the functionBehavior is still used
mapFunctionBehaviorsToKeep.put(functionBehavior.getQualifiedName(), Boolean.TRUE);
}
// checked methods
public void updateUmlStaticPort(org.eclipse.uml2.uml.Port port, String[] newMultiplicityRange,
HashMap<String, Boolean> mapPortsToKeep) {
// Update its multiplicity if needed
entityUtil.updateUmlStaticPort(port, newMultiplicityRange);
// Set the flag to signal the port is still used
mapPortsToKeep.put(port.getQualifiedName(), Boolean.TRUE);
}
public void updateUmlNonStaticPort(org.eclipse.uml2.uml.Port port, eu.fbk.tools.editor.oss.oss.Port ossPort,
Type newType, String[] newMultiplicityRange, FlowDirection portDirection, Stereotype flowPortStereotype,
HashMap<String, Boolean> mapPortsToKeep) {
// Port found, update its direction if needed
final FlowPort flowPort = (FlowPort) port.getStereotypeApplication(flowPortStereotype);
if (flowPort.getDirection() != portDirection) {
flowPort.setDirection(portDirection);
}
// Update its type if needed
entityUtil.updateUmlNonStaticPort(port, newType, newMultiplicityRange);
// Set the flag to signal the port is still used
mapPortsToKeep.put(port.getQualifiedName(), Boolean.TRUE);
// Add the port to the list of changes NOT NEEDED BECAUSE
// DIAGRAMS ARE AUTO-UPDATING
// addedElements.add(port);
}
public void updateUmlRefinementFormalProperty(Constraint umlConstraint, String updatedText, String language,
HashMap<String, Boolean> mapFormalPropertiesToKeep) {
// Update the formal property if needed
entityUtil.updateUmlConstraint(umlConstraint, updatedText, language);
// Set the flag to signal the formal property is
// still used
mapFormalPropertiesToKeep.put(umlConstraint.getQualifiedName(), Boolean.TRUE);
}
public void updateUmlFormalProperty(Constraint umlConstraint, String assertionText,String language,
HashMap<String, FormalProperty> hashFormalProperties, HashMap<String, Boolean> mapFormalPropertiesToKeep) {
// Update the formal property if needed
final String formalPropertyText = entityUtil.getConstraintBodyStr(umlConstraint,language);
// If the expression is different, save it, otherwise go on
if (!assertionText.equals(formalPropertyText)) {
entityUtil.setTextInUMLConstraint(umlConstraint, assertionText, language);
}
// Set the flag to signal the formal property is still used
mapFormalPropertiesToKeep.put(umlConstraint.getQualifiedName(), Boolean.TRUE);
}
public void updateUmlContract(Class umlContract, String ossAssumptionText, String ossGuaranteeText, String language,
HashMap<String, FormalProperty> hashFormalProperties, HashMap<String, Boolean> mapContractPropertiesToKeep,
HashMap<String, Boolean> mapFormalPropertiesToKeep, Class owner) {
final org.polarsys.chess.contracts.profile.chesscontract.Contract contract =
contractEntityUtil.getContract(umlContract);
final FormalProperty contractAssumption = contract.getAssume();
final FormalProperty contractGuarantee = contract.getGuarantee();
// Check if the assumption formal property is already present in the hash
final FormalProperty hashAssumption = hashFormalProperties.get(ossAssumptionText);
if (hashAssumption != null) {
logger.debug("assumption already present in the hash = " + hashAssumption);
// Check if the assumption is different from the one already set
if (hashAssumption != contractAssumption) {
// Check if the current assumption is child of the contract. If so, it can be removed
if (contractAssumption.getBase_Constraint().getOwner() == contract.getBase_Class()) {
// The old assumption needs to be removed from the contract
final EList<Constraint> fpList = new BasicEList<Constraint>();
fpList.add(contractAssumption.getBase_Constraint());
entityUtil.removeFormalProperty(fpList, contractAssumption.getBase_Constraint().getQualifiedName());
}
// Set the new assumption
contract.setAssume(hashAssumption);
}
} else {
logger.debug("assumption not present in the hash");
// Check if the current assumption is child of the contract. If so, it can be edited
if (contractAssumption.getBase_Constraint().getOwner() == contract.getBase_Class()) {
// The assumption is the same, update it if needed
entityUtil.updateUmlConstraint(contractAssumption.getBase_Constraint(), ossAssumptionText, language);
} else {
// The assumption is a block formal property, cannot be modified or removed
// A new one has to be created
contractEntityUtil.createAssumptionToUmlContract(umlContract);
final FormalProperty assumptionFormalProperty = contractEntityUtil.getAssumeFromUmlContract(umlContract);
entityUtil.setTextInUMLConstraint(assumptionFormalProperty.getBase_Constraint(), ossAssumptionText, language);
}
}
// Check if the guarantee formal property is already present in the hash
final FormalProperty hashGuarantee = hashFormalProperties.get(ossGuaranteeText);
if (hashGuarantee != null) {
logger.debug("guarantee already present in the hash = " + hashGuarantee);
// Check if the guarantee is different from the one already set
if (hashGuarantee != contractGuarantee) {
// Check if the current guarantee is child of the contract. If so, it can be removed
if (contractGuarantee.getBase_Constraint().getOwner() == contract.getBase_Class()) {
// The old guarantee needs to be removed from the contract
final EList<Constraint> fpList = new BasicEList<Constraint>();
fpList.add(contractGuarantee.getBase_Constraint());
entityUtil.removeFormalProperty(fpList, contractGuarantee.getBase_Constraint().getQualifiedName());
}
// Set the new guarantee
contract.setGuarantee(hashGuarantee);
}
} else {
logger.debug("guarantee not present in the hash");
// Check if the current guarantee is child of the contract. If so, it can be edited
if (contractGuarantee.getBase_Constraint().getOwner() == contract.getBase_Class()) {
// The guarantee is the same, update it if needed
entityUtil.updateUmlConstraint(contractGuarantee.getBase_Constraint(), ossGuaranteeText, language);
} else {
// The guarantee is a block formal property, cannot be modified or removed
// A new one has to be created
contractEntityUtil.createGuaranteeToUmlContract(umlContract);
final FormalProperty guaranteeFormalProperty = contractEntityUtil.getGuaranteeFromUmlContract(umlContract);
entityUtil.setTextInUMLConstraint(guaranteeFormalProperty.getBase_Constraint(), ossGuaranteeText, language);
}
}
// Set the flag to signal the contractProperty is still used
final ContractProperty contractProperty = (ContractProperty) chessSystemModel.getContract(owner,
// dslContract.getName() should be the same
umlContract.getName());
mapContractPropertiesToKeep.put(contractProperty.getBase_Property().getQualifiedName(), Boolean.TRUE);
}
public void updateUmlAssociation(Property componentInstance, Type type, String[] ossSubComponentMultiplicity,
HashMap<String, Boolean> mapComponentInstancesToKeep) throws Exception {
entityUtil.updateUmlAssociation(componentInstance, type, ossSubComponentMultiplicity);
// Set the flag to signal the componentInstance is still used
mapComponentInstancesToKeep.put(componentInstance.getQualifiedName(), Boolean.TRUE);
}
public Constraint createUmlInterfaceFormalProperty(String assertionName, String assertionText,
HashMap<String, FormalProperty> hashFormalProperties, Class owner) {
Constraint umlConstraint = entityUtil.createInterfaceFormalProperty(owner, assertionName, assertionText);
// Add the formal property to the hash
hashFormalProperties.put(assertionName, entityUtil.getFormalProperty(umlConstraint));
return umlConstraint;
}
public Class createUmlContract(String contractName, String ossAssumptionText, String ossGuaranteeText,
HashMap<String, FormalProperty> hashFormalProperties, Class owner, Stereotype contractStereotype) {
// Create an empty Contract
Class umlContract = contractEntityUtil.createContract(owner, contractName, contractStereotype);
org.polarsys.chess.contracts.profile.chesscontract.Contract contract =
contractEntityUtil.getContract(umlContract);
// Check if the assumption formal property is already defined
final FormalProperty assumption = hashFormalProperties.get(ossAssumptionText);
if (assumption != null) {
logger.debug("assumption already present = " + assumption);
// Add the assume formal property
contract.setAssume(assumption);
} else {
logger.debug("assumption not present");
// Create a new formal property
contractEntityUtil.setTextToAssumeOrCreateAssume(ossAssumptionText, umlContract);
}
// Check if the guarantee formal property is already defined
final FormalProperty guarantee = hashFormalProperties.get(ossGuaranteeText);
if (guarantee != null) {
logger.debug("guarantee already present = " + guarantee);
// Add the assume formal property
contract.setGuarantee(guarantee);
} else {
logger.debug("guarantee not present");
// Create a new formal property
contractEntityUtil.setTextToGuaranteeOrCreateGuarantee(ossGuaranteeText, umlContract);
}
return umlContract;
}
/**
* Updates the expression of the given Macro Definition, if needed.
* @param umlConstraint the Macro Definition as Constraint
* @param macroDefinitionExpression the new expression
* @param mapMacroDefinitionsToKeep the map of existing Macro Definitions
*/
public void updateMacroDefinition(Constraint umlConstraint, String macroDefinitionExpression, String language,
HashMap<String, Boolean> mapMacroDefinitionsToKeep) {
entityUtil.updateMacroDefinition(umlConstraint, macroDefinitionExpression,language);
// Set the flag to signal the macro definition is still used
mapMacroDefinitionsToKeep.put(umlConstraint.getQualifiedName(), Boolean.TRUE);
}
/**
* Returns the list of diagrams in which the given element is present.
* @param members the list of members in which the element is present
* @param qualifiedElement the qualified name of element
* @return names of the diagrams
*/
public Set<String> getInvolvedDiagrams(EList<?> members, String qualifiedElement) {
final Set<String> diagramNames = new HashSet<String>();
for (Object object : members) {
NamedElement element = null;
if (object instanceof NamedElement) {
element = (NamedElement) object;
} else if (object instanceof ContractProperty) {
element = ((ContractProperty) object).getBase_Property();
}
if (element != null && element instanceof NamedElement) {
if (element.getQualifiedName().equals(qualifiedElement)) {
try {
NavigationService navigationService = null;
try {
final ServicesRegistry registry = ServiceUtilsForEObject.getInstance().getServiceRegistry(element);
if (registry != null) {
navigationService = registry.getService(NavigationService.class);
}
} catch (ServiceException e) {
e.printStackTrace();
}
if (navigationService != null) {
final List<NavigableElement> navigableElements = navigationService.getNavigableElements(element);
if (navigableElements != null) {
for (NavigableElement navigableElement : navigableElements) {
final List<Object> viewsToSelect = getViewsToSelect(navigableElement, false);
for (Object view : viewsToSelect) {
diagramNames.add(getText(view));
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} else {
logger.debug("cannot find a reprentation for " + qualifiedElement);
}
}
return diagramNames;
}
// The following code has been taken from these classes:
// org.eclipse.papyrus.infra.gmfdiag.navigation.ui.DynamicNavigateLabelProvider
// org.eclipse.papyrus.infra.gmfdiag.navigation.ui.DynamicNavigate
protected static boolean isLocalLabelProvider;
private static String getText(Object element) {
if (element instanceof NavigableElement) {
return ((NavigableElement) element).getLabel();
} else if (element instanceof EObject) {
return getName((EObject) element);
}
return element.toString();
}
private static String getName(EObject element) {
ILabelProvider labelProvider = getLabelProvider((EObject) element);
String name = labelProvider.getText(element);
if (isLocalLabelProvider) {
labelProvider.dispose();
}
if (name != null) {
return name;
} else {
return element.toString();
}
}
private static ILabelProvider getLabelProvider(EObject element) {
ILabelProvider labelProvider = null;
try {
labelProvider = ServiceUtilsForEObject.getInstance().getService(LabelProviderService.class, element).getLabelProvider("org.eclipse.papyrus.infra.services.navigation.menu.labelprovider");
} catch (ServiceException e) {
e.printStackTrace();
}
if (labelProvider == null) {
labelProvider = new LabelProvider();
isLocalLabelProvider = true;
} else {
isLocalLabelProvider = false;
}
return labelProvider;
}
/**
* Get views representing a navigable element
*
* @param navElement
* The navigable element represented in views
* @param onlyOpened
* Only opened views are returned
* @return
* List of views representing the navigable element
*/
private List<Object> getViewsToSelect(NavigableElement navElement, boolean onlyOpened) {
if (navElement == null) {
return null;
}
EObject element = null;
if (navElement instanceof ExtendedNavigableElement
&& ((ExtendedNavigableElement) navElement).getSemanticElement() instanceof EObject) {
element = (EObject) ((ExtendedNavigableElement) navElement).getSemanticElement();
}
if (element != null) {
ViewerSearchService viewerSearchService = null;
try {
viewerSearchService = ServiceUtilsForEObject.getInstance().getService(ViewerSearchService.class, element);
} catch (Exception e) {
e.printStackTrace();
}
if (viewerSearchService != null) {
return viewerSearchService.getViewersInCurrentModel(element, null, false, onlyOpened);
}
}
return new LinkedList<Object>();
}
}