blob: e202f881653b052c7f4935e412bb5b5e7d2a9689 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - 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:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*
* This copyright notice shows up in the generated Java code
*
*/
package org.eclipse.osbp.xtext.table.generator
import java.io.StringWriter
import java.io.Writer
import java.util.HashMap
import java.util.Map
import javax.inject.Inject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.emf.ecore.xmi.XMLResource
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl
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.LPackage
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute
import org.eclipse.osbp.dsl.semantic.entity.LBean
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceFactory
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropPriceStyle
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropQuantityStyle
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropStyle
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleFactory
import org.eclipse.osbp.utils.common.EntityUtils
import org.eclipse.osbp.xtext.table.TableDtoDatasource
import org.eclipse.osbp.xtext.table.TableGrid
import org.eclipse.osbp.xtext.table.TableModel
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.generator.IGenerator
import org.eclipse.xtext.naming.IQualifiedNameProvider
import static extension org.eclipse.osbp.infogrid.model.gridsource.util.Util.*
import javax.persistence.metamodel.ListAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LClass
/**
* Generates code from your model files on save.
*
* see http://www.eclipse.org/Xtext/documentation.html#TutorialCodeGeneration
*/
class TableGridSourceGenerator implements IGenerator {
@Inject extension IQualifiedNameProvider
@Inject extension TypeHelper
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
resource.toBinary(fsa)
}
def toBinary(Resource input, IFileSystemAccess fsa) {
val TableModel lModel = input.contents.get(0) as TableModel
lModel.packages.forEach [
val packageName = it.name
it.tables.forEach [
val tableName = it.name
if (it.tabletype instanceof TableGrid) {
generateXMI(it.tabletype as TableGrid, packageName, tableName, fsa);
}
]
]
}
def generateXMI(TableGrid grid, String packageName, String tableName, IFileSystemAccess fsa) {
val XMLResource outputRes = new XMLResourceImpl
val ds = grid.source
ds.id = packageName + "." + tableName + "Grid"
// set required inputs using the dto defined in the grid table
ds.rootTypeFQN = '''«(ds.dtoSource.eContainer as LPackage).name».«ds.dtoSource.name»'''
if (ds.properties !== null && ds.properties.length > 0) {
// set required properties
for (prop : ds.properties) {
prop.dotPath = prop.calcDotPath
// set source FQN for column permission checks
prop.sourceFQN = prop.path.field.eContainer.fullyQualifiedName.toString
// prepare dot path in styles
prop.style.prepare
}
} else {
var attributesMap = <String, String>newHashMap
var attributesTypeMap = <String, LScalarType>newHashMap
var attributesSourceMap = <String, String>newHashMap
var sourceFQN = ds.dtoSource.fullyQualifiedName.toString
for (attr : ds.dtoSource.attributes) {
// filtering out id, uuid, version, transient, CreateAt, CreateBy, UpdateAt and UpdateBy
if (ds.allowedAttribute(attr)) {
attr.fillAttributes(sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap)
}
}
if (ds.dtoSource.superType !== null) {
sourceFQN = ds.dtoSource.superType.fullyQualifiedName.toString
for (attr : ds.dtoSource.superType.attributes) {
// filtering out id, uuid, version, transient, CreateAt, CreateBy, UpdateAt and UpdateBy
if (ds.allowedAttribute(attr)) {
attr.fillAttributes(sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap)
}
}
}
for (attrKey : attributesMap.keySet){
var prop = CxGridSourceFactory.eINSTANCE.createCxGridProperty();
prop.dotPath = attributesMap.get(attrKey)
prop.style = attributesTypeMap.get(attrKey).propStyle
sourceFQN = attributesSourceMap.get(attrKey)
if (sourceFQN === null){
sourceFQN = ds.rootTypeFQN
}
prop.sourceFQN = sourceFQN
prop.editable = true
ds.properties.add(prop)
}
}
val copy = EcoreUtil.copy(ds)
outputRes.contents += copy
// create a writer
val Writer writer = new StringWriter
outputRes.save(writer, null)
fsa.generateFile(ds.id + ".gridsource_xmi", "xmi", writer.toString)
}
protected def boolean allowedAttribute(TableDtoDatasource ds, LDtoAbstractAttribute attr) {
var allowedAttr = true
var LAttribute attribute = attr
if (attr instanceof LDtoInheritedAttribute) {
attribute = (attr as LDtoInheritedAttribute).inheritedFeature
}
var wrappedType = ds.dtoSource.wrappedType
if (wrappedType instanceof LClass){
allowedAttr = (wrappedType as LClass).isNormalAttribute(attribute)
}
allowedAttr
}
def CxGridPropStyle getPropStyle(LScalarType type) {
if (type instanceof LDataType) {
if (type.date) {
return CxGridStyleFactory.eINSTANCE.createCxGridPropDateStyle()
} else if (type.asBlob) {
// TODO (JCD): Decision to make which style to provide for 'asBlob' types
return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle()
} else {
var jvmType = (type as LDataType).jvmTypeReference?.type
if (jvmType !== null) {
if (jvmType.string) {
return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle()
} else if (jvmType.boolean) {
return CxGridStyleFactory.eINSTANCE.createCxGridPropBooleanStyle()
} else if (jvmType.date) {
return CxGridStyleFactory.eINSTANCE.createCxGridPropDateStyle()
} else if (jvmType.number) {
return CxGridStyleFactory.eINSTANCE.createCxGridPropNumberStyle()
}
}
}
}
return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle()
}
def fillAttributes(LDtoAbstractAttribute attr, String sourceFQN, HashMap<String, String> attributesMap, HashMap<String, LScalarType> attributesTypeMap, HashMap<String, String> attributesSourceMap) {
var LAttribute attribute = attr
if (attr instanceof LDtoInheritedAttribute) {
attribute = (attr as LDtoInheritedAttribute).inheritedFeature
}
var type = attribute.type as LScalarType
recurseAttributesMap(sourceFQN, type, attribute, attributesMap, attributesTypeMap, attributesSourceMap)
}
def dispatch void prepare(CxGridPropStyle style) {
}
def dispatch void prepare(CxGridPropPriceStyle style) {
style.valuePropertyDotPath = style.valuePropertyPath.calcDotPath
style.currencyPropertyDotPath = style.currencyPropertyPath.calcDotPath
}
def dispatch void prepare(CxGridPropQuantityStyle style) {
style.valuePropertyDotPath = style.valuePropertyPath.calcDotPath
style.uomPropertyDotPath = style.uomPropertyPath.calcDotPath
}
def void recurseAttributesMap(String sourceFQN, LScalarType type, LAttribute attribute, Map<String, String> attributesMap, HashMap<String, LScalarType> attributesTypeMap, HashMap<String, String> attributesSourceMap) {
if (type !== null && type instanceof LBean) {
var bean = type as LBean
for (attr : bean.allAttributes) {
if (attr.type instanceof LBean) {
recurseAttributesMap(sourceFQN, attr.type, attribute, attributesMap, attributesTypeMap, attributesSourceMap)
} else {
attr.fillAttributeMaps(sourceFQN, attribute.name, attributesMap, attributesTypeMap, attributesSourceMap)
}
}
} else {
attribute.fillAttributeMaps(sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap)
}
}
def void fillAttributeMaps(LAttribute attr, String sourceFQN, Map<String, String> attributesMap, HashMap<String, LScalarType> attributesTypeMap, HashMap<String, String> attributesSourceMap){
attr.fillAttributeMaps(sourceFQN, null, attributesMap, attributesTypeMap, attributesSourceMap)
}
def void fillAttributeMaps(LAttribute attr, String sourceFQN, String attributeBeanName, Map<String, String> attributesMap, HashMap<String, LScalarType> attributesTypeMap, HashMap<String, String> attributesSourceMap){
var attrName = attr.name
if (attributeBeanName !== null) {
attrName = '''«attributeBeanName».«attrName»'''
}
attributesMap.put(attr.name, attrName)
attributesTypeMap.put(attr.name, attr.type)
attributesSourceMap.put(attr.name, sourceFQN)
}
}