Skip to content

Commit

Permalink
Changes elide to only inject models annotated with @Inject (#1299)
Browse files Browse the repository at this point in the history
* Changes elide to only inject models annotated with @Inject

* Codacy fix

Co-authored-by: Aaron Klish <[email protected]>
  • Loading branch information
aklish and Aaron Klish authored May 1, 2020
1 parent 210314f commit e362c10
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
38 changes: 38 additions & 0 deletions elide-core/src/main/java/com/yahoo/elide/core/EntityBinding.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
Expand Down Expand Up @@ -89,6 +90,9 @@ public class EntityBinding {
@Getter
private AccessType accessType;

@Getter
private final boolean injected;

private EntityDictionary dictionary;

@Getter
Expand Down Expand Up @@ -122,6 +126,7 @@ public class EntityBinding {

/* empty binding constructor */
private EntityBinding() {
injected = false;
jsonApiType = null;
entityName = null;
apiVersion = NO_VERSION;
Expand Down Expand Up @@ -175,6 +180,7 @@ public EntityBinding(EntityDictionary dictionary,

// Map id's, attributes, and relationships
List<AccessibleObject> fieldOrMethodList = getAllFields();
injected = shouldInject();

if (fieldOrMethodList.stream().anyMatch(field -> field.isAnnotationPresent(Id.class))) {
accessType = AccessType.FIELD;
Expand Down Expand Up @@ -252,6 +258,17 @@ public List<AccessibleObject> getAllFields() {
return fields;
}

private List<AccessibleObject> getAllMethods() {
List<AccessibleObject> methods = new ArrayList<>();

methods.addAll(getInstanceMembers(entityClass.getDeclaredMethods(), (method) -> !method.isSynthetic()));
for (Class<?> type : inheritedTypes) {
methods.addAll(getInstanceMembers(type.getDeclaredMethods(), (method) -> !method.isSynthetic()));
}

return methods;
}

/**
* Bind fields of an entity including the Id field, attributes, and relationships.
*
Expand Down Expand Up @@ -634,6 +651,27 @@ public <A extends Annotation> A getMethodAnnotation(Class<A> annotationClass, St
return annotation == NO_ANNOTATION ? null : annotationClass.cast(annotation);
}

private boolean shouldInject() {
boolean hasField = getAllFields().stream()
.anyMatch(accessibleObject -> accessibleObject.isAnnotationPresent(Inject.class));

if (hasField) {
return true;
}

boolean hasMethod = getAllMethods().stream()
.anyMatch(accessibleObject -> accessibleObject.isAnnotationPresent(Inject.class));

if (hasMethod) {
return true;
}

boolean hasConstructor = Arrays.stream(entityClass.getConstructors())
.anyMatch(ctor -> ctor.getAnnotation(Inject.class) != null);

return hasConstructor;
}

private List<Class<?>> getInheritedTypes(Class<?> entityClass) {
ArrayList<Class<?>> results = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,11 @@ public String getNameFromAlias(Object entity, String alias) {
*/
public <T> void initializeEntity(T entity) {
if (entity != null) {
injector.inject(entity);
EntityBinding binding = getEntityBinding(entity.getClass());

if (binding.isInjected()) {
injector.inject(entity);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,93 @@ public void testBadLookupEntityClass() {
assertThrows(IllegalArgumentException.class, () -> lookupEntityClass(Object.class));
}

@Test
public void testFieldIsInjected() {
EntityDictionary testDictionary = new EntityDictionary(new HashMap<>());

@Include
class FieldInject {
@Inject
private String field;
}

testDictionary.bindEntity(FieldInject.class);

assertTrue(testDictionary.getEntityBinding(FieldInject.class).isInjected());
}

@Test
public void testInheritedFieldIsInjected() {
EntityDictionary testDictionary = new EntityDictionary(new HashMap<>());
class BaseClass {
@Inject
private String field;
}

@Include
class SubClass extends BaseClass {
private String anotherField;
}

testDictionary.bindEntity(SubClass.class);

assertTrue(testDictionary.getEntityBinding(SubClass.class).isInjected());
}

@Test
public void testMethodIsInjected() {
EntityDictionary testDictionary = new EntityDictionary(new HashMap<>());

@Include
class MethodInject {
@Inject
private void setField(String field) {
//NOOP
}
}

testDictionary.bindEntity(MethodInject.class);

assertTrue(testDictionary.getEntityBinding(MethodInject.class).isInjected());
}

@Test
public void testInhertedMethodIsInjected() {
EntityDictionary testDictionary = new EntityDictionary(new HashMap<>());
class BaseClass {
@Inject
private void setField(String field) {
//NOOP
}
}

@Include
class SubClass extends BaseClass {
private String anotherField;
}

testDictionary.bindEntity(SubClass.class);

assertTrue(testDictionary.getEntityBinding(SubClass.class).isInjected());
}

@Test
public void testConstructorIsInjected() {
EntityDictionary testDictionary = new EntityDictionary(new HashMap<>());

@Include
class ConstructorInject {
@Inject
public ConstructorInject(String field) {
//NOOP
}
}

testDictionary.bindEntity(ConstructorInject.class);

assertTrue(testDictionary.getEntityBinding(ConstructorInject.class).isInjected());
}

@Test
public void testFieldLookup() throws Exception {
bindEntity(Book.class);
Expand Down

0 comments on commit e362c10

Please sign in to comment.