public void DealClassifier(org.eclipse.uml2.uml.Classifier c1, RefOntoUML.Classifier c2) { DealNamedElement(c1, c2); // Important for Generalization, Property RelateElements(c1, c2); // isAbstract c2.setIsAbstract(c1.isAbstract()); }
public SignatureFacade createConstructorFacade(InstanceCreationExpression exp) throws Exception { List<TypeExpression> arguments = new ArrayList<TypeExpression>(); Map<String, TypeExpression> argumentsMap = new HashMap<String, TypeExpression>(); if (exp.getTuple().getInstanceCreationTupleElement() != null) { for (InstanceCreationTupleElement tupleElement : exp.getTuple().getInstanceCreationTupleElement()) { TypeExpression typeOfArgument = new TypeUtils().getTypeOfExpression(tupleElement.getObject()); if (typeOfArgument.getTypeFacade() instanceof ErrorTypeFacade) throw new TypeInferenceException(typeOfArgument); arguments.add(typeOfArgument); argumentsMap.put(tupleElement.getRole(), typeOfArgument); } } // first try to determine if the expression directly refers to a Class or a DataType TypeFacade cddClassifier = TypeFacadeFactory.eInstance.createVoidFacade(exp.getConstructor()); boolean errorInResolutionOfClassifier = false; if (cddClassifier instanceof ErrorTypeFacade) { errorInResolutionOfClassifier = true; } else { Classifier referencedType = cddClassifier.extractActualType(); if (referencedType instanceof PrimitiveType) { throw new Exception("Constructor invocations do not apply to primitive types"); } if (referencedType instanceof Enumeration) { throw new Exception("Constructor invocations do not apply to enumerations"); } if (referencedType.isAbstract()) { throw new Exception("Abstract classifiers cannot be instantiated"); } // The classifier has been resolved. Must determine if arguments match with possible // constructors if (referencedType instanceof org.eclipse.uml2.uml.Class) { List<EObject> visibleConstructor = AlfScopeProvider.scopingTool .getVisibleOperationsOrBehaviors(referencedType) .resolveByName(referencedType.getName()); if (visibleConstructor.size() > 1) { // try to match with arguments // if does not match, raise an exception List<SignatureFacade> visibleConstructorSignatures = new ArrayList<SignatureFacade>(); for (EObject cddConstructor : visibleConstructor) { SignatureFacade cddConstructorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(cddConstructor); if (cddConstructorSignature.isAConstructor()) visibleConstructorSignatures.add(cddConstructorSignature); } List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, visibleConstructorSignatures); if (matchingSignatures.size() > 1) { String errorMessage = referencedType.getName() + "("; boolean first = true; for (TypeExpression arg : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += arg.getLabel(); } errorMessage += ") resolves to multiple constructors"; throw new Exception(errorMessage); } else if (matchingSignatures.size() == 0) { String errorMessage = "Constructor " + referencedType.getName() + "("; boolean first = true; for (TypeExpression arg : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += arg.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } else { // exactly one match return matchingSignatures.get(0); } } else if (visibleConstructor.size() == 0) { if (arguments.size() > 0) { // Throw an exception String errorMessage = "Constructor " + referencedType.getName() + "("; boolean first = true; for (TypeExpression t : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += t.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } return new DefaultConstructorFacade((Class) referencedType); } else { // exactly one constructor found // Tries to determine if arguments match SignatureFacade constructor = createSignatureFacade(visibleConstructor.get(0)); if (!constructor.isAConstructor()) { // Throw an exception String errorMessage = "Constructor " + referencedType.getName() + "("; boolean first = true; for (TypeExpression t : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += t.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } String potentialErrorMessage = constructor.isCompatibleWithMe(argumentsMap); if (potentialErrorMessage.length() == 0) return constructor; else throw new Exception(potentialErrorMessage); } } else if (referencedType instanceof DataType) { // This is a data type. // must match arguments with visible properties of the data type SignatureFacade defaultDataTypeConstructor = new DefaultConstructorFacade((DataType) referencedType); String errorMessage = defaultDataTypeConstructor.isCompatibleWithMe(argumentsMap); if (!(errorMessage.length() == 0)) throw new Exception(errorMessage); else return defaultDataTypeConstructor; } } if (errorInResolutionOfClassifier) { // We can try again, but considering that: // - the last element in the qualified name as the name of a constructor // - the element before the last element is a class name if (exp.getConstructor().getRemaining() == null) throw new Exception("Constructor " + exp.getConstructor().getId() + " is undefined"); QualifiedNameWithBinding remaining = exp.getConstructor(); QualifiedNameWithBinding cddClassName = exp.getConstructor(); QualifiedNameWithBinding cddConstructorName = exp.getConstructor(); EObject previousPackage = null; while (cddConstructorName.getRemaining() != null) { cddClassName = cddConstructorName; cddConstructorName = cddConstructorName.getRemaining(); } if (remaining != cddClassName) { List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(remaining.getId()); if (visiblePackages.isEmpty()) { throw new Exception("Could not resolve package " + remaining.getId()); } else if (visiblePackages.size() > 1) { throw new Exception(remaining.getId() + " resolves to multiple packages"); } else { List<EObject> nestedVisiblePackages; previousPackage = visiblePackages.get(0); remaining = remaining.getRemaining(); while (remaining != cddClassName) { nestedVisiblePackages = AlfScopeProvider.scopingTool .getVisiblePackages(previousPackage) .resolveByName(remaining.getId()); if (nestedVisiblePackages.isEmpty()) { throw new Exception("Could not resolve package " + remaining.getId()); } else if (nestedVisiblePackages.size() > 1) { throw new Exception(remaining.getId() + " resolves to multiple packages"); } previousPackage = nestedVisiblePackages.get(0); remaining = remaining.getRemaining(); } } } // At this point, the (potential) path has been validated // cddClassName should resolve to a classifier List<EObject> visibleClassifiers = null; EObject resolvedClassifier = null; if (previousPackage != null) visibleClassifiers = AlfScopeProvider.scopingTool .getVisibleClassifiers(previousPackage) .resolveByName(cddClassName.getId()); else visibleClassifiers = AlfScopeProvider.scopingTool .getVisibleClassifiers(exp) .resolveByName(cddClassName.getId()); if (visibleClassifiers.isEmpty()) { throw new Exception("Could not resolve classifier " + cddClassName.getId()); } else if (visibleClassifiers.size() > 1) { throw new Exception(remaining.getId() + " resolves to multiple classifiers."); } else { resolvedClassifier = visibleClassifiers.get(0); } List<EObject> visibleConstructor = AlfScopeProvider.scopingTool .getVisibleOperationsOrBehaviors(resolvedClassifier) .resolveByName(cddConstructorName.getId()); if (visibleConstructor.size() > 1) { // try to match with arguments // if does not match, raise an exception List<SignatureFacade> visibleConstructorSignatures = new ArrayList<SignatureFacade>(); for (EObject cddConstructor : visibleConstructor) { SignatureFacade cddConstructorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(cddConstructor); if (cddConstructorSignature.isAConstructor()) visibleConstructorSignatures.add(cddConstructorSignature); } List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, visibleConstructorSignatures); if (matchingSignatures.size() > 1) { String errorMessage = cddConstructorName.getId() + "("; boolean first = true; for (TypeExpression arg : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += arg.getLabel(); } errorMessage += ") resolves to multiple constructors"; throw new Exception(errorMessage); } else if (matchingSignatures.size() == 0) { String errorMessage = "Constructor " + cddConstructorName.getId() + "("; boolean first = true; for (TypeExpression arg : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += arg.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } else { // exactly one match return matchingSignatures.get(0); } } else if (visibleConstructor.size() == 0) { String errorMessage = "Constructor " + cddConstructorName.getId() + "("; boolean first = true; for (TypeExpression arg : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += arg.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } else { // exactly one constructor // Tries to determine if arguments match SignatureFacade constructor = createSignatureFacade(visibleConstructor.get(0)); if (!constructor.isAConstructor()) { // Throw an exception String errorMessage = "Constructor " + cddConstructorName.getId() + "("; boolean first = true; for (TypeExpression t : arguments) { if (first) first = false; else errorMessage += ", "; errorMessage += t.getLabel(); } errorMessage += ") is undefined"; throw new Exception(errorMessage); } String potentialErrorMessage = constructor.isCompatibleWithMe(arguments, true); if (potentialErrorMessage.length() == 0) return constructor; else throw new Exception(potentialErrorMessage); } } throw new Exception("Not supported case"); }