| /******************************************************************************* |
| * Copyright (c) 2016, 2018 Willink Transformations and others. |
| * 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: |
| * E.D.Willink - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.qvtd.pivot.qvtrelation.utilities; |
| |
| import java.util.List; |
| |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.ocl.pivot.CollectionType; |
| import org.eclipse.ocl.pivot.OCLExpression; |
| import org.eclipse.ocl.pivot.Property; |
| import org.eclipse.ocl.pivot.StandardLibrary; |
| import org.eclipse.ocl.pivot.Type; |
| import org.eclipse.ocl.pivot.Variable; |
| import org.eclipse.ocl.pivot.utilities.EnvironmentFactory; |
| import org.eclipse.ocl.pivot.utilities.PivotUtil; |
| import org.eclipse.qvtd.pivot.qvtbase.Pattern; |
| import org.eclipse.qvtd.pivot.qvtbase.QVTbaseFactory; |
| import org.eclipse.qvtd.pivot.qvtbase.TypedModel; |
| import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseHelper; |
| import org.eclipse.qvtd.pivot.qvtbase.utilities.TraceHelper; |
| import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern; |
| import org.eclipse.qvtd.pivot.qvtrelation.Key; |
| import org.eclipse.qvtd.pivot.qvtrelation.QVTrelationFactory; |
| import org.eclipse.qvtd.pivot.qvtrelation.Relation; |
| import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp; |
| import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; |
| import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation; |
| import org.eclipse.qvtd.pivot.qvtrelation.SharedVariable; |
| import org.eclipse.qvtd.pivot.qvtrelation.TemplateVariable; |
| import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp; |
| import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp; |
| import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem; |
| import org.eclipse.qvtd.pivot.qvttemplate.QVTtemplateFactory; |
| import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; |
| import com.google.common.collect.Iterables; |
| |
| /** |
| * QVTrelationHelper provides helper routines to assist creation of QVTrelation model elements. |
| */ |
| public class QVTrelationHelper extends QVTbaseHelper |
| { |
| public QVTrelationHelper(@NonNull EnvironmentFactory environmentFactory) { |
| super(environmentFactory); |
| } |
| |
| public void addWhenPredicate(@NonNull Relation qvtrRelation, @NonNull OCLExpression asExpression) { |
| Pattern asPattern = qvtrRelation.getWhen(); |
| if (asPattern == null) { |
| asPattern = QVTbaseFactory.eINSTANCE.createPattern(); |
| qvtrRelation.setWhen(asPattern); |
| } |
| asPattern.getPredicate().add(createPredicate(asExpression)); |
| } |
| |
| public void addWherePredicate(@NonNull Relation qvtrRelation, @NonNull OCLExpression asExpression) { |
| Pattern asPattern = qvtrRelation.getWhere(); |
| if (asPattern == null) { |
| asPattern = QVTbaseFactory.eINSTANCE.createPattern(); |
| qvtrRelation.setWhere(asPattern); |
| } |
| asPattern.getPredicate().add(createPredicate(asExpression)); |
| } |
| |
| /** |
| * Traverse the templateExp hierarchy assigning all special variables (_) to specialVariables allocating a distinctive name to each. |
| * Append special member variables to relationVariables as well. |
| */ |
| public void computeBoundVariables(@NonNull List<@NonNull Variable> boundVariables, @NonNull OCLExpression asExpression) { |
| if (asExpression instanceof ObjectTemplateExp) { |
| ObjectTemplateExp asObjectTemplateExp = (ObjectTemplateExp)asExpression; |
| Variable asBoundVariable = QVTrelationUtil.getBindsTo(asObjectTemplateExp); |
| if (!boundVariables.contains(asBoundVariable)) { |
| boundVariables.add(asBoundVariable); |
| } |
| for (@NonNull PropertyTemplateItem asPart : QVTrelationUtil.getOwnedParts(asObjectTemplateExp)) { |
| computeBoundVariables(boundVariables, QVTrelationUtil.getOwnedValue(asPart)); |
| } |
| } |
| else if (asExpression instanceof CollectionTemplateExp) { |
| CollectionTemplateExp asCollectionTemplateExp = (CollectionTemplateExp)asExpression; |
| Variable asBoundVariable = QVTrelationUtil.getBindsTo(asCollectionTemplateExp); |
| if (!boundVariables.contains(asBoundVariable)) { |
| boundVariables.add(asBoundVariable); |
| } |
| for (@NonNull OCLExpression asMemberExpression : QVTrelationUtil.getOwnedMembers(asCollectionTemplateExp)) { |
| computeBoundVariables(boundVariables, asMemberExpression); |
| } |
| } |
| // else if (asExpression instanceof VariableExp) { // FIXME temporary test compatibility |
| // Variable asVariable = QVTrelationUtil.getReferredVariable((VariableExp)asExpression); |
| // if (!boundVariables.contains(asVariable)) { |
| // boundVariables.add(asVariable); |
| // } |
| // } |
| } |
| |
| public @NonNull CollectionTemplateExp createCollectionTemplateExp(@NonNull TemplateVariable asTemplateVariable, org.eclipse.ocl.pivot.@NonNull Class asClass, boolean isRequired) { |
| CollectionTemplateExp asCollectionTemplateExp = QVTtemplateFactory.eINSTANCE.createCollectionTemplateExp(); |
| // asObjectTemplateExp.setName(PivotUtil.getName(asTemplateVariable)); |
| asCollectionTemplateExp.setType(asClass); |
| asCollectionTemplateExp.setReferredCollectionType((CollectionType)asClass); |
| asCollectionTemplateExp.setIsRequired(isRequired); |
| asCollectionTemplateExp.setBindsTo(asTemplateVariable); |
| return asCollectionTemplateExp; |
| } |
| |
| public @NonNull DomainPattern createDomainPattern(@NonNull TemplateExp asTemplateExp) { |
| DomainPattern asDomainPattern = QVTrelationFactory.eINSTANCE.createDomainPattern(); |
| asDomainPattern.setTemplateExpression(asTemplateExp); |
| return asDomainPattern; |
| } |
| |
| public @NonNull Key createKey(org.eclipse.ocl.pivot.@NonNull Class asClass, @NonNull Iterable<@NonNull Property> asProperties) { |
| Key asKey = QVTrelationFactory.eINSTANCE.createKey(); |
| asKey.setIdentifies(asClass); |
| Iterables.addAll(QVTrelationUtil.Internal.getOwnedPartsList(asKey), asProperties); |
| return asKey; |
| } |
| |
| public @NonNull ObjectTemplateExp createObjectTemplateExp(@NonNull TemplateVariable asTemplateVariable, org.eclipse.ocl.pivot.@NonNull Class asClass, boolean isRequired) { |
| ObjectTemplateExp asObjectTemplateExp = QVTtemplateFactory.eINSTANCE.createObjectTemplateExp(); |
| // asObjectTemplateExp.setName(PivotUtil.getName(asTemplateVariable)); |
| setType(asObjectTemplateExp, asClass,isRequired); |
| asObjectTemplateExp.setReferredClass(asClass); |
| asObjectTemplateExp.setBindsTo(asTemplateVariable); |
| return asObjectTemplateExp; |
| } |
| |
| public @NonNull PropertyTemplateItem createPropertyTemplateItem(@NonNull Property asProperty, @NonNull OCLExpression asExpression) { |
| PropertyTemplateItem asPropertyTemplateItem = QVTtemplateFactory.eINSTANCE.createPropertyTemplateItem(); |
| boolean isOpposite = asProperty.isIsImplicit(); |
| asPropertyTemplateItem.setIsOpposite(isOpposite); |
| asPropertyTemplateItem.setReferredProperty(isOpposite ? PivotUtil.getOpposite(asProperty) : asProperty); |
| asPropertyTemplateItem.setValue(asExpression); |
| return asPropertyTemplateItem; |
| } |
| |
| public @NonNull Relation createRelation(@NonNull String name, @NonNull Iterable<@NonNull RelationDomain> asRelationDomains) { |
| Relation asRelation = QVTrelationFactory.eINSTANCE.createRelation(); |
| asRelation.setName(name); |
| Iterables.addAll(QVTrelationUtil.Internal.getOwnedDomainsList(asRelation), asRelationDomains); |
| return asRelation; |
| } |
| |
| public @NonNull RelationCallExp createRelationCallExp(@NonNull Relation asRelation, @NonNull List<? extends @NonNull OCLExpression> asArguments) { |
| RelationCallExp asRelationCallExp = QVTrelationFactory.eINSTANCE.createRelationCallExp(); |
| asRelationCallExp.setReferredRelation(asRelation); |
| Iterables.addAll(QVTrelationUtil.Internal.getOwnedArgumentsList(asRelationCallExp), asArguments); |
| setType(asRelationCallExp, environmentFactory.getStandardLibrary().getBooleanType(), true);; |
| return asRelationCallExp; |
| } |
| |
| public @NonNull RelationDomain createRelationDomain(@NonNull TypedModel asTypedModel) { |
| RelationDomain asRelationDomain = QVTrelationFactory.eINSTANCE.createRelationDomain(); |
| asRelationDomain.setTypedModel(asTypedModel); |
| return asRelationDomain; |
| } |
| |
| public @NonNull RelationalTransformation createRelationalTransformation(@NonNull String name, @NonNull Iterable<@NonNull TypedModel> asTypedModels) { |
| StandardLibrary standardLibrary = environmentFactory.getStandardLibrary(); |
| RelationalTransformation asRelationalTransformation = QVTrelationFactory.eINSTANCE.createRelationalTransformation(); |
| asRelationalTransformation.setName(name); |
| Iterables.addAll(QVTrelationUtil.Internal.getModelParameterList(asRelationalTransformation), asTypedModels); |
| asRelationalTransformation.getSuperClasses().add(standardLibrary.getOclElementType()); |
| return asRelationalTransformation; |
| } |
| |
| public @NonNull SharedVariable createSharedVariable(@Nullable String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) { |
| SharedVariable asVariable = QVTrelationFactory.eINSTANCE.createSharedVariable(); |
| asVariable.setName(name); |
| asVariable.setIsImplicit(name == null); |
| setType(asVariable, asType, isRequired); |
| asVariable.setOwnedInit(asInitExpression); |
| return asVariable; |
| } |
| |
| public @NonNull TemplateVariable createTemplateVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) { |
| TemplateVariable asVariable = QVTrelationFactory.eINSTANCE.createTemplateVariable(); |
| asVariable.setName(name); |
| setType(asVariable, asType, isRequired); |
| asVariable.setOwnedInit(asInitExpression); |
| return asVariable; |
| } |
| |
| public @NonNull Variable createTraceClassVariable(@NonNull TraceHelper traceHelper) { |
| SharedVariable traceClassVariable; |
| traceClassVariable = QVTrelationFactory.eINSTANCE.createSharedVariable(); |
| traceClassVariable.setName(QVTrelationUtil.TRACE_CLASS_NAME); |
| traceClassVariable.setIsImplicit(true); |
| setType(traceClassVariable, traceHelper.getTraceElementClass(), true); // Use an ancestral QVTTrace type since derived type not yet synthesized |
| traceClassVariable.setOwnedInit(null); |
| return traceClassVariable; |
| } |
| |
| public @NonNull TypedModel createTraceTypedModel() { |
| TypedModel asTypedModel = QVTbaseFactory.eINSTANCE.createTypedModel(); |
| asTypedModel.setName(QVTrelationUtil.TRACE_TYPED_MODEL_NAME); |
| asTypedModel.setIsTrace(true); |
| return asTypedModel; |
| } |
| } |