/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * * 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.uml.alf.validation.typing; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EObject; import org.eclipse.papyrus.uml.alf.alf.AcceptClause; import org.eclipse.papyrus.uml.alf.alf.AcceptStatement; import org.eclipse.papyrus.uml.alf.alf.Expression; import org.eclipse.papyrus.uml.alf.alf.SequenceExpansionExpression; import org.eclipse.papyrus.uml.alf.alf.SuffixExpression; import org.eclipse.papyrus.uml.alf.alf.TemplateBinding; import org.eclipse.papyrus.uml.alf.validation.AlfJavaValidator; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.ElementImport; import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.Operation; import org.eclipse.uml2.uml.ParameterableElement; import org.eclipse.uml2.uml.TemplateParameter; import org.eclipse.uml2.uml.TemplateParameterSubstitution; import org.eclipse.uml2.uml.TemplateableElement; import org.eclipse.uml2.uml.TypedElement; import org.eclipse.uml2.uml.UMLFactory; public class TypeFacade { protected EObject typeObject ; public void setTypeObject(EObject typeObject) { this.typeObject = typeObject ; //TODO this.templateBindingFacade = TemplateBindingFacadeFactory.eInstance.createTemplateBindingFacade(typeObject) ; } public String getLabelWithoutBinding() { if (typeObject == null) return "<Undefined>" ; return "" ; } public int isCompatibleWithMe(TypeFacade type) { Classifier myType = extractActualType(this) ; if (myType == null) // i.e. any return 3 ; Classifier hisType = extractActualType(type) ; if (hisType == null) return 0 ; if (perfectMatch(myType, hisType)) return 3 ; //else if (autoConversionMatch(myType, hisType)) TODO: temporarily commented. Rules need to be clarified // return 2 ; else if (inheritanceMatch(myType, hisType)) return 1 ; else return 0 ; } private boolean perfectMatch(Classifier myType, Classifier hisType) { boolean myTypeIsPredefined = myType.getName().equals("Integer") || myType.getName().equals("String") || myType.getName().equals("Boolean") || myType.getName().equals("UnlimitedNatural"); boolean hisTypeIsPredefined = hisType.getName().equals("Integer") || hisType.getName().equals("String") || hisType.getName().equals("Boolean") || hisType.getName().equals("UnlimitedNatural"); if (myTypeIsPredefined && hisTypeIsPredefined) return myType.getName().equals(hisType.getName()) ; return myType == hisType ; } private boolean autoConversionMatch(Classifier myType, Classifier hisType) { String autoConvertionOperatorName = "To" + myType.getName() ; List<SignatureFacade> availableConversionOperator = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(autoConvertionOperatorName) ; if (availableConversionOperator.isEmpty()) return false ; else { int numberOfMatchingOperators = 0 ; for (SignatureFacade cddMatchingConvertionOperator : availableConversionOperator) { Classifier parameterType = extractActualType(cddMatchingConvertionOperator.getParameters().get(0).getTypeFacade()) ; Classifier returnType = extractActualType(cddMatchingConvertionOperator.getReturnType().getTypeFacade()) ; if (perfectMatch(parameterType, hisType) && perfectMatch(returnType, myType)) numberOfMatchingOperators++ ; } return numberOfMatchingOperators == 1 ; } } private boolean inheritanceMatch(Classifier myType, Classifier hisType) { return hisType.getGenerals().contains(myType) ; } public static Classifier extractActualType(TypeFacade t) { Classifier actualType = null ; if (t.typeObject instanceof Classifier) actualType = (Classifier)t.typeObject ; else if (t.typeObject instanceof ElementImport){ ElementImport eImport = (ElementImport)t.typeObject ; if (eImport.getImportedElement() instanceof Classifier) actualType = (Classifier)eImport.getImportedElement() ; } else if (t.typeObject instanceof TypedElement) { actualType = (Classifier)((TypedElement)t.typeObject).getType() ; } else if (t instanceof VoidFacade) { actualType = extractActualType(((VoidFacade)t).getTypeFacade()) ; } else if (t.typeObject instanceof SequenceExpansionExpression) { // first retrieves the expression nesting this sequence variable EObject cddExpression = t.typeObject.eContainer() ; while (! (cddExpression instanceof Expression)) cddExpression = cddExpression.eContainer() ; // infers the type of the nesting expression, ignoring the t.typeObject suffix TypeExpression typeOfPrefix = new TypeUtils((SuffixExpression)t.typeObject).getTypeOfExpression((Expression)cddExpression) ; actualType = extractActualType(typeOfPrefix.getTypeFacade()) ; for (Operation o : actualType.getAllOperations()) { if (o.getName().equals("toSequence")) { actualType = (Classifier) (o.getReturnResult() != null ? o.getReturnResult().getType() : actualType) ; } } } return actualType ; } public Classifier extractActualType() { return extractActualType(this) ; } public boolean isAbstract() { Classifier myType = extractActualType() ; return myType != null ? myType.isAbstract() : false ; } public boolean isATemplate() { Classifier myType = extractActualType() ; return myType != null ? myType.isTemplate() : false ; } public boolean equals(Classifier c) { return this.typeObject == c ; } public boolean isACollection() { return this.isCompatibleWithMe(TypeUtils._Collection) > 0 || this.isCompatibleWithMe(TypeUtils._Set) > 0 || this.isCompatibleWithMe(TypeUtils._Bag) > 0 || this.isCompatibleWithMe(TypeUtils._Queue) > 0 || this.isCompatibleWithMe(TypeUtils._OrderedSet) > 0 || this.isCompatibleWithMe(TypeUtils._List) > 0 || this.isCompatibleWithMe(TypeUtils._Deque) > 0 || this.isCompatibleWithMe(TypeUtils._Map) > 0 ; } public boolean isOrdered() { // TODO Auto-generated method stub return false; } public String getLabel() { return "" ; // TODO: uncomment when template bindings are supported + this.templateBindingFacade.getLabel() ; } }