com.blogspot.toomuchcoding.spock.subjcollabs.FieldRetriever.groovy Maven / Gradle / Ivy
package com.blogspot.toomuchcoding.spock.subjcollabs
import groovy.transform.PackageScope
import org.codehaus.groovy.reflection.ClassInfo
import org.spockframework.runtime.model.FieldInfo
import java.lang.reflect.Field
@PackageScope
class FieldRetriever {
Map getAllUnsetFields(Collection injectionCandidates, FieldInfo fieldInfo, Object subject) {
Map fields = getAllMatchingFields(injectionCandidates, fieldInfo)
return fields.findAll { Field field, Field injectionCandidate -> field.get(subject) == null }
}
private Map getAllMatchingFields(Collection injectionCandidates, FieldInfo fieldInfo) {
List fields = getAllFieldsFromSubject(fieldInfo.type, [])
return getMatchingFieldsBasingOnTypeAndPropertyName(injectionCandidates, fields)
}
private List getAllFieldsFromSubject(Class type, List fields) {
fields.addAll(type.declaredFields.findAll { Field field -> !field.isSynthetic() && field.type != ClassInfo })
if (type.superclass != null) {
fields.addAll(getAllFieldsFromSubject(type.superclass, fields))
}
fields*.setAccessible(true)
return fields
}
private Map getMatchingFieldsBasingOnTypeAndPropertyName(Collection injectionCandidates, List allFields) {
Map matchingFields = [:]
injectionCandidates.each { Field injectionCandidate ->
List matchingTypes = allFields.findAll { it.type == injectionCandidate.type }
Field injectionCandidateByNameAndType = matchingTypes.find { it.name.equalsIgnoreCase(injectionCandidate.name) }
if (injectionCandidateByNameAndType) {
matchingFields[injectionCandidateByNameAndType] = injectionCandidate
} else {
matchingFields = matchingFields << matchingTypes.collectEntries { [(it) : injectionCandidate] }
}
}
return matchingFields
}
}