blob: bd27a86836b04e62a3d982d36b6b9e36123c3c82 [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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.dsl.entity.xtext.generator
import com.google.inject.Inject
import java.util.Collections
import java.util.HashSet
import java.util.List
import java.util.Set
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.naming.IQualifiedNameConverter
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.resource.IResourceDescriptions
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.common.types.LDateType
import org.eclipse.osbp.dsl.semantic.common.types.LEnum
import org.eclipse.osbp.dsl.semantic.common.types.LImport
import org.eclipse.osbp.dsl.semantic.common.types.LReference
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage
import org.eclipse.osbp.dsl.semantic.entity.LBean
import org.eclipse.osbp.dsl.semantic.entity.LBeanFeature
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.LEntityFeature
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
/**
* This generator automatically creates a generic .dtos-file from a given entity model.
* Imports, datatype declarations, enums and comments are carried over to the .dtos file,
* while bean and entity declarations are translated to DTO declarations with the
* appropriate inheritance information. Attributes and references are defined as inherited
* in this default conversion.
*/
class DtosFileGenerator {
@Inject extension JvmTypesBuilder
@Inject extension ModelExtensions
@Inject extension IQualifiedNameConverter
@Inject
private ResourceDescriptionsProvider provider;
IResourceDescriptions descriptions
def getContent(LTypedPackage pkg) {
descriptions = provider.getResourceDescriptions(pkg.eResource)
return pkg.doGetContent
}
def doGetContent(LTypedPackage pkg) '''
«pkg.toDocu»
package «pkg.toDtoPackageName» {
/* Imports the required artifacts */
«pkg.toImports»
«FOR LDataType lDatatype : pkg.datatypes»
«lDatatype.toDocu»
«lDatatype.toDataType»
«ENDFOR»
«FOR LEntity lEntity : pkg.entities»
«lEntity.toDocu»
«lEntity.toEntityDeclaration»
«FOR LEntityFeature feature : lEntity.features.filter[
(it instanceof LAttribute && !(it as LAttribute).derived) || (it instanceof LReference)]»
«feature.toFeature»
«ENDFOR»
«FOR LEntityFeature feature : lEntity.features.filter[(it instanceof LAttribute && (it as LAttribute).derived)]»
«(feature as LAttribute).toDerivedAttribute»
«ENDFOR»
}
«ENDFOR»
«FOR LBean lBean : pkg.beans»
«lBean.toDocu»
«lBean.toBeanDeclaration»
«FOR LBeanFeature feature : lBean.features.filter[
(it instanceof LAttribute && !(it as LAttribute).derived) || (it instanceof LReference)]»
«feature.toFeature»
«ENDFOR»
}
«ENDFOR»
«FOR LEnum lEnum : pkg.enums»
enum «lEnum.name» {
«lEnum.toLiterals»
}
«ENDFOR»
}
'''
def toEntityDeclaration(LEntity lEntity) {
return '''
«IF lEntity.abstract»abstract «ENDIF»autoDto «lEntity.name»Dto «IF lEntity.superType != null»extends «lEntity.
superType.name»Dto «ENDIF»wraps «lEntity.name» {
'''
}
def String toImports(LTypedPackage pkg) {
val Set<String> imports = new HashSet()
for (LImport lImport : pkg.imports) {
imports += lImport.importedNamespace.findProper
}
for (EObject element : pkg.eAllContents.toIterable) {
switch (element) {
LEntity: {
val LTypedPackage lPkg = element.eContainer as LTypedPackage;
imports += lPkg.name + ".*"
imports += lPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
if (element.superType != null) {
val LTypedPackage lSuperPkg = element.superType.eContainer as LTypedPackage;
imports += lSuperPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
}
}
LBean: {
val LTypedPackage lPkg = element.eContainer as LTypedPackage;
imports += lPkg.name + ".*"
imports += lPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
if (element.superType != null) {
val LTypedPackage lSuperPkg = element.superType.eContainer as LTypedPackage;
imports += lSuperPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
}
}
LEnum: {
val LTypedPackage lPkg = element.eContainer as LTypedPackage;
imports += lPkg.name + ".*"
imports += lPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
}
LEntityReference: {
val LEntity lEntity = element.type
val LTypedPackage lPkg = lEntity.eContainer as LTypedPackage;
imports += lPkg.name + ".*"
imports += lPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
}
LEntityAttribute: {
if (element.type instanceof LBean) {
val LBean lBean = element.type as LBean
val LTypedPackage lPkg = lBean.eContainer as LTypedPackage;
imports += lPkg.name + ".*"
imports += lPkg.toDtoPackageName + ".*"
imports += lPkg.toDtoPackageName + ".mapper.*"
}
}
}
}
imports.remove(null)
val List<String> sortable = newArrayList(imports)
Collections.sort(sortable)
val StringBuilder b = new StringBuilder
for (String imported : sortable) {
b.append("import ")
b.append(imported)
b.append(";")
b.append("\n")
}
return b.toString
}
def findProper(String value) {
val fqn = value.toQualifiedName
// is already a wildcard import
if (value.endsWith(".*")) {
return value
}
var expected = fqn;
while (expected != QualifiedName.EMPTY) {
if (isPackage(expected)) {
return expected.toString + ".*"
} else {
expected = expected.skipLast(1)
}
}
return null
}
def boolean isPackage(QualifiedName fqn) {
val result = descriptions.getExportedObjects(OSBPTypesPackage.Literals.LTYPED_PACKAGE, fqn, false)
return !result.empty
}
def toBeanDeclaration(LBean lBean) {
return '''
autoDto «lBean.name»Dto «IF lBean.superType != null»extends «lBean.superType.name»Dto «ENDIF»wraps «lBean.name» {
'''
}
def toDocu(EObject element) {
var docu = element.documentation
if (!docu.nullOrEmpty) {
var docus = docu.split('\n')
if (docus.length > 1) {
return '''
/**
«FOR line : docus»
«" * "»«line»
«ENDFOR»
*/'''.toString
} else if (docus.length == 1) {
return '''/** «docu» */'''.toString
}
}
return ""
}
def dispatch toFeature(LAttribute att) '''
«att.toDocu»
inherit var «att.name»;
'''
def dispatch toFeature(LReference att) '''
«att.toDocu»
inherit ref «att.name»;
'''
def dispatch toFeature(LEntityReference att) '''
«att.toDocu»
inherit ref «att.name» mapto «att.type.name»Dto;
'''
def dispatch toFeature(LBeanReference att) '''
«att.toDocu»
inherit ref «att.name» mapto «att.type.name»Dto;
'''
def toDerivedAttribute(LAttribute att) '''
«att.toDocu»
derived «IF att.domainDescription»domainDescription «ENDIF» «att.type.name» «att.name» «att.blockExpression»
'''
def toLiterals(LEnum lEnum) {
var result = new StringBuilder
for (lit : lEnum.literals) {
result.append(lit.name);
result.append(", ");
}
return result.substring(0, result.length - 2)
}
def toDataType(LDataType lDatatype) {
'''
datatype «lDatatype.name» «IF lDatatype.date»dateType «IF lDatatype.dateType == LDateType.DATE»date«ELSEIF lDatatype.
dateType == LDateType.TIME»time«ELSE»timestamp«ENDIF»«ELSEIF lDatatype.asBlob»as blob«ELSE»jvmType «lDatatype.
jvmTypeReference.type.qualifiedName»«IF lDatatype.asPrimitive» as primitive«ENDIF»«ENDIF»;
'''
}
def String toPackageName(LTypedPackage pkg) {
pkg.name + ".dtos"
}
def Iterable<LDataType> datatypes(LTypedPackage pkg) {
pkg.types.filter[it instanceof LDataType].map[it as LDataType];
}
def Iterable<LEntity> entities(LTypedPackage pkg) {
pkg.types.filter[it instanceof LEntity].map[it as LEntity];
}
def Iterable<LBean> beans(LTypedPackage pkg) {
pkg.types.filter[it instanceof LBean].map[it as LBean];
}
def Iterable<LEnum> enums(LTypedPackage pkg) {
pkg.types.filter[it instanceof LEnum].map[it as LEnum];
}
def String blockExpression(LAttribute attribute) {
val resource = attribute.eResource as XtextResource
return resource.serializer.serialize(attribute.derivedGetterExpression)
}
}