| /** |
| * |
| * 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.autowirehelper.utils |
| |
| import java.util.List |
| import java.util.Map |
| import java.util.function.Function |
| import javax.inject.Inject |
| import org.apache.commons.lang.StringEscapeUtils |
| import org.eclipse.osbp.dsl.semantic.common.types.LDataType |
| import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue |
| import org.eclipse.osbp.dsl.semantic.common.types.LScalarType |
| import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute |
| 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.entity.LEntity |
| import org.eclipse.osbp.ecview.dsl.extensions.BindableTypeResolver |
| import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions.OperationInfo |
| import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper |
| import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot |
| import org.eclipse.osbp.ecview.semantic.uimodel.UiLayout |
| import org.eclipse.osbp.ecview.semantic.uimodel.UiModel |
| import org.eclipse.osbp.ecview.semantic.uimodel.UiView |
| import org.eclipse.osbp.ecview.semantic.uimodel.impl.UiViewImpl |
| import org.eclipse.osbp.runtime.common.annotations.CompareType |
| import org.eclipse.osbp.runtime.common.annotations.DomainDescription |
| import org.eclipse.osbp.runtime.common.annotations.DomainKey |
| import org.eclipse.osbp.runtime.common.annotations.FilterDepth |
| import org.eclipse.osbp.runtime.common.annotations.Properties |
| import org.eclipse.osbp.runtime.common.annotations.TargetEnumConstraints |
| import org.eclipse.osbp.utils.common.EntityUtils |
| import org.eclipse.xtext.common.types.JvmAnnotationAnnotationValue |
| import org.eclipse.xtext.common.types.JvmAnnotationReference |
| import org.eclipse.xtext.common.types.JvmDeclaredType |
| import org.eclipse.xtext.common.types.JvmEnumAnnotationValue |
| import org.eclipse.xtext.common.types.JvmField |
| import org.eclipse.xtext.common.types.JvmIntAnnotationValue |
| import org.eclipse.xtext.common.types.JvmStringAnnotationValue |
| import org.eclipse.xtext.common.types.JvmType |
| import org.eclipse.xtext.common.types.JvmTypeAnnotationValue |
| import org.eclipse.xtext.common.types.util.TypeReferences |
| import org.eclipse.xtext.naming.IQualifiedNameProvider |
| |
| class AutowireUtil { |
| @Inject extension IQualifiedNameProvider |
| @Inject extension TypeHelper |
| @Inject |
| private TypeReferences typeReferences; |
| |
| public def String generateId(UiLayout layout) { |
| val BindableTypeResolver resolver = new BindableTypeResolver |
| var resolvedType = resolver.resolveType(layout.autoWireSource) |
| var viewName = "" |
| |
| var parent = layout.eContainer |
| while (!(parent instanceof UiModel)) { |
| if (parent instanceof UiViewImpl) { |
| viewName = (parent as UiViewImpl).name |
| } |
| parent = parent.eContainer |
| } |
| var uimodel = parent as UiModel |
| return '''«uimodel.packageName»«IF viewName != null».«viewName»«ENDIF»«IF resolvedType != null».«resolvedType. |
| identifier»«ENDIF»''' |
| } |
| |
| public def UiView getUiView(UiLayout layout) { |
| var parent = layout.eContainer |
| while (!(parent instanceof UiViewImpl)) { |
| parent = parent.eContainer |
| } |
| if (parent instanceof UiViewImpl) { |
| return (parent as UiViewImpl) |
| } |
| } |
| |
| public def boolean isAttribute(JvmType type, String attribute, String filterName) { |
| var dto = EntityUtils.getDto(type) |
| if (dto != null) { |
| var attr = dto.attributes.findFirst[toName == attribute] |
| if (attr != null) { |
| var datatype = attr.toDatatype as LDataType |
| return datatype.name == filterName |
| } |
| } |
| return false |
| } |
| |
| /** |
| * Detects all the existing properties of the jvmtype corresponding attribute, the datatype of the attribute and references. |
| */ |
| public def List<Pair> toProperties(JvmDeclaredType type, String attributeName) { |
| val result = type.toFieldProperties.get(attributeName) |
| if (result != null) { |
| for (prop : result) { |
| |
| // unescape quotes like ¤ to avoid UTF-8 conflicts |
| prop.value = StringEscapeUtils.unescapeHtml(prop.value); |
| } |
| } |
| return if(result != null) result else newArrayList() |
| } |
| |
| /** |
| * Detects all the existing properties of the jvmtype corresponding reference and the referenced dto. |
| */ |
| public def Map<String, List<Pair>> toFieldProperties(JvmDeclaredType jvmType) { |
| val Map<String, List<Pair>> propMap = newHashMap() |
| jvmType.allFeatures.filter(typeof(JvmField)).forEach [ |
| val attrPropKey = '''«jvmType.qualifiedName».«it.simpleName»''' |
| val List<Pair> values = newArrayList() |
| propMap.put(attrPropKey, values) |
| it.annotations.filter [ e | |
| val result = e.annotation.identifier.equals(typeof(Properties).name) |
| return result |
| ].forEach [ |
| val JvmAnnotationReference ref = it; |
| ref.values.map[it as JvmAnnotationAnnotationValue].forEach [ av | |
| av.values.forEach [ |
| val keyAn = it.values.get(0) as JvmStringAnnotationValue |
| val valueAn = it.values.get(1) as JvmStringAnnotationValue |
| values.add(new Pair(keyAn.values.get(0), valueAn.values.get(0))) |
| ] |
| ] |
| ] |
| ] |
| |
| return propMap |
| } |
| |
| /** |
| * Returns the depth of the filter for BeanReferenceFields |
| */ |
| public def int toFilterDepth(JvmField field) { |
| val ref = field.annotations.findFirst [ e | |
| val result = e.annotation.identifier.equals(typeof(FilterDepth).name) |
| return result |
| ] |
| |
| if (ref === null) { |
| return 0 |
| } |
| |
| val JvmIntAnnotationValue depthVal = ref.values.get(0) as JvmIntAnnotationValue |
| return depthVal.values.get(0) |
| } |
| |
| /** |
| * Returns info about the TargetEnumConstraints annotation. |
| * |
| * usage: |
| * |
| val targets = toEnumReferenceConstraint(info.field, [ |
| return computer.loadClass(uiLayout?.eResource?.resourceSet, it.qualifiedName) |
| ]) |
| |
| * |
| * |
| */ |
| public def List<TargetEnumProps> toEnumReferenceConstraint(JvmField jvmField, |
| Function<JvmType, Class<?>> typeProvider) { |
| val List<TargetEnumProps> targets = newArrayList; |
| jvmField.annotations.filter [ e | |
| val result = e.annotation.identifier.equals(typeof(TargetEnumConstraints).name) |
| return result |
| ].forEach [ |
| val JvmAnnotationReference ref = it; |
| ref.values.map[it as JvmAnnotationAnnotationValue].forEach [ av | |
| av.values.forEach [ |
| val target = new TargetEnumProps |
| target.targetProperty = (it.values.get(0) as JvmStringAnnotationValue).values.get(0) |
| val enumClassJvmType = (it.values.get(1) as JvmTypeAnnotationValue).values.get(0) |
| target.enumClass = typeProvider.apply(enumClassJvmType.type) |
| |
| target.enumLiteral = (it.values.get(2) as JvmStringAnnotationValue).values.get(0) |
| target.compareType = CompareType.valueOf( |
| (it.values.get(3) as JvmEnumAnnotationValue).values.get(0).simpleName) |
| targets += target |
| ] |
| ] |
| ] |
| |
| return targets |
| } |
| |
| /** |
| * Detects all the existing properties of the jvmtype corresponding datatype of the attribute. |
| */ |
| public def LDataType toDataType(JvmType type, String attributeName) { |
| var dto = EntityUtils.getDto(type) |
| if (dto != null) { |
| var attr = dto.attributes.findFirst[toName == attributeName] |
| if (attr != null) { |
| var dataType = attr.toDatatype |
| if (dataType instanceof LDataType) { |
| return (attr.toDatatype as LDataType) |
| } |
| } |
| } |
| return null |
| } |
| |
| /** |
| * Provides the datatype of the corresponding attribute. |
| */ |
| public def List<LKeyAndValue> toDataTypeProperties(JvmType type, String attributeName) { |
| var dataType = type.toDataType(attributeName) |
| if (dataType != null) { |
| return dataType.properties |
| } |
| return newArrayList() |
| } |
| |
| def String toName(LDtoFeature feature) { |
| if (feature instanceof LDtoInheritedAttribute) { |
| return feature.inheritedFeature.name |
| } else if (feature instanceof LDtoInheritedReference) { |
| return feature.inheritedFeature.name |
| } else { |
| return feature.name |
| } |
| } |
| |
| def LScalarType toDatatype(LDtoAbstractAttribute att) { |
| if (att instanceof LDtoInheritedAttribute) { |
| return att.inheritedFeature.type |
| } else { |
| return att.type |
| } |
| } |
| |
| def boolean isBlob(JvmType type, String attribute) { |
| var dto = EntityUtils.getDto(type) |
| var attrs = dto.attributes.filter[name == attribute] |
| for (attr : attrs) { |
| var datatype = attr.type as LDataType |
| println(datatype) |
| return datatype.asBlob |
| } |
| return false |
| } |
| |
| def String getEntityName(UiBeanSlot uiBeanSlot) { |
| val entity = EntityUtils.getEntityFromDto(uiBeanSlot.jvmType.type) as LEntity |
| var String eName |
| if (entity == null) { |
| if (uiBeanSlot.jvmType.type == null) { |
| eName = "" |
| } else if (uiBeanSlot.jvmType.type != null) { |
| |
| // Temporary solution till final solution found. |
| // eName = uiBeanSlot.jvmType.type.toString |
| eName = "" |
| } |
| } else { |
| eName = entity.name |
| } |
| return eName |
| } |
| |
| // Helper Methods |
| def boolean isClass(JvmType type) { |
| if (typeReferences.is(type, Class)) { |
| return true; |
| } |
| return false; |
| } |
| |
| // Helper Methods |
| def boolean isByteArray(JvmType type) { |
| if (typeReferences.is(type, typeof(byte[]))) { |
| return true; |
| } |
| return false; |
| } |
| |
| def boolean isAllowed(JvmType type, JvmType beanType, OperationInfo info) { |
| if (type.numberWithDigits) { |
| return true |
| } else if (type.numberWithoutDigits) { |
| return true |
| } else if (type.string) { |
| return true |
| } else if (type.date) { |
| return true |
| } else if (type.byteArray) { |
| return true |
| } else if (type.boolean) { |
| return true |
| } else if (type.enum) { |
| return true |
| } else if (info.domainReference) { |
| switch (type) { |
| JvmDeclaredType: |
| if ((type as JvmDeclaredType).isAnnotationOf(typeof(DomainKey)) || |
| (type as JvmDeclaredType).isAnnotationOf(typeof(DomainDescription))) { |
| return true |
| } |
| } |
| return false |
| } else if (info.field != null && info.field.collection) { |
| return true |
| } |
| return false |
| } |
| |
| private def boolean isAnnotationOf(JvmDeclaredType type, Class<?> clazz) { |
| for (member : type.members) { |
| for (annotation : member.annotations) { |
| if (annotation.annotation.identifier.equals(clazz.canonicalName)) { |
| return true |
| } |
| } |
| } |
| for (superType : type.superTypes) { |
| if (superType.type instanceof JvmDeclaredType) { |
| return isAnnotationOf((superType.type as JvmDeclaredType), clazz) |
| } |
| } |
| return false |
| } |
| |
| static class Pair { |
| public String key |
| public String value |
| |
| new(String key, String value) { |
| this.key = key; |
| this.value = value; |
| } |
| |
| } |
| |
| public static class TargetEnumProps { |
| /** |
| * The property of the target type of the reference that must match the enum |
| * literal. |
| * |
| * @return the string |
| */ |
| String targetProperty; |
| |
| /** |
| * The enum class used to get the enum literal. |
| * |
| * @return the class |
| */ |
| Class<?> enumClass; |
| |
| /** |
| * The name of the enum literal that is used as a filter. |
| * |
| * @return the string |
| */ |
| String enumLiteral; |
| |
| /** |
| * The compareType used to execute the filter. |
| * |
| * @return the compare type |
| */ |
| CompareType compareType = CompareType.EQUALS; |
| } |
| |
| } |