/******************************************************************************* * Copyright (c) 2013, 2015 Willink Transformations and others. * 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: * E.D.Willink - initial API and implementation *******************************************************************************/ package org.eclipse.ocl.pivot.internal.library; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.ElementExtension; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.LanguageExpression; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.evaluation.Executor; import org.eclipse.ocl.pivot.ids.IdResolver; import org.eclipse.ocl.pivot.ids.TypeId; import org.eclipse.ocl.pivot.utilities.MetamodelManager; import org.eclipse.ocl.pivot.utilities.NameUtil; import org.eclipse.ocl.pivot.utilities.ParserException; import org.eclipse.ocl.pivot.values.InvalidValueException; /** * An instance of StereotypeProperty supports evaluation of a property call that accesses a stereotype extension property. */ public class StereotypeProperty extends ConstrainedProperty { public StereotypeProperty(@NonNull Property property) { super(property); } @Override public @Nullable Object evaluate(@NonNull Executor executor, @NonNull TypeId returnTypeId, @Nullable Object sourceValue) { IdResolver idResolver = executor.getIdResolver(); EObject eObject = asNavigableObject(sourceValue, property, executor); Object boxedValue = null; if (eObject instanceof ElementExtension) { ElementExtension elementExtension = (ElementExtension)eObject; String propertyName = property.getName(); Property extensionProperty = NameUtil.getNameable(elementExtension.getOwnedProperties(), propertyName); if (extensionProperty == null) { boolean gotIt = false; Object defaultValue = null; LanguageExpression defaultExpression = null; if (elementExtension.isIsApplied()) { EObject umlStereotypeApplication = elementExtension.getESObject(); if (umlStereotypeApplication != null) { EClass eClass = umlStereotypeApplication.eClass(); EStructuralFeature eStructuralFeature = NameUtil.getENamedElement(eClass.getEAllStructuralFeatures(), propertyName); if (eStructuralFeature != null) { defaultValue = idResolver.boxedValueOf(umlStereotypeApplication.eGet(eStructuralFeature)); gotIt = true; } } } if (!gotIt && (elementExtension.isIsApplied() || elementExtension.isIsRequired())) { Property theProperty = NameUtil.getNameable(elementExtension.getStereotype().getOwnedProperties(), propertyName); defaultValue = theProperty != null ? theProperty.getDefaultValue() : null; defaultExpression = theProperty != null ? theProperty.getOwnedExpression() : null; gotIt = true; } extensionProperty = PivotFactory.eINSTANCE.createProperty(); extensionProperty.setName(propertyName); extensionProperty.setIsRequired(property.isIsRequired()); extensionProperty.setIsStatic(property.isIsStatic()); extensionProperty.setType(property.getType()); extensionProperty.setDefaultValue(defaultValue); extensionProperty.setOwnedExpression(defaultExpression); elementExtension.getOwnedProperties().add(extensionProperty); } /* Property extensionProperty = ClassUtil.getNamedElement(elementExtension.getOwnedAttribute(), propertyName); if (extensionProperty == null) { boolean gotIt = false; EObject umlStereotypeApplication = elementExtension.getETarget(); if (umlStereotypeApplication != null) { EClass eClass = umlStereotypeApplication.eClass(); EStructuralFeature eStructuralFeature = EcoreUtils.getNamedElement(eClass.getEAllStructuralFeatures(), propertyName); if (eStructuralFeature != null) { Object value = umlStereotypeApplication.eGet(eStructuralFeature); gotIt = true; } } if (!gotIt && ) if (elementExtension.isApplied() && !elementExtension.isRequired()) { return null; } } */ // Property theProperty = ClassUtil.getNamedElement(elementExtension.getStereotype().getOwnedAttribute(), property.getName()); // if (theProperty == null) { // return super.evaluate(executor, returnTypeId, sourceValue); // } Object defaultValue = extensionProperty.getDefaultValue(); LanguageExpression defaultExpression = extensionProperty.getOwnedExpression(); if (!extensionProperty.isIsDerived()) { boxedValue = defaultValue; //idResolver.createInstance(property.getTypeId(), defaultValueLiteral); } else if (defaultExpression != null) { String body = defaultExpression.getBody(); if (body != null) { try { MetamodelManager metamodelManager = executor.getMetamodelManager(); ExpressionInOCL expr = metamodelManager.parseSpecification(defaultExpression); OCLExpression bodyExpression = expr.getOwnedBody(); if (bodyExpression != null) { boxedValue = executor.evaluate(bodyExpression); // FIXME errors } } catch (ParserException e) { throw new InvalidValueException(e, "Bad defaultExpression for '{0}'", property); } } } } else { EClass eClass = eObject.eClass(); EStructuralFeature eFeature = NameUtil.getENamedElement(eClass.getEAllStructuralFeatures(), property.getName()); if (eFeature != null) { Object value = eObject.eGet(eFeature); boxedValue = value != null ? idResolver.boxedValueOf(value, eFeature, returnTypeId) : null; } } return boxedValue; } }