All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joinedworkz.common.helper.CmnModelHelper.xtend Maven / Gradle / Ivy

package org.joinedworkz.common.helper

import java.util.Collection
import java.util.List
import java.util.Set
import javax.inject.Inject
import javax.inject.Singleton
import org.joinedworkz.common.adapter.KeyAdapter
import org.joinedworkz.common.strategies.ColumnNameStrategy
import org.joinedworkz.common.strategies.TableNameStrategy
import org.joinedworkz.core.model.CmnComplexType
import org.joinedworkz.core.model.CmnElement
import org.joinedworkz.core.model.CmnEnumeration
import org.joinedworkz.core.model.CmnField
import org.joinedworkz.core.model.CmnFieldContainer
import org.joinedworkz.core.model.CmnFieldSet
import org.joinedworkz.core.model.CmnModel
import org.joinedworkz.core.model.CmnNamedObject
import org.joinedworkz.core.model.CmnObject
import org.joinedworkz.core.model.CmnOperation
import org.joinedworkz.core.model.CmnOperationParameter
import org.joinedworkz.core.model.CmnPlatform
import org.joinedworkz.core.model.CmnType

@Singleton
class CmnModelHelper {
    
    @Inject
    TableNameStrategy tableNameStrategy
    
    @Inject
    ColumnNameStrategy columnNameStrategy
    
    @Inject
    Inflector inflector
	
	val static char BRACKET = '('
	val static char DOT = '.'
	
	protected extension NameHelper nameHelper = new NameHelper
	
	final protected static String JAVA_NAME = "javaName";
	final protected static String JAVA_TYPE = "javaType";
	final protected static String TABLE_NAME = "tableName";
	final protected static String COLUMN_NAME = "columnName";
	final protected static String COLUMN_TYPE = "columnType";
	
	def String lastSegment(String type) {
		if (type !== null) {
			val bracketIndex = type.indexOf(BRACKET)
			var relevantDotIndex = -1
			if (bracketIndex > 0) {
				val beforeBracket = type.substring(0,bracketIndex)
				relevantDotIndex = beforeBracket.lastIndexOf(DOT)
			} else {
				relevantDotIndex = type.lastIndexOf(DOT)
			}
			if (relevantDotIndex > 0) {
				return type.substring(relevantDotIndex + 1)
			}
		}
		return type
	}
	
	def String packageSegments(String type) {
		if (type !== null) {
			val lastDotIndex = type.lastIndexOf('.')
			if (lastDotIndex > 0) {
				return type.substring(0,lastDotIndex)
			}
		}
		return type
	}
	
	def CmnModel getModel(CmnElement cmnObject) {
		if (cmnObject instanceof CmnModel) {
			return cmnObject
		} else if (cmnObject.container !== null) {
			return getModel(cmnObject.container)
		} else {
		    throw new RuntimeException('Model not found for element of type ' + cmnObject?.class.canonicalName)
		}
	}
	
    def concreteFieldContainers(CmnModel model) {
        model.modelElements.filter(e | isDtoObject(e)).filter(CmnFieldContainer).filter[isConcrete]
    }
    
	def boolean isDtoObject(CmnObject it) {
		return it instanceof CmnFieldContainer && !(it instanceof CmnFieldSet)
	}
	
	def isConcrete(CmnFieldContainer it) {
        abstract === null || !abstract
    }
    
    def isFinalized(CmnObject it) {
        model.isTrue('finalized')
    }
    
    def isAvailableInPlatform(CmnObject it, String qualifiedPlatformName) {
        val modelOfObject = model
        if (modelOfObject.isTrue('finalized')) {
            return modelOfObject.platform.isPlatform(qualifiedPlatformName)
        }
        return true        
    }
    
    def boolean isPlatform(CmnPlatform platform, String qualifiedPlatformName) {
        if (platform.qualifiedName == qualifiedPlatformName) {
            return true
        } else if (platform.basePlatform !== null) {
            return isPlatform(platform.basePlatform, qualifiedPlatformName)
        } else {
            return false
        }
    }
	
	def boolean multipleOccurences(Integer maxOccurs) {
        return maxOccurs !== null && (1 !== maxOccurs)
    }
	
	def CmnFieldContainer getBaseFieldContainer(CmnElement it) {
        if (it instanceof CmnType) {
            val baseType = it.baseType
            if (baseType instanceof CmnComplexType) {
                return baseType
            }
        }
        return null
    }
    
    def Set collectBaseTypes(Set types) {
		var collectedTypes = newLinkedHashSet
		for (type : types) {
			addBaseTypeRecursive(collectedTypes, type)
		}
		return collectedTypes
	}
	
	def void addBaseTypeRecursive(Set collectedTypes, CmnType type) {
		val baseType = type.baseType
		if (baseType !== null) {
			collectedTypes.add(baseType)
			addBaseTypeRecursive(collectedTypes, baseType)
		}
	}
	
	def String getName(CmnElement cmnObject) {
        if (cmnObject instanceof CmnNamedObject) {
            return cmnObject.name
        }
	}
	
	def Integer getInteger(CmnObject object, String propertyName) {
	     val property = object.getProperty(propertyName)
	     if (property !== null) {
	        val propertyValue = property.value
	        if (propertyValue instanceof Integer) {
	            return propertyValue as Integer
	        }
	     }
	}
	
	def Boolean getBoolean(CmnObject object, String propertyName) {
         val property = object.getProperty(propertyName)
         if (property !== null) {
            val propertyValue = property.value
            if (propertyValue instanceof Boolean) {
                return propertyValue as Boolean
            }
         }
    }
    
     def boolean isTrue(CmnObject object, String propertyName) {
         val property = object.getProperty(propertyName)
         if (property !== null) {
            val propertyValue = property.value
            if (propertyValue instanceof Boolean) {
                return (propertyValue as Boolean).booleanValue
            }
         }
         return false
    }
    
        
    def determineEnumType(CmnType type) {
        if (type instanceof CmnEnumeration) {
            return type.hasStereoType('integer') ? 'Integer' : null
        }
    }
	
	def String javaType(CmnElement object) {
		val javaType = object.javaTypeProperty
		if (javaType !== null) {
			return javaType
		}
		
		if (object instanceof CmnField) {
			return object.type?.name
		} else if (object instanceof CmnType) {
			return object.name
		}
	}
	
	def javaTypeProperty(CmnElement it) {
		getString(JAVA_TYPE)
	}
	
	def CmnType keyType(CmnType it) {
		if (it instanceof CmnFieldContainer) {
			return keyFieldOfType?.type
		}
	}
    
    def String keyJavaName(CmnType it) {
		if (it instanceof CmnFieldContainer) {
			return keyFieldOfType?.javaName
		}
	}
	
	def CmnField keyFieldOfType(CmnType it) {  
		if (it instanceof CmnFieldContainer) {
		 	var keyAdapter = getAdapter(KeyAdapter) // cache key field for containing type (the referenced type)
		 	if (keyAdapter === null) {
			 	var keyField = keyFields?.head
				if (keyField === null) {
					keyField = baseType?.keyFieldOfType
				}
				if (keyField === null) {
					System.err.println("Key field not found of type: " + name)
					System.err.println("Key fields size: " + keyFields.size)
					throw new IllegalStateException("No key fields found for type: " + name)
				}
				keyAdapter = new KeyAdapter(keyField)
				putAdapter(keyAdapter)
			}
			return keyAdapter.keyField
		}
	}
	
	def isKey(CmnField it) {
		if (container instanceof CmnFieldContainer) {
			return (container as CmnFieldContainer).containsKeyField(it)
		} else {
			hasStereoType('key') // TODO remove this deprecated variant
		}
	}
	
	def boolean containsKeyField(CmnFieldContainer container, CmnField field) {
		val containsKey = container.keyFields?.contains(field)
		if (containsKey) {
			return true
		} else if (container.container instanceof CmnFieldContainer) {
			val containerContainsKey = (container.container as CmnFieldContainer).containsKeyField(field)
			if (containsKey) {
				return true
			}
		} 
		return field.hasStereoType('key')  // TODO remove this deprecated variant
	}
		
	def String javaType(CmnOperationParameter object) {
        if (object.type !== null) {
            return object.type.javaType
        } else if (object.referencedField !== null) {
            return object.referencedField.javaDtoFieldType
        }
    }
	
	def CmnType dtoFieldType(CmnField field) {
    	if (field.isReferenceField) {
    		val keyFieldType = field.referencedRootField.type.keyType
    		if (keyFieldType === null) {
    			System.err.println("Error: key type not found for field " + field.name + ' of type ' + field.type.name)
    		}
    		return keyFieldType
    	} else {
    		return field.type 
    	}
    }
    
    def CmnField referencedRootField(CmnField field) {
    	if (field.sourceField !== null  && !field.relationField) {
    		System.out.println("Get root of: "+field.container.name +"."+field.name)
    		return field.sourceField.referencedRootField
    	} else {
    		return field
    	}
    }
    
    def Iterable collectAllReferences(CmnFieldContainer it, List references) {
        references.addAll(fields.filter[isReferenceField])
        val base = baseFieldContainer
        if (base !== null) {
            base.collectAllReferences(references)
        }
        return references
    }
    
    def Iterable collectReferencesToBeImplemented(CmnFieldContainer it, List references) {
        references.addAll(fields.filter[isReferenceField])
        val base = baseFieldContainer
        if (base !== null && base.abstract) {
            base.collectReferencesToBeImplemented(references)
        }
        return references
    }
    
    def boolean isReferenceField(CmnField field) {
    	if (Boolean.TRUE === field.isReference) {
    		return true
    	} else if (field.sourceField !== null && !field.relationField) {
    		val processedFields = newHashSet
    		processedFields.add(field)
    		return field.sourceField.isReferenceFieldRecursive(processedFields)
    	}
    	return false
    }
    
    def boolean isReferenceFieldRecursive(CmnField field, Set processedFields) {
    	if (processedFields.contains(field)) {
    		System.out.println("Field already processed: " + field.name)
    		return false
    	}
    	processedFields.add(field)
    	if (Boolean.TRUE === field.isReference) {
    		return true
    	} else if (field.sourceField !== null) {
			if (processedFields.contains(field.sourceField)) {
	    		System.out.println("Source field already processed: " + field.sourceField.name)
	    		return false
	    	}
    		return field.sourceField.isReferenceFieldRecursive(processedFields)
    	}
    	return false
    }
	
	def String javaDtoFieldType(CmnField field) {
		if (field !== null) {
			if (!field.isReferenceField) {  // ignore type property in case of reference (then the type property of the key-field is relevant)
				val typeFromProperty = field.javaTypeProperty
				if (typeFromProperty !== null) {
					return typeFromProperty
				}
			}
			val dtoType = field.dtoFieldType
			if (dtoType !== null) {
				return dtoType.javaType
			} else {
				return 'String'
			}
		} else {
			return null
		}
    }
    
    def String javaDtoFieldName(CmnField field) {
		val fieldName = field.javaName
		if (field.isReferenceField) {
			/* custom name of a field overrides the standard reference field naming */
			if (field.sourceField !== null) {
				val sourceFieldJavaName = field.sourceFieldJavaNameRecursive
				if (fieldName != sourceFieldJavaName) {
					return fieldName
				}
			}
			val keyName = field.type.keyJavaName
			if (field.collection) {
				val singularFieldName = inflector.singularize(fieldName)
				val pluralKeyName = keyName !== null ? inflector.pluralize(keyName) : null
				return singularFieldName + pluralKeyName?.toFirstUpper
			} else {
				return fieldName + keyName?.toFirstUpper
			}
		} else {
			return fieldName
		}
	}
	
	def String sourceFieldJavaNameRecursive(CmnField field) {
		if (field.sourceField !== null) {
			return field.sourceField.sourceFieldJavaNameRecursive
		} else {
			return field.javaName
		}
	}
	
	def String javaName(CmnField field) {
		val javaName = field.getString(JAVA_NAME)
		if (javaName !== null) {
			return javaName
		} else {
			return field.name
		}
	}
	
	def String javaName(CmnOperationParameter it) {
        if (name !== null) {
            return name
        } else if (referencedField !== null) {
            return referencedField.javaDtoFieldName
        }
    }
	
	def String parameterName(CmnOperationParameter it) {
        if (name !== null) {
            return name
        } else if (referencedField !== null) {
            return referencedField.javaName
        }
    }
	
	def String tableName(CmnElement object) {
		if (object instanceof CmnFieldContainer) {
			val tableName = object.getString(TABLE_NAME)
			if (tableName !== null) {
				return tableName
			}
			// TODO instead of explicitly calling the following method invoke table name strategy on all related model elements
			return tableNameStrategy.defaultTableName(object)
		}
		return "UNDEFINED_TABLE_NAME"

	}
	
	def String columnName(CmnField field) {
	    if (field !== null) {
    		val javaName = field.getString(COLUMN_NAME)
    		if (javaName !== null) {
    			return javaName
    		} 
		    // TODO instead of explicitly calling the following method invoke column name strategy on all related model elements
			return columnNameStrategy.defaultColumnName(field)
	    }
	}
	
	def String columnType(CmnField field) {
		val columnType = field.getString(COLUMN_TYPE)
		val javaType = field.javaDtoFieldType
		if (columnType !== null) {
			return columnType
		} else if (javaType !== null) {
		    if (javaType.endsWith('UUID')) {
		        return 'UUID'
		    } else if (javaType.endsWith('Integer')) {
		        val precision = field.getInteger('precision')
		        if (precision !== null && precision < 5) {
		            return 'SMALLINT'
		        } else {
		            return 'INTEGER'
		        }
		    } else if (javaType.endsWith('Long')) {
                return 'BIGINT'
		    }
		}
		if (field.type instanceof CmnEnumeration) {
		    val enumType = determineEnumType(field.type)
		    if (enumType == 'Integer') {
		        return 'INTEGER'
		    } else {
		        return 'VARCHAR'
		    }
		}
		val typeName = field.type?.name?.toUpperCase
		if (hasStereoTypeString(field.type)) {
		    if ("TEXT" != typeName) {
    			return "VARCHAR"
		    }
		}
		return typeName
		
	}
	
	def hasStereoType(CmnObject it, String stereoTypeName) {
		return stereoTypes !== null && stereoTypes.contains(stereoTypeName)
	}
	
	def hasStereoType(CmnComplexType it, String stereoTypeName) {
        return stereoTypes !== null && stereoTypes.contains(stereoTypeName)
    }
    
    def hasStereoType(CmnFieldContainer it, String stereoTypeName) {
        return stereoTypes !== null && stereoTypes.contains(stereoTypeName)
    }
    
    def hasStereoTypeContainedIn(CmnObject it, String ...stereoTypeNames) {
        if ( stereoTypes !== null) {
            for (stereoTypeName : stereoTypeNames) {
                if (stereoTypes.contains(stereoTypeName)) {
                    return true
                }
            }
        }
        return false
    }
	
	def hasStereoTypeString(CmnType it) {
		hasStereoType("string")
	}
	
	
	def Iterable allFields(CmnFieldContainer fieldContainer, boolean pullAllBaseFields) {
		if (fieldContainer instanceof CmnComplexType) {
    		val Collection allFields = newArrayList
    		collectFields(allFields, fieldContainer, pullAllBaseFields)
    		return allFields
		} else {
		    return fieldContainer.fields
		}
	}
		
	def void collectFields(Collection collectedFields, CmnType type, boolean pullAllBaseFields) {
		if (type instanceof CmnComplexType) {
		    if (pullAllBaseFields || type.hasAbstractBaseType) {
			     collectFields(collectedFields, type.baseType, pullAllBaseFields)
			}
			collectedFields.addAll(type.fields)
		}
	}
	
	def Iterable allDtoFields(CmnFieldContainer fieldContainer, boolean pullAllBaseFields) {
		if (fieldContainer instanceof CmnComplexType) {
    		val Collection allFields = newArrayList
    		collectDtoFields(allFields, fieldContainer, pullAllBaseFields)
    		return allFields
		} else {
		    return fieldContainer.dtoFields
		}
	}
		
	def void collectDtoFields(Collection collectedFields, CmnType type, boolean pullAllBaseFields) {
		if (type instanceof CmnComplexType) {
		    if (pullAllBaseFields || type.hasAbstractBaseType) {
			     collectFields(collectedFields, type.baseType, pullAllBaseFields)
			}
			collectedFields.addAll(type.dtoFields)
		}
	}
		
	def Iterable dtoFields(CmnFieldContainer it) {
	    return fields.filter[!isM2NRelation]
	}
	
	def isM2NRelation(CmnField it) {
        if (isRelationField) {
            return isCollection && sourceField !== null && sourceField.isCollection
        } else {
            return false
        }
    }
	
	def Collection allOperations(CmnFieldContainer fieldContainer, boolean pullAllBaseOperations) {
    		val Collection allOperations = newArrayList
    		collectOperations(allOperations, fieldContainer, pullAllBaseOperations)
    		return allOperations
	}
		
	def void collectOperations(Collection collectedOperations, CmnElement type, boolean pullAllBaseOperations) {
		if (type instanceof CmnComplexType) {
		    if (pullAllBaseOperations || type.hasAbstractBaseType) {
		        collectOperations(collectedOperations, type.baseType, pullAllBaseOperations)
		    }
		}
		if (type instanceof CmnFieldContainer) {
			collectedOperations.addAll(type.operations)
		}
	}
	    
    def CmnType determineReturnType(CmnOperation operation) {
        if (operation.returnType !== null) {
            return operation.returnType
        } else if (operation.baseOperation !== null) {
            return determineReturnType(operation.baseOperation);
        }
    }
	
	def boolean hasAbstractBaseType(CmnComplexType it) {
	    val baseFieldContainer = getBaseFieldContainer
	    return baseFieldContainer.isAbstract
	}
	
	def boolean isAbstract(CmnFieldContainer it) {
        if (it !== null) {
            val isAbstract = it.abstract
           return isAbstract !== null && isAbstract
        } else {
            return false
        }
    }
    
    def boolean isAbstract(CmnOperation it) {
        if (it !== null) {
            val isAbstract = it.abstract
           return isAbstract !== null && isAbstract
        } else {
            return false
        }
    }
		
	def boolean isCollection(CmnField field) {
	    
	    val collectionIsSpecifiedOnField = field.maxOccurs !== null && (field.maxOccurs < 0 || field.maxOccurs > 1)
	    if (collectionIsSpecifiedOnField) {
	        return true
	    }
	    
        if (field.relation !== null) {

            val fieldContainer = field.container
            if (field.relation.leftType == fieldContainer) {
                return field.relation.leftMaxOccurs !== null &&
                    (field.relation.leftMaxOccurs < 0 || field.relation.leftMaxOccurs > 1)
            } else
                (field.relation.rightType == fieldContainer)
            {
                return field.relation.rightMaxOccurs !== null &&
                    (field.relation.rightMaxOccurs < 0 || field.relation.rightMaxOccurs > 1)
            }

        }
        return false

    }
    
    def isRelationField(CmnField it) {
        if (isRelation !== null && isRelation) {
            return isCollection && sourceField !== null && sourceField.isCollection
        } else {
            return false
        }
    }
    
    def List getImmutableFields(CmnFieldContainer it, boolean recursive) {
        if (it !== null) {
            val immutable = hasStereoType('immutable')
            val immutableFields = newArrayList
            if (recursive) {
                immutableFields .addAll(getImmutableFields(baseFieldContainer, true))
            }
            immutableFields.addAll(fields.filter[immutable || hasStereoType('immutable')])
            return immutableFields
        } else {
            return emptyList
        }
    }
    
    def boolean hasImmutableFields(CmnFieldContainer it, boolean recursive) {
        if (it !== null && fields !== null && !fields.empty) {
           if (hasStereoType('immutable')) {
               return true
           }
           if (fields.exists[hasStereoType('immutable')]) {
               return true
           }
           if (recursive) {
                return hasImmutableFields(baseFieldContainer, true)
           }
        }
        return false
    }
    
    def Iterable allImmutableFields(CmnFieldContainer complexType) {
        val baseImmutableFields = complexType.baseFieldContainer.getImmutableFields(true).filter[!isCollection]
        val immutableFields = complexType.getImmutableFields(false).filter[!isCollection]
        if (!immutableFields.empty || !baseImmutableFields.empty) {
            val allImmutableFields = newArrayList
            allImmutableFields.addAll(baseImmutableFields)
            allImmutableFields.addAll(immutableFields)
            return allImmutableFields
        }
        return emptyList
    }

	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy