| /** |
| * |
| * 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) |
| } |
| |
| |
| } |