blob: 27f9213bd77cb4d010663d9b4d166a70ce14eacb [file] [log] [blame]
/**
* 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
}
}