| /** |
| * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Florian Pirchner - Initial implementation |
| */ |
| package org.eclipse.osbp.dsl.services.xtext.extensions |
| |
| import com.google.inject.Inject |
| import java.util.List |
| import org.eclipse.emf.ecore.EObject |
| import org.eclipse.xtext.common.types.JvmTypeReference |
| import org.eclipse.xtext.common.types.util.TypeReferences |
| import org.eclipse.xtext.naming.IQualifiedNameProvider |
| import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder |
| import org.eclipse.osbp.dsl.semantic.common.helper.Bounds |
| import org.eclipse.osbp.dsl.semantic.common.types.LAttribute |
| import org.eclipse.osbp.dsl.semantic.common.types.LFeature |
| import org.eclipse.osbp.dsl.semantic.common.types.LReference |
| import org.eclipse.osbp.dsl.semantic.common.types.LType |
| import org.eclipse.osbp.dsl.semantic.dto.LDto |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoAttribute |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedReference |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoOperation |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoReference |
| import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute |
| import org.eclipse.osbp.dsl.semantic.entity.LBeanReference |
| import org.eclipse.osbp.dsl.semantic.entity.LEntity |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityReference |
| import org.eclipse.osbp.dsl.semantic.service.LCardinality |
| import org.eclipse.osbp.dsl.semantic.service.LInjectedService |
| |
| class ModelExtensions extends org.eclipse.osbp.dsl.common.xtext.extensions.ModelExtensions { |
| |
| @Inject extension IQualifiedNameProvider |
| @Inject extension JvmTypesBuilder |
| @Inject extension MethodNamingExtensions |
| |
| @Inject TypeReferences references; |
| |
| def dispatch JvmTypeReference toTypeReference(LDtoAbstractReference prop) { |
| var JvmTypeReference jvmTypeRef = prop.toDtoTypeParameterReference |
| return jvmTypeRef |
| } |
| |
| def dispatch JvmTypeReference toTypeReference(LDtoAbstractAttribute prop) { |
| var JvmTypeReference jvmTypeRef = prop.toDtoTypeParameterReference |
| return jvmTypeRef |
| } |
| |
| /** |
| * Creates a type references with respect to inherited features |
| */ |
| def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoAbstractReference prop) { |
| |
| // prop.type is instanceof DTO |
| return prop.type?.toTypeReference.cloneWithProxies |
| } |
| |
| /** |
| * Creates a type references with respect to inherited features |
| */ |
| def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoAbstractAttribute prop) { |
| |
| // prop.type is instanceof LDataType |
| return prop.type?.toTypeReference.cloneWithProxies |
| } |
| |
| /** |
| * Creates a type references with respect to inherited features |
| */ |
| def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoInheritedAttribute prop) { |
| |
| if (prop.type != null) { |
| |
| // if the type is a different one, then use the type of the property |
| // needs to be mapped by a custom mapper in dsl |
| return prop.type?.toTypeReference.cloneWithProxies |
| } |
| |
| // creates a type reference for the inherited LDataType |
| return prop.inheritedFeature?.toTypeReference.cloneWithProxies |
| } |
| |
| /** |
| * Creates a type references with respect to inherited features |
| */ |
| def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoInheritedReference prop) { |
| |
| // for inherited references, the dto type is specified -> So use it |
| return prop.type?.toTypeReference.cloneWithProxies |
| } |
| |
| /** |
| * Creates a type reference with respect to multiplicity |
| */ |
| def JvmTypeReference toDtoTypeParameterReferenceWithMultiplicity(LDtoFeature prop) { |
| var ref = prop.toDtoTypeParameterReference |
| if (ref != null && prop.bounds.toMany) { |
| ref = references.getTypeForName(typeof(List), prop, ref) |
| } |
| return ref |
| } |
| |
| /** |
| * Creates a type reference with respect to multiplicity |
| */ |
| def JvmTypeReference toRawTypeReferenceWithMultiplicity(LDtoFeature prop) { |
| var ref = prop.toRawTypeRefernce; |
| if (prop.bounds.toMany) { |
| ref = references.getTypeForName(typeof(List), prop, ref) |
| } |
| return ref |
| } |
| |
| def dispatch isCascading(LDtoOperation prop) { |
| false |
| } |
| |
| def LDtoAbstractReference getResolvedOpposite(LDtoReference prop) { |
| |
| // For a toMany that has already an opposite, return it. |
| // Otherwise search in the referenced type for the property with the owner type. |
| if (prop.opposite != null) { |
| return prop.opposite |
| } else if (prop.type instanceof LDto) { |
| val LDto ref = prop.type as LDto |
| ref.references.findFirst[it.opposite == prop] |
| } |
| } |
| |
| /** |
| * Returns true, if toCheck can be cast to superType |
| */ |
| def boolean isCastable(LDto toCheck, LDto superType) { |
| val String toCheckFqn = toCheck.fullyQualifiedName.toString |
| val String superTypeFqn = superType.fullyQualifiedName.toString |
| |
| if (toCheckFqn.equals(superTypeFqn)) { |
| return true |
| } else { |
| val LDto toCheckSuperType = toCheck.getSuperType |
| if (toCheckSuperType != null) { |
| return toCheckSuperType.isCastable(superType) |
| } else { |
| return false; |
| } |
| } |
| } |
| |
| def dispatch inherited(LFeature prop) { |
| return false |
| } |
| |
| def dispatch inherited(LDtoInheritedReference prop) { |
| return true |
| } |
| |
| def dispatch inherited(LDtoInheritedAttribute prop) { |
| return true |
| } |
| |
| /** |
| * The binary <code>+</code> operator that concatenates two strings. |
| * |
| * @param a |
| * a string. |
| * @param b |
| * another string. |
| * @return <code>a + b</code> |
| */ |
| def static String operator_plus(String a, String b) { |
| if (a == null || b == null) |
| return "" |
| |
| return a + b; |
| } |
| |
| def dispatch String toTypeName(LDtoAttribute prop) { |
| prop.type.name |
| } |
| |
| def dispatch String toTypeName(LDtoInheritedAttribute prop) { |
| if (prop.type != null) { |
| prop.type.name |
| } else { |
| prop.inheritedFeature.^type.name |
| } |
| } |
| |
| def dispatch String toTypeName(LDtoReference prop) { |
| prop.type?.name |
| } |
| |
| def dispatch String toTypeName(LDtoInheritedReference prop) { |
| prop.type?.name |
| } |
| |
| def dispatch LType toRawType(LFeature prop) { |
| throw new IllegalStateException("not a valid call") |
| } |
| |
| def dispatch LType toRawType(LDtoAttribute prop) { |
| prop.type |
| } |
| |
| def dispatch LType toRawType(LDtoInheritedAttribute prop) { |
| prop.inheritedFeature?.type |
| } |
| |
| def dispatch LType toRawType(LDtoReference prop) { |
| prop.type |
| } |
| |
| def dispatch LType toRawType(LDtoInheritedReference prop) { |
| prop.inheritedFeature?.toRawType |
| } |
| |
| def dispatch LType toRawType(LEntityReference prop) { |
| prop.type as LType |
| } |
| |
| def dispatch LType toRawType(LEntityAttribute prop) { |
| prop.type as LType |
| } |
| |
| def dispatch LType toRawType(LBeanReference prop) { |
| prop.type as LType |
| } |
| |
| def dispatch LType toRawType(LBeanAttribute prop) { |
| prop.type as LType |
| } |
| |
| def toRawTypeRefernce(LDtoFeature prop) { |
| prop.toRawType?.toTypeReference |
| } |
| |
| def String toRawTypeName(LDtoFeature prop) { |
| prop.toRawType?.name |
| } |
| |
| def dispatch LReference opposite(LDtoFeature prop) { |
| null |
| } |
| |
| def dispatch LReference opposite(LDtoReference prop) { |
| return prop.opposite |
| } |
| |
| def dispatch LReference opposite(LDtoInheritedReference prop) { |
| if (prop.inherited && prop.inheritedFeature != null) { |
| return prop.inheritedFeature.opposite |
| } else { |
| return null |
| } |
| } |
| |
| def dispatch LReference opposite(LEntityReference prop) { |
| prop.opposite as LReference |
| } |
| |
| def dispatch LReference opposite(LBeanReference prop) { |
| prop.opposite as LReference |
| } |
| |
| def dispatch Bounds getBounds(LDtoFeature prop) { |
| if (prop.inherited) { |
| return Bounds.createFor(prop.inheritedFeature); |
| } else { |
| return Bounds.createFor(prop); |
| } |
| } |
| |
| def dispatch String toName(LDtoFeature feature) { |
| if(feature == null || !feature.inherited && feature.name == null) return "" |
| if (feature.inherited) { |
| return feature.inheritedFeature?.toName |
| } |
| return feature.name.replace("^", "") |
| } |
| |
| def dispatch String toName(LDto dto) { |
| if (dto == null || dto.name == null) { |
| return "" |
| } |
| return dto.name.replace("^", "") |
| } |
| |
| // def dispatch String internalToName(LFeature prop) { |
| // return prop.name; |
| // } |
| // |
| // def dispatch String internalToName(LDtoFeature prop) { |
| // if (prop.inherited) { |
| // return prop.inheritedFeature?.name; |
| // } else { |
| // return prop.name; |
| // } |
| // } |
| def dispatch LReference inheritedFeature(LDtoFeature prop) { |
| return null |
| } |
| |
| def dispatch LReference inheritedFeature(LDtoInheritedReference prop) { |
| return prop.inheritedFeature |
| } |
| |
| def dispatch LAttribute inheritedFeature(LDtoInheritedAttribute prop) { |
| return prop.inheritedFeature |
| } |
| |
| override isToMany(LFeature prop) { |
| if (prop == null) { |
| return false |
| } |
| return internalIsToMany(prop); |
| } |
| |
| def dispatch boolean isTransient(EObject context) { |
| false |
| } |
| |
| def dispatch boolean isTransient(LDtoAttribute context) { |
| context.transient |
| } |
| |
| def dispatch boolean internalIsToMany(LFeature prop) { |
| return prop.bounds.toMany; |
| } |
| |
| def dispatch boolean internalIsToMany(LDtoFeature prop) { |
| if (prop.inherited && prop.inheritedFeature != null) { |
| return prop.inheritedFeature.internalIsToMany |
| } else { |
| return prop.bounds.toMany; |
| } |
| } |
| |
| def dispatch boolean isCascading(LDtoAbstractReference prop) { |
| if (prop.inherited && prop.inheritedFeature != null) { |
| return prop.inheritedFeature.cascading |
| } else { |
| return prop.cascading; |
| } |
| } |
| |
| def dispatch boolean isCascading(LDtoAbstractAttribute prop) { |
| if (prop.inherited && prop.inheritedFeature != null) { |
| return prop.inheritedFeature.cascading |
| } else { |
| return prop.cascading; |
| } |
| } |
| |
| def isCrossReference(LDtoFeature prop) { |
| return prop instanceof LReference && !prop.cascading |
| } |
| |
| // def dispatch boolean shouldUseCrossReference(LDtoFeature prop) { |
| // |
| // // if (prop.crossReference) { |
| // // if (prop.inherited && prop.inheritedFeature != null) { |
| // // return prop.inheritedFeature.shouldUseCrossReference |
| // // } else { |
| // // return true |
| // // } |
| // // } |
| // return false |
| // } |
| // |
| // def dispatch boolean shouldUseCrossReference(LEntityReference prop) { |
| // if (prop.cascading) { |
| // return false |
| // } |
| // |
| // if (prop.opposite == null) { |
| // return true |
| // } |
| // |
| // if (prop.opposite.cascading) { |
| // return false |
| // } |
| // return true |
| // } |
| def isMany(LInjectedService service) { |
| return service.cardinality == LCardinality::ZERO_TO_MANY || service.cardinality == LCardinality::ONE_TO_MANY |
| } |
| |
| def boolean basedOnEntity(LDto dto) { |
| dto.wrappedType != null && dto.wrappedType instanceof LEntity |
| } |
| |
| def Iterable<LDtoAbstractAttribute> collectAllAttributes(LDto dto) { |
| return dto.allFeatures.filter[it instanceof LDtoAbstractAttribute].map[it as LDtoAbstractAttribute] |
| } |
| |
| def LAttribute idAttribute(LDto dto) { |
| for (LDtoAbstractAttribute prop : dto.collectAllAttributes) { |
| if (prop.inherited && prop.inheritedFeature != null) { |
| val LAttribute attribute = prop.inheritedFeature as LAttribute |
| if (attribute.id || attribute.uuid) { |
| return attribute |
| } |
| } else { |
| if (prop.id || prop.uuid) { |
| return prop |
| } |
| } |
| } |
| } |
| |
| def LEntity wrappedEntity(LDto dto) { |
| if (dto.basedOnEntity) { |
| return dto.wrappedType as LEntity |
| } |
| return null |
| } |
| |
| def String wrappedEntityName(LDto dto) { |
| val entity = dto.wrappedEntity |
| if (entity != null) { |
| return entity.name |
| } |
| return null |
| } |
| } |