blob: cd3d71abdfb9cc476e96c906fe0eed518e781764 [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.autowirehelper
import com.google.inject.Inject
import java.util.ArrayList
import java.util.Collection
import java.util.LinkedList
import java.util.List
import java.util.Map
import java.util.Set
import java.util.Stack
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.InternalEObject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.osbp.autowirehelper.utils.AutowireUtil
import org.eclipse.osbp.autowirehelper.utils.AutowireUtil.Pair
import org.eclipse.osbp.dsl.common.datatypes.IDto
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingUpdateStrategy
import org.eclipse.osbp.ecview.core.common.model.binding.YDetailValueBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment
import org.eclipse.osbp.ecview.core.common.model.core.YAlignmentContainer
import org.eclipse.osbp.ecview.core.common.model.core.YAuthorizationable
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlotListBindingEndpoint
import org.eclipse.osbp.ecview.core.common.model.core.YDetailBeanSlot
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable
import org.eclipse.osbp.ecview.core.common.model.core.YLayout
import org.eclipse.osbp.ecview.core.common.model.core.YView
import org.eclipse.osbp.ecview.core.^extension.model.^extension.util.SimpleExtensionModelFactory
import org.eclipse.osbp.ecview.dsl.autowire.IAutowireDelegate
import org.eclipse.osbp.ecview.dsl.derivedstate.UiModelDerivedStateComputerx
import org.eclipse.osbp.ecview.dsl.extensions.BeanHelper
import org.eclipse.osbp.ecview.dsl.extensions.BindableTypeResolver
import org.eclipse.osbp.ecview.dsl.extensions.BindingInfoHelper
import org.eclipse.osbp.ecview.dsl.extensions.BindingInfoHelper.BindingInfo
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions.OperationInfo
import org.eclipse.osbp.ecview.dsl.extensions.SuperTypeCollector
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper
import org.eclipse.osbp.ecview.^extension.api.ILayoutingStrategy
import org.eclipse.osbp.ecview.^extension.model.YColumnInfo
import org.eclipse.osbp.ecview.^extension.model.YECviewFactory
import org.eclipse.osbp.ecview.^extension.model.YStrategyLayout
import org.eclipse.osbp.ecview.^extension.model.YSubTypeSuspect
import org.eclipse.osbp.ecview.^extension.model.YSuspect
import org.eclipse.osbp.ecview.^extension.model.YTypedCompoundSuspect
import org.eclipse.osbp.ecview.^extension.model.YTypedSuspect
import org.eclipse.osbp.ecview.^extension.model.visibility.YVisibilityFactory
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot
import org.eclipse.osbp.ecview.semantic.uimodel.UiBindingEndpointAssignment
import org.eclipse.osbp.ecview.semantic.uimodel.UiEmbeddable
import org.eclipse.osbp.ecview.semantic.uimodel.UiHorizontalLayout
import org.eclipse.osbp.ecview.semantic.uimodel.UiLayout
import org.eclipse.osbp.mobile.vaadin.ecview.model.VMVerticalComponentGroup
import org.eclipse.osbp.mobile.vaadin.ecview.model.VaadinMobileFactory
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.OnKanbanCard
import org.eclipse.osbp.runtime.common.annotations.UniqueEntry
import org.eclipse.osbp.runtime.common.metric.TimeLogger
import org.eclipse.osbp.utils.functionnormalizer.api.FunctionTypingAPI
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference
import org.eclipse.xtext.common.types.JvmPrimitiveType
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.TypesFactory
import org.eclipse.xtext.common.types.TypesPackage
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.resource.IReferenceDescription
import org.eclipse.xtext.ui.editor.findrefs.IReferenceFinder
import org.eclipse.xtext.util.IAcceptor
import org.eclipse.xtext.util.concurrent.IUnitOfWork
import org.eclipse.osbp.runtime.common.layouting.IPropertyConstants
@SuppressWarnings("restriction")
class AutowireHelper implements IAutowireDelegate {
@Inject extension TypeHelper
@Inject extension AutowireUtil
@Inject extension IQualifiedNameProvider
@Inject BindingInfoHelper bindingInfoHelper;
@Inject
private IReferenceFinder referenceFinder;
private VaadinMobileFactory vFactory = VaadinMobileFactory.eINSTANCE
UiModelDerivedStateComputerx computer
boolean mobile
YLayout yLayout
UiLayout uiLayout
Layouter layouter
JvmDeclaredType beanType
final SimpleExtensionModelFactory factory = new SimpleExtensionModelFactory
YView yView
YBeanSlot yMainBeanslot
override autowire(UiLayout uiLayout, UiModelDerivedStateComputerx computer, boolean mobile) {
if (!uiLayout.autowire) {
return
}
this.computer = computer;
this.mobile = mobile;
this.uiLayout = uiLayout;
this.yLayout = computer.associatedUi(uiLayout)
this.yView = yLayout.view
this.yMainBeanslot = getBeanSlot(uiLayout)
switch (uiLayout) {
UiHorizontalLayout: {
layouter = if(!mobile) new StrategyLayoutLayouter else new MobileLayouter
layouter.setup(uiLayout, yLayout)
}
default:
return
}
val BindableTypeResolver resolver = new BindableTypeResolver
var resolvedType = resolver.resolveType(uiLayout.autoWireSource)
if (resolvedType instanceof JvmDeclaredType) {
beanType = resolvedType as JvmDeclaredType
// Gets the operation infos for the given type in form of a map
val opInfoMap = OperationExtensions.getOperationInfos(beanType)
// operation info map sorted in a list
val sortedOpInfoMapList = createSortedMapList(opInfoMap)
// creates the a suspect structure based on the operation infos
sortedOpInfoMapList.createSuspectStructure(beanType, mobile, null)
}
}
/**
* Finds all sub types of the beanType
*/
def findSubTypes(JvmType dtoType, Resource resource) {
val Set<URI> result = newHashSet()
val Set<URI> jvmTypeURIs = newHashSet()
jvmTypeURIs += EcoreUtil.getURI(dtoType)
val IAcceptor<IReferenceDescription> acceptor = [
val IReferenceDescription desc = it
if (desc.EReference === TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE) {
if (sourceEObjectUri.fragment.endsWith("/@superTypes.0")) {
val URI uri = desc.sourceEObjectUri;
result += URI.createURI(uri.toString.replace("/@superTypes.0", ""))
}
}
]
referenceFinder.findAllReferences(jvmTypeURIs, new LocalResourceAccess(resource.resourceSet), acceptor, null)
result
}
def YBeanSlot getBeanSlot(UiLayout uiLayout) {
var autoWireSourceTemp = uiLayout.autoWireSource
if (autoWireSourceTemp instanceof UiBindingEndpointAssignment) {
var alias = (autoWireSourceTemp as UiBindingEndpointAssignment).typedBindableAlias
if (alias instanceof UiBeanSlot) {
return computer.associatedUi(alias as UiBeanSlot)
}
}
return null
}
def createSuspectStructure(JvmDeclaredType type, boolean mobile, YTypedCompoundSuspect parentSuspect) {
// Gets the operation infos for the given type in form of a map
val opInfoMap = OperationExtensions.getOperationInfos(type)
// operation info map sorted in a list
val sortedOpInfoMapList = createSortedMapList(opInfoMap)
sortedOpInfoMapList.createSuspectStructure(type, mobile, parentSuspect)
}
def createSuspectStructure(LinkedList<Map<String, OperationInfo>> sortedOpInfoMapList, JvmDeclaredType dtoType,
boolean mobile, YTypedCompoundSuspect parentSuspect) {
if (!dtoType.isEnum) {
sortedOpInfoMapList.forEach [
it.createSuspectStructure(dtoType, mobile, parentSuspect)
]
}
// lets create a new suspect in form of a tree to add the sub types to it
val subTypeURIs = findSubTypes(dtoType, uiLayout.eResource)
if (!subTypeURIs.empty) {
val subtypeRootSuspect = YECviewFactory.eINSTANCE.createYSubTypeBaseSuspect
subtypeRootSuspect.tags += ILayoutingStrategy.TAG__SUBTYPES_ROOT
// TODO load the class
subtypeRootSuspect.typeQualifiedName = dtoType.qualifiedName
layouter.add(subtypeRootSuspect)
layouter.pushHierarchy(subtypeRootSuspect)
}
subTypeURIs.forEach [
val JvmDeclaredType subDtoJvmType = uiLayout.eResource.resourceSet.getEObject(it, true) as JvmDeclaredType
subDtoJvmType.createSubTypeDtoSuspect()
]
if (!subTypeURIs.empty) {
layouter.popHierarchy
}
}
def createSuspectStructure(Map<String, OperationInfo> opInfoMap, JvmDeclaredType dtoType, boolean mobile,
YTypedCompoundSuspect parentSuspect) {
opInfoMap.values.filter[!(it.databaseInfo)].forEach [
var JvmType type = null
try {
type = getter.returnType.type
} catch (NullPointerException e) {
return
}
var YSuspect suspect
var properties = newArrayList()
if (it.field !== null) {
properties.addAll(dtoType.toProperties(it.field.declaringType.qualifiedName + "." + it.name))
}
if (type.boolean && !it.isDirtyMark) {
if(mobile) type.createMobileSwitch(it) else suspect = type.createCheckbox(it)
} else if (type.numberWithDigits) {
suspect = type.createDecimalField(it)
if (dtoType.isAttribute(it.name, "NumberToUomo")) {
suspect.tags += "NumberToUomo"
} else {
var dataType = dtoType.toDataType(it.name)
if (dataType !== null) {
var dataTypeName = dataType.jvmTypeReference.type.identifier
if (dataTypeName.equals(Double.canonicalName)) {
suspect = type.createCustomDecimalField(it)
}
}
}
} else if (type.numberWithoutDigits) {
val fieldType = properties.findFirst[it.key.equals(IPropertyConstants.PROPERTY_KEY__FIELD_TYPE)]?.value
if (fieldType !== null && properties.exists [
fieldType.equalsIgnoreCase(IPropertyConstants.PROPERTY_SLIDER)
]) {
suspect = type.createSlider(it, properties)
} else if (!it.idOrUUID && !it.version && !it.dirtyMark) {
suspect = type.createNumberField(it)
}
} else if (type.string) {
val fieldType = properties.findFirst[it.key.equals(IPropertyConstants.PROPERTY_KEY__FIELD_TYPE)]?.value
if (!it.idOrUUID && !it.version && !it.dirtyMark) {
var functionTypingAPI = new FunctionTypingAPI()
val functionImagePicker = functionTypingAPI.functionImagePickerTypeName
if (it.isDomainKey || it.isDomainDescription ||
(!fieldType.nullOrEmpty && fieldType.equals(IPropertyConstants.PROPERTY_SUGGESTTEXT))) {
suspect = type.createSuggestTextField(it, opInfoMap)
} else if (properties.exists[key.toLowerCase.equals(IPropertyConstants.PROPERTY_BLOB)]) {
suspect = type.createBlopUploadComponent(it)
} else if (!fieldType.nullOrEmpty && fieldType.equals(IPropertyConstants.PROPERTY_RICH_TEXT)) {
suspect = type.createRichTextField(it)
} else if (!fieldType.nullOrEmpty && fieldType.equals(IPropertyConstants.PROPERTY_MASKED_TEXT)) {
val mask = properties.findFirst[it.key.equals(IPropertyConstants.PROPERTY_MASK)]?.value
suspect = type.createMaskedTextField(it, mask)
} else if (!fieldType.nullOrEmpty && fieldType.equals(IPropertyConstants.PROPERTY_PASSWORD)) {
suspect = type.createPasswordField(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_TEXTAREA)]) {
suspect = type.createTextAreaField(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_ORGANIZATION)]) {
suspect = type.createOrganizationComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_PERSPECTIVE)]) {
suspect = type.createPerspectiveComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_PRINTSERVICE)]) {
suspect = type.createPrintServiceComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_I18N)]) {
suspect = type.createI18nComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_THEME)]) {
suspect = type.createThemeComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(IPropertyConstants.PROPERTY_MODEL)]) {
suspect = type.createModelComboBox(it)
} else if (properties.exists[key.equalsIgnoreCase(functionImagePicker)]) {
suspect = type.createIconComboBox(it)
} else {
suspect = type.createTextField(it)
}
}
} else if (type.date) {
suspect = type.createDateField(it)
} else if (type.enum) {
if (properties.exists[key.toLowerCase.equals(IPropertyConstants.PROPERTY_OPTION_GROUP)]) {
suspect = type.createEnumOptionsGroup(it)
} else {
suspect = type.createEnumComboBox(it)
}
} else if (type.byteArray) {
val fieldType = properties.findFirst[it.key.equals(IPropertyConstants.PROPERTY_KEY__FIELD_TYPE)]?.value
if (!fieldType.nullOrEmpty && fieldType.equals(IPropertyConstants.PROPERTY_RICH_TEXT)) {
suspect = type.createRichTextField(it)
} else {
suspect = type.createBlopUploadComponent(it)
}
} else if (it.domainReference) {
suspect = type.createBeanReferenceField(it)
} else if (it.field !== null && it.field.collection) {
if (it.asGrid) {
suspect = type.createGrid(it)
} else if (it.asTable) {
suspect = type.createTableField(it)
}
} else if (type.dto) {
suspect = type.createDtoSuspect(it)
}
// mark groups
if (suspect !== null && it.isGroupMember) {
suspect.tags.add(ILayoutingStrategy.TAG__GROUP)
suspect.groupName = it.groupMemberName
}
if (parentSuspect === null) {
type.completeSuspect(it, suspect, dtoType)
} else {
type.completeSuspect(it, suspect, parentSuspect, dtoType)
}
for (keyAndValue : properties) {
if(suspect !== null) suspect.properties.put(keyAndValue.key.toLowerCase, keyAndValue.value)
}
]
}
def createAuthorizationVisibilityProcessor(YAuthorizationable element, OperationInfo info) {
if (info.field !== null) {
val type = info.field.eContainer as JvmGenericType
if (!info.getter.returnType.type.isClass && info.getter.returnType.type.isAllowed(type, info)) {
element.authorizationGroup = type.fullyQualifiedName.toString
element.authorizationId = info.field.simpleName
}
}
}
def YSuspect createDtoSuspect(JvmType type, OperationInfo info) {
val dtoSuspect = YECviewFactory.eINSTANCE.createYTypedCompoundSuspect
dtoSuspect.tags += ILayoutingStrategy.TAG__DTO
if (type instanceof JvmDeclaredType) {
type.createSuspectStructure(false, dtoSuspect)
}
return dtoSuspect
}
/**
* A suspect that is created for each sub type of beanType.<br>
* 1) we create a compound suspect<br>
* 2) we add the compound suspect to the layout<br>
* 3) we create a typed suspect for each operation info<br>
* 4) we add the new typed suspect to the compound suspect and create a tree<br>
*/
def YSuspect createSubTypeDtoSuspect(JvmDeclaredType subDtoJvmType) {
val subTypeSuspect = YECviewFactory.eINSTANCE.createYSubTypeSuspect
subTypeSuspect.tags += ILayoutingStrategy.TAG__SUBTYPE
subTypeSuspect.typeQualifiedName = subDtoJvmType.qualifiedName
subTypeSuspect.type = computer.loadClass(uiLayout.eResource.resourceSet, subTypeSuspect.typeQualifiedName)
// create a new beanslot with the subtype. The main slot will become bound to this slot
val YView view = computer.currentView
val YDetailBeanSlot detailSlot = view.addDetailBeanSlot(subTypeSuspect.typeQualifiedName, subTypeSuspect.type,
yMainBeanslot, "");
detailSlot.tags += ILayoutingStrategy.TAG__SUBTYPE
// assign the detail bean slot to the sub type suspect for bindings later
subTypeSuspect.beanSlot = detailSlot
// add the new suspect to the layout
layouter.add(subTypeSuspect)
// create a new child node in the suspect hierarchy
layouter.pushHierarchy(subTypeSuspect)
// create a hierarchy for the sub dto suspects
// Gets the operation infos for the given type in form of a map and converts the
// operation info map into a sorted list
val subTypeInfos = createSortedMapList(OperationExtensions.getOperationInfos(subDtoJvmType, false))
subTypeInfos.createSuspectStructure(subDtoJvmType, mobile, subTypeSuspect)
// pop the latest subDtoSuspect
layouter.popHierarchy
return subTypeSuspect
}
/**
* Returns true, if the type is a dto.
*/
def boolean isDto(JvmType type) {
val collector = new SuperTypeCollector()
val superTypes = collector.collectSuperTypeNames(type)
// if any of the supertype names equals org.eclipse.osbp.dsl.common.datatypes.IDto
return superTypes.contains(typeof(IDto).name)
}
def completeSuspect(JvmType type, OperationInfo info, YSuspect suspect, JvmType parentType) {
if (suspect !== null) {
suspect.id = '''«uiLayout.generateId».«info.name»'''
if (info.readonly) {
suspect.tags += "readonly"
}
if (info.isOnKanbanCard) {
suspect.tags += "onKanbanCard"
}
if (info.isUniqueEntry) {
suspect.tags += "unique"
var splittedId = info.id.split(":")
if (splittedId.length > 1) {
var fqClassName = splittedId.get(0)
suspect.properties.put("class", fqClassName)
}
suspect.properties.put("name", info.name)
// register the container of the binding to the suspect. Otherwise we can not check for the uniqueness
suspect.createModelValueContainerBinding(info.name, type, "value")
}
if (isValidationConstraint(info)) {
suspect.tags += "constraint"
var splittedId = info.id.split(":")
if (splittedId.length > 1) {
var fqClassName = splittedId.get(0)
suspect.properties.put("class", fqClassName)
}
suspect.properties.put("name", info.name)
}
layouter.add(suspect)
if (info.field !== null && info.field.collection) {
suspect.createModelListBinding(info, type, "list");
} else {
suspect.createModelValueBinding(info.name, type, "value", parentType);
}
// fix the masterDetailBinding endpoint of the child suspects
if (suspect instanceof YTypedCompoundSuspect) {
val masterValueEP = suspect.valueBindingEndpoints.get(0)
if (!suspect.valueBindingEndpoints.isEmpty) {
for (child : suspect.children) {
child.id = suspect.id + child.id
if (!child.valueBindingEndpoints.isEmpty) {
val childValueEP = child.valueBindingEndpoints.get(0)
if (childValueEP instanceof YDetailValueBindingEndpoint) {
childValueEP.masterObservable = EcoreUtil.copy(masterValueEP) as YValueBindingEndpoint
}
}
}
}
}
// create the authorization infos
suspect.createAuthorizationVisibilityProcessor(info)
}
}
def completeSuspect(JvmType type, OperationInfo info, YSuspect suspect, YTypedCompoundSuspect parentSuspect,
JvmType parentType) {
if (suspect !== null) {
suspect.id = '''«parentSuspect.id».«info.name»'''
if (info.readonly) {
suspect.tags += "readonly"
}
if (isValidationConstraint(info)) {
suspect.tags += "constraint"
var splittedId = info.id.split(":")
if (splittedId.length > 1) {
var fqClassName = splittedId.get(0)
suspect.properties.put("class", fqClassName)
}
suspect.properties.put("name", info.name)
}
parentSuspect.children.add(suspect)
if (info.field !== null && info.field.collection) {
suspect.createModelListBinding(info, type, "list");
} else {
suspect.createModelValueBinding(info.name, type, "value", parentType);
}
// create the authorization infos
suspect.createAuthorizationVisibilityProcessor(info)
}
}
/**
* Sorted the attributes with the primitive types first and the rest after. Also all collections were left out.
*/
def createSortedOpInfoMapForCollections(Map<String, OperationInfo> opInfoMap) {
val sortedOpInfoList = <String, OperationInfo>newLinkedHashMap()
val nonPrimitiveOpInfoMap = <String, OperationInfo>newLinkedHashMap()
opInfoMap.forEach [ key, opInfo |
var JvmType detailType
// do not create a column if field is a collection
if (opInfo.field !== null && !opInfo.field.collection) {
detailType = opInfo.getter.returnType.type
val isPrimitive = detailType instanceof JvmPrimitiveType || detailType.getQualifiedName().equals(
typeof(String).getName());
if (isPrimitive) {
sortedOpInfoList.put(key, opInfo)
} else {
nonPrimitiveOpInfoMap.put(key, opInfo)
}
}
]
sortedOpInfoList.putAll(nonPrimitiveOpInfoMap)
sortedOpInfoList
}
/**
* Sorted the attributes in a individual but fix order.
*/
def createSortedMapList(Map<String, OperationInfo> opInfoMap) {
val sortedOpInfoList = <Map<String, OperationInfo>>newLinkedList()
// At this moment the order of the following method is not desired. See #203.
// +++++ Due to the not existing sorting the following lines of code are replaced by ...
/*
* val domainKeyOpInfoMap = <String, OperationInfo>newHashMap()
* val constraintsOpInfoMap = <String, OperationInfo>newHashMap()
* val indexOpInfoMap = <String, OperationInfo>newHashMap()
* val stringOpInfoMap = <String, OperationInfo>newHashMap()
* val restOpInfoMap = <String, OperationInfo>newHashMap()
* // extract String-OperationInfos into a new Map to display later and display all string attributes first.
* opInfoMap.forEach [ key, opInfo |
* val type = opInfo.getter.returnType.type
* if (opInfo !== null && isDomainKey(opInfo)) {
* domainKeyOpInfoMap.put(key, opInfo)
* } else if (opInfo !== null && isIndex(opInfo)) {
* indexOpInfoMap.put(key, opInfo)
* } else if (type.string) {
* stringOpInfoMap.put(key, opInfo)
* } else {
* restOpInfoMap.put(key, opInfo)
* }
* ]
* sortedOpInfoList.add(domainKeyOpInfoMap)
* sortedOpInfoList.add(indexOpInfoMap)
* sortedOpInfoList.add(stringOpInfoMap)
* sortedOpInfoList.add(constraintsOpInfoMap)
* sortedOpInfoList.add(restOpInfoMap)
*/
// ++++ ... this line.
sortedOpInfoList.add(opInfoMap)
sortedOpInfoList
}
def isDomainKey(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (DomainKey.canonicalName.equals(annotationRefs.annotation.identifier)) {
return true
}
}
}
return false
}
def isOnKanbanCard(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (OnKanbanCard.canonicalName.equals(annotationRefs.annotation.identifier)) {
return true
}
}
}
return false
}
def isDomainDescription(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (DomainDescription.canonicalName.equals(annotationRefs.annotation.identifier)) {
return true
}
}
}
return false
}
def isValidationConstraint(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (annotationRefs.annotation.identifier !== null &&
annotationRefs.annotation.identifier.startsWith("javax.validation")) {
return true
}
}
}
return false
}
def isUniqueEntry(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (annotationRefs.annotation.identifier !== null &&
annotationRefs.annotation.identifier.equals(UniqueEntry.canonicalName)) {
return true
}
}
}
return false
}
def isIndex(OperationInfo info) {
if (info !== null && info.field !== null) {
for (annotationRefs : info.field.annotations) {
if (DomainKey.canonicalName.equals(annotationRefs.annotation.identifier)) {
return true
}
}
}
return false
}
/**
* Returns true, if the type is boolean
*
* @param type
* @return
*/
def isByteArray(JvmType type) {
if (type === null)
return false;
if (isArray(type, Byte) || isArray(type, Byte.TYPE)) {
return true;
}
return false;
}
def isArray(JvmType type, Class<?> clazz) {
if (type === null)
return false;
var className = clazz.getName();
if (className.charAt(0) == '[') {
className = clazz.getCanonicalName();
}
className = className.concat("[]")
var result = className.equals(type.getIdentifier());
return result;
}
def YTypedSuspect createTextField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__TEXT
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createSuggestTextField(JvmType type, OperationInfo info, Map<String, OperationInfo> opInfoMap) {
val OperationInfo idAttInfo = opInfoMap.values.toIdInfo
if (idAttInfo === null) {
return createTextField(type, info)
}
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__SUGGEST_TEXT
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)
suspect.typeQualifiedName = beanType.qualifiedName
suspect.properties.put(IPropertyConstants.PROPERTY__ITEM_CAPTION, info.name)
suspect.properties.put(IPropertyConstants.PROPERTY__ITEM_FILTER, info.name)
suspect.properties.put(IPropertyConstants.PROPERTY__ITEM_UUID, idAttInfo.name)
suspect
}
/**
* Returns the operation info for the id property.
*/
def OperationInfo getToIdInfo(Collection<OperationInfo> infos) {
for (OperationInfo info : infos) {
if (info.idOrUUID) {
return info
}
}
return null
}
def YTypedSuspect createTextAreaField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__TEXTAREA
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createSlider(JvmType type, OperationInfo info, ArrayList<Pair> pairs) {
val minValue = pairs.findFirst[it.key.equals("min")]?.value as String
val maxValue = pairs.findFirst[it.key.equals("max")]?.value as String
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__SLIDER
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect.properties.put("min", minValue)
suspect.properties.put("max", maxValue)
suspect
}
def YTypedSuspect createDecimalField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__DECIMAL
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createNumberField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__NUMBER
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createCheckbox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__BOOLEAN
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createDateField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__DATE
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createIconComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__IMAGE_PICKER
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YTypedSuspect createEnumComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__ENUM_COMBO
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createOrganizationComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__ORGANIZATION_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createPerspectiveComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__PERSPECTIVE_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createThemeComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__THEME_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createModelComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__MODEL_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createPrintServiceComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__PRINTSERVICE_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createI18nComboBox(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__I18N_COMBO
suspect.type = typeof(String)
suspect.typeQualifiedName = typeof(String).name
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createEnumOptionsGroup(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__ENUM_OPTIONS
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect.id = '''«uiLayout.generateId».«info.name»'''
if (info.readonly) {
suspect.tags += "readonly"
}
suspect
}
def YTypedSuspect createBeanReferenceField(JvmType type, OperationInfo info) {
var YTypedSuspect suspect = null
var suspectType = computer.loadClass(uiLayout?.eResource?.resourceSet, type?.qualifiedName)
var captionProperty = BeanHelper.findCaptionProperty(suspectType)
var captionDescription = BeanHelper.findDescriptionProperty(suspectType)
if (captionProperty !== null || captionDescription !== null) {
suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.type = suspectType
suspect.tags += ILayoutingStrategy.TAG__BEAN_REFERENCE
suspect.id = '''«uiLayout.generateId».«info.name»'''
if (info.readonly) {
suspect.tags += "readonly"
}
if (info.hasAnnotation(FilterDepth)) {
val depth = toFilterDepth(info.field)
suspect.properties.put(IPropertyConstants.PROPERTY__FILTER_DEPTH, Integer.toString(depth))
}
suspect.typeQualifiedName = type.qualifiedName
suspect.properties.put(IPropertyConstants.PROPERTY__ITEM_CAPTION, captionProperty)
suspect.properties.put(IPropertyConstants.PROPERTY__ITEM_DESCRIPTION, captionDescription)
}
suspect
}
def YTypedSuspect createTableField(JvmType type, OperationInfo info) {
type.createCollection(info, ILayoutingStrategy.TAG__TABLE)
}
def YTypedSuspect createGrid(JvmType type, OperationInfo info) {
type.createCollection(info, ILayoutingStrategy.TAG__GRID)
}
def YTypedSuspect createCollection(JvmType type, OperationInfo info, String tag) {
val suspect = YECviewFactory.eINSTANCE.createYCollectionSuspect
val JvmParameterizedTypeReference collectionType = info.getter.returnType as JvmParameterizedTypeReference
val JvmTypeReference typeInCollection = collectionType.arguments.get(0)
try {
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, typeInCollection.qualifiedName)
} catch (NullPointerException ex) {
ex.printStackTrace
throw ex
}
suspect.tags += tag
suspect.typeQualifiedName = typeInCollection.qualifiedName
// Not used! Has to be removed!
// var typeRef = info.field.type
// var JvmDeclaredType argType
if (typeInCollection?.type instanceof JvmDeclaredType) {
val castedType = typeInCollection.type as JvmDeclaredType
// TODO get props from JVMType
val propMap = castedType.toFieldProperties
val opInfoMap = OperationExtensions.getOperationInfos(castedType)
val sortedOpInfoMap = createSortedOpInfoMapForCollections(opInfoMap)
sortedOpInfoMap.values.filter[!(it.databaseInfo) && !(it.idOrUUID) && !(it.version) && !(it.dirtyMark)].
forEach [
var JvmType detailType = it.getter.returnType.type
var YColumnInfo columnInfo = null
val isPrimitive = detailType instanceof JvmPrimitiveType;
if (it.isDomainReference) {
// else use the domain key field and reserve them till the end
for (nestedInfo : JvmTypeProperties.getOperationInfos(detailType as JvmDeclaredType).values) {
if (nestedInfo.hasAnnotation(typeof(DomainKey))) {
val nestPropMap = (detailType as JvmDeclaredType).toFieldProperties
columnInfo = nestedInfo.type.createYColumnInfo
columnInfo.name = it.field.simpleName + "." + nestedInfo.attributePath
var propList = nestPropMap.get(nestedInfo.name)
columnInfo.setYColumnInfoProperties(propList)
}
}
} else {
var JvmType objectType = it.field.type.type;
if (isPrimitive) {
val primitiveTypeName = it.field.type.type.qualifiedName
val InternalEObject proxy = TypesFactory.eINSTANCE.createJvmVoid as InternalEObject
proxy.eSetProxyURI(URI.createURI(toObjectProxy(primitiveTypeName)))
objectType = EcoreUtil.resolve(proxy, uiLayout.eResource) as JvmType
}
columnInfo = objectType.createYColumnInfo
columnInfo.name = it.name
var propList = propMap.get(it.field.identifier)
columnInfo.setYColumnInfoProperties(propList)
}
if (columnInfo !== null) {
// TODO (JCD): Simple name instead of FQN till solution of ticket - #581
columnInfo.labelI18nKey = columnInfo.name
suspect.columns += columnInfo
}
]
}
suspect
}
/**
* Creates a proxy object
**/
def toObjectProxy(String primitiveTypeName) {
switch (primitiveTypeName) {
case "int":
return '''java:/Objects/java.lang.Integer#java.lang.Integer'''
default:
return '''java:/Objects/java.lang.«primitiveTypeName.toFirstUpper»#java.lang.«primitiveTypeName.
toFirstUpper»'''
}
}
def void createMobileSwitch(JvmType type, OperationInfo info) {
val yField = vFactory.createVMSwitch
yField.initialEnabled = !info.readonly
// yField.labelI18nKey = i18nRootKey + "." + info.name
yField.label = info.name
layouter.add(yField)
yField.createBinding(info, type, "value");
}
def YSuspect createRichTextField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
if (type.string) {
suspect.tags += ILayoutingStrategy.TAG__RICH_TEXT__STRING
} else if (type.byteArray) {
suspect.tags += ILayoutingStrategy.TAG__RICH_TEXT__BLOB
} else {
throw new IllegalArgumentException(
"RichTextFields need to be bound to String or byte[]. " + type.qualifiedName +
" is not a valid option.")
}
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YSuspect createMaskedTextField(JvmType type, OperationInfo info, String mask) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__MASKED_TEXT_FIELD
suspect.properties.put(IPropertyConstants.PROPERTY_MASK, mask)
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YSuspect createMaskedDecimalField(JvmType type, OperationInfo info, String mask) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__MASKED_DECIMAL_FIELD
suspect.properties.put(IPropertyConstants.PROPERTY_MASK, mask)
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YSuspect createPasswordField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
if (type.string) {
suspect.tags += ILayoutingStrategy.TAG__PASSWORD
} else {
throw new IllegalArgumentException(
"PasswordField need to be bound to String. " + type.qualifiedName + " is not a valid option.")
}
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YSuspect createBlopUploadComponent(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__BLOB
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
def YSuspect createCustomDecimalField(JvmType type, OperationInfo info) {
val suspect = YECviewFactory.eINSTANCE.createYTypedSuspect
suspect.tags += ILayoutingStrategy.TAG__DECIMAL
suspect.type = computer.loadClass(uiLayout.eResource.resourceSet, type.qualifiedName)
suspect.typeQualifiedName = type.qualifiedName
suspect
}
/**
* Create the bindings and install at the view
*/
def createBinding(YEmbeddable yField, OperationInfo info, JvmType type, String fieldProperty) {
// use the autoWireSource as the model endpoint
val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.autoWireSource as UiBindingEndpointAssignment
val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
detailValueEndpoint.propertyPath = info.name
detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)
// create the field endpoint
val yFieldEndpoint = BindingFactory.eINSTANCE.createYECViewModelValueBindingEndpoint
yFieldEndpoint.element = yField
yFieldEndpoint.propertyPath = fieldProperty
yFieldEndpoint.typeQualifiedName = beanType.qualifiedName
yFieldEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet, beanType.qualifiedName)
if (yFieldEndpoint.type !== null && yFieldEndpoint.type.isAssignableFrom(typeof(EObject))) {
yFieldEndpoint.emfNsURI = yField.eClass.EPackage.nsURI
}
// bind model to target
val yBinding = BindingFactory.eINSTANCE.createYValueBinding();
yBinding.setTargetEndpoint(yFieldEndpoint);
yBinding.setModelEndpoint(detailValueEndpoint);
yBinding.setModelToTargetStrategy(YBindingUpdateStrategy.UPDATE);
yBinding.setTargetToModelStrategy(
if(info.readonly) YBindingUpdateStrategy.NEVER else YBindingUpdateStrategy.UPDATE)
// register the binding at the current view
yLayout.view.orCreateBindingSet.bindings += yBinding
// set the i18n key based on the binding
// yField.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, detailValueEndpoint.propertyPath)
yField.labelI18nKey = detailValueEndpoint.propertyPath
}
/**
* Create the bindings and install at the view
*/
def createModelValueBinding(YSuspect suspect, String propertyPath, JvmType type, String fieldProperty,
JvmType parentType) {
val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
var YValueBindingEndpoint endpoint = null
var path = ""
// If a subTypeBeanSlot could be found, then we need to create a binding endpoint against this beanslot.
// The main slot has a different type then detail beanslot. And we can not bind fields contained in the subtype
// to the main bean slot. Eclipse databinding requires a proper type at binding creation.
if (subTypeBeanSlot === null) {
// use the autoWireSource as the model endpoint
val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
autoWireSource as UiBindingEndpointAssignment
val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
detailValueEndpoint.propertyPath = propertyPath
detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet,
parentType.qualifiedName)
endpoint = detailValueEndpoint
path = detailValueEndpoint.propertyPath
} else {
endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath)
path = propertyPath
}
suspect.getValueBindingEndpoints().add(endpoint);
// set the i18n key based on the binding
// suspect.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, path)
suspect.labelI18nKey = path
suspect.label = propertyPath
}
/**
* Creates a binding which points to the container of the property
*/
def createModelValueContainerBinding(YSuspect suspect, String propertyPath, JvmType type, String property) {
var fieldProperty = property
if (fieldProperty.contains(".")) {
fieldProperty = fieldProperty.substring(0, fieldProperty.lastIndexOf("."))
} else {
fieldProperty = null
}
val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
var YValueBindingEndpoint endpoint = null
// If a subTypeBeanSlot could be found, then we need to create a binding endpoint against this beanslot.
// The main slot has a different type then detail beanslot. And we can not bind fields contained in the subtype
// to the main bean slot. Eclipse databinding requires a proper type at binding creation.
if (subTypeBeanSlot === null) {
// use the autoWireSource as the model endpoint
val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
autoWireSource as UiBindingEndpointAssignment
val yModelEndpoint = computer.createValueBindingEndpoint(uiModelEndpoint)
endpoint = yModelEndpoint
if (fieldProperty !== null) {
val detailValueEndpoint = yModelEndpoint.createDetailValueEndpoint
detailValueEndpoint.propertyPath = propertyPath
detailValueEndpoint.type = computer.loadClass(uiLayout.eResource.resourceSet,
beanType.qualifiedName)
endpoint = detailValueEndpoint
}
} else {
endpoint = subTypeBeanSlot.createBindingEndpoint(propertyPath)
}
suspect.containerValueBindingEndpoint = endpoint
}
/**
* Checks if the suspect is contained in an YSubTypeSuspect. <br>
* If so, then the detail beanslot of the YSubTypeSuspect is returned. Null otherwise.
*/
def YBeanSlot findSubTypeBeanSlot(YSuspect suspect) {
if (suspect === null) {
return null
}
if (suspect instanceof YSubTypeSuspect) {
return suspect.beanSlot
}
val parent = suspect.eContainer
if (parent instanceof YSuspect) {
return parent.findSubTypeBeanSlot
}
return null
}
/**
* Create the bindings and install at the view
*/
def createModelListBinding(YSuspect suspect, OperationInfo info, JvmType type, String fieldProperty) {
val YBeanSlot subTypeBeanSlot = suspect.findSubTypeBeanSlot
var YListBindingEndpoint endpoint = null
if (subTypeBeanSlot === null) {
// use the autoWireSource as the model endpoint
val UiBindingEndpointAssignment uiModelEndpoint = uiLayout.
autoWireSource as UiBindingEndpointAssignment
endpoint = createListBindingEndpointWithNested(uiModelEndpoint, info.name)
} else {
endpoint = subTypeBeanSlot.createListBindingEndpoint(info.name, subTypeBeanSlot.valueType)
}
suspect.getValueBindingEndpoints().add(endpoint);
// set the i18n key based on the binding
// suspect.labelI18nKey = I18nKeyProvider.toI18nKey(beanType.qualifiedName, info.name)
suspect.labelI18nKey = info.name
suspect.label = info.name
}
/**
* Creates a listbinding with respect to nested collection fields. <p>
* For instance:<br>
* beanSlot contains Person. We want to bind the children of persons father to a table.
* So we need to access the children collection of the beanslot by a nested property path: <code>beanslot.father.children</code>
*/
def YListBindingEndpoint createListBindingEndpointWithNested(UiBindingEndpointAssignment epDef,
String attributePath) {
if (epDef === null) {
return null
}
var YListBindingEndpoint result = null;
val BindingInfoHelper.BindingInfo info = new BindingInfoHelper.BindingInfo()
bindingInfoHelper.collectBindingInfo(epDef, info);
if (info.bindingRoot instanceof UiBeanSlot) {
val uiBeanSlot = info.bindingRoot as UiBeanSlot
val YBeanSlot yBeanSlot = computer.associatedUi(uiBeanSlot)
val YBeanSlotListBindingEndpoint ep = factory.createBeanSlotListBindingEndpoint
ep.beanSlot = yBeanSlot
ep.attributePath = toNestedCollectionPath(info, attributePath)
result = ep
} else if (info.bindingRoot instanceof UiEmbeddable) {
val YEmbeddable yElement = computer.associatedUi(info.bindingRoot)
val YECViewModelListBindingEndpoint ep = factory.createECViewModelListBindingEndpoint
ep.element = yElement
ep.propertyPath = toNestedCollectionPath(info, attributePath)
if (info.typeForBinding !== null) {
ep.typeQualifiedName = info.typeForBinding.qualifiedName
ep.type = computer.loadClass(epDef.eResource.resourceSet, ep.typeQualifiedName)
}
if (yElement !== null) {
ep.emfNsURI = yElement.eClass.EPackage.nsURI
}
result = ep
}
return result
}
def toNestedCollectionPath(BindingInfo info, String attributePath) {
val StringBuilder b = new StringBuilder
if (!info.path.toString.nullOrEmpty) {
b.append(info.path.toString)
}
if (!attributePath.nullOrEmpty) {
if (b.length > 0) {
b.append(".")
}
b.append(attributePath)
}
val pathResult = b.toString
pathResult
}
/**
* Creates y column info element
*/
def YColumnInfo createYColumnInfo(JvmType type) {
val YColumnInfo columnInfo = YECviewFactory.eINSTANCE.createYColumnInfo
columnInfo.typeQualifiedName = type.qualifiedName
columnInfo.type = computer.loadClass(uiLayout.eResource.resourceSet, columnInfo.typeQualifiedName)
columnInfo
}
/**
* Sets properties into y column info
*/
def setYColumnInfoProperties(YColumnInfo columnInfo, List<AutowireUtil.Pair> propList) {
var properties = columnInfo.properties
if (propList !== null) {
for (prop : propList) {
properties.put(prop.key, prop.value)
}
}
}
public interface Layouter {
def void setup(UiLayout uiRootLayout, YLayout yRootLayout)
def void add(YEmbeddable element);
def void add(YSuspect suspect);
def void pushHierarchy(YTypedCompoundSuspect suspect);
def void popHierarchy();
}
public static class MobileLayouter implements Layouter {
VMVerticalComponentGroup group
override setup(UiLayout uiRootLayout, YLayout yRootLayout) {
group = VaadinMobileFactory.eINSTANCE.createVMVerticalComponentGroup
yRootLayout.elements += group
}
override add(YEmbeddable element) {
group.addElement(element)
}
override add(YSuspect ySuspect) {
// layout.suspects += ySuspect
}
override pushHierarchy(YTypedCompoundSuspect suspect) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override popHierarchy() {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
}
public static class StrategyLayoutLayouter implements Layouter {
Stack<YTypedCompoundSuspect> currentSubDtoSuspect = new Stack
YStrategyLayout layout
override setup(UiLayout uiRootLayout, YLayout yRootLayout) {
layout = YECviewFactory.eINSTANCE.createYStrategyLayout
layout.id = "strategyLayout"
layout.numberColumns = uiRootLayout.numberColumns
yRootLayout.numberColumns = uiRootLayout.numberColumns
yRootLayout.elements += layout
yRootLayout.view.visibilityProcessors +=
YVisibilityFactory.eINSTANCE.createYAuthorizationVisibilityProcessor
if (yRootLayout instanceof YAlignmentContainer) {
yRootLayout.applyAlignment(layout, YAlignment.FILL_FILL)
}
}
override add(YEmbeddable element) {
}
override add(YSuspect ySuspect) {
if (!currentSubDtoSuspect.isEmpty) {
currentSubDtoSuspect.peek.children += ySuspect
} else {
layout.suspects += ySuspect
}
}
override pushHierarchy(YTypedCompoundSuspect suspect) {
currentSubDtoSuspect.push(suspect)
}
override popHierarchy() {
currentSubDtoSuspect.pop
}
}
/**
* The Class LocalResourceAccess.
*/
public static class LocalResourceAccess implements IReferenceFinder.ILocalResourceAccess {
ResourceSet rs
new(ResourceSet rs) {
this.rs = rs
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.xtext.findReferences.IReferenceFinder.IResourceAccess
* #readOnly(org.eclipse.emf.common.util.URI,
* org.eclipse.xtext.util.concurrent.IUnitOfWork)
*/
override <R> R readOnly(URI targetURI, IUnitOfWork<R, ResourceSet> work) {
return work.exec(rs);
}
}
}