
com.github.nill14.utils.init.inject.PojoInjectionDescriptor Maven / Gradle / Ivy
The newest version!
package com.github.nill14.utils.init.inject;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Set;
import java.util.stream.Stream;
import com.github.nill14.utils.init.api.IBeanDescriptor;
import com.github.nill14.utils.init.api.IParameterType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.reflect.TypeToken;
@SuppressWarnings("serial")
public class PojoInjectionDescriptor implements Serializable, IBeanDescriptor {
private final ImmutableList fields;
private final ImmutableList methods;
private final ImmutableList constructors;
private final TypeToken typeToken;
private final Set> interfaces;
@SuppressWarnings("unchecked")
public PojoInjectionDescriptor(IParameterType parameterType) {
this((TypeToken) TypeToken.of(parameterType.getGenericType()));
}
@SuppressWarnings("unchecked")
public PojoInjectionDescriptor(Class extends T> pojoClazz) {
this(TypeToken.of((Class) pojoClazz));
}
public PojoInjectionDescriptor(TypeToken typeToken) {
Preconditions.checkNotNull(typeToken);
this.typeToken = typeToken;
interfaces = typeToken.getTypes().interfaces().rawTypes();
fields = ImmutableList.copyOf(
injectableFields(ReflectionUtils.getInstanceFields(typeToken), typeToken.getRawType()).iterator());
methods = ImmutableList.copyOf(
injectableMethods(ReflectionUtils.getInstanceMethods(typeToken), typeToken.getRawType()).iterator());
constructors = ImmutableList.copyOf(
injectableConstructors(Stream.of(typeToken.getRawType().getDeclaredConstructors())).iterator());
// ImmutableList.Builder builder = ImmutableList.builder();
// for (FieldInjectionDescriptor f : fields) {
// builder.add(f.getParameterType());
// }
// for (MethodInjectionDescriptor m : methods) {
// builder.addAll(m.getParameterTypes());
// }
// TODO gather optional and mandatory dependencies
}
@Override
public ImmutableList getFieldDescriptors() {
return fields;
}
@Override
public ImmutableList getMethodDescriptors() {
return methods;
}
@Override
public ImmutableList getConstructorDescriptors() {
return constructors;
}
@Override
public Set> getInterfaces() {
return interfaces;
}
@Override
public Set> getDeclaredTypes() {
return typeToken.getTypes().rawTypes();
}
private Stream extends ConstructorInjectionDescriptor> injectableConstructors(Stream> constructors) {
return constructors.map(c -> {
if (c.getParameterCount() == 0
|| c.isAnnotationPresent(javax.inject.Inject.class)
|| c.isAnnotationPresent(com.google.inject.Inject.class)) {
return new ConstructorInjectionDescriptor(c);
}
else return null;
}).filter(x -> x != null);
}
private Stream extends MethodInjectionDescriptor> injectableMethods(Stream nonStaticMethods, Class> declaringClass) {
return nonStaticMethods.map(m -> {
if (m.isAnnotationPresent(javax.inject.Inject.class)
|| m.isAnnotationPresent(com.google.inject.Inject.class)) {
return new MethodInjectionDescriptor(m, declaringClass);
}
else return null;
}).filter(x -> x != null);
}
private Stream extends FieldInjectionDescriptor> injectableFields(Stream nonStaticFields, Class> declaringClass) {
return nonStaticFields.map(f -> {
if (f.isAnnotationPresent(javax.inject.Inject.class)
|| f.isAnnotationPresent(com.google.inject.Inject.class)) {
return new FieldInjectionDescriptor(f, declaringClass);
}
else return null;
}).filter(x -> x != null);
}
@SuppressWarnings("unchecked")
@Override
public Class getRawType() {
return (Class) typeToken.getRawType();
}
@Override
public Type getGenericType() {
return typeToken.getType();
}
@Override
public boolean canBeInstantiated() {
Class> clazz = typeToken.getRawType();
return !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers()) && !constructors.isEmpty();
}
@Override
public String toString() {
return typeToken.toString();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("Proxy required");
}
private Object writeReplace() {
return new SerializableProxy(this);
}
private static class SerializableProxy implements Serializable {
private final TypeToken> token;
public SerializableProxy(PojoInjectionDescriptor> pd) {
this.token = pd.typeToken;
}
private Object readResolve() {
return new PojoInjectionDescriptor<>(token);
}
}
@Override
public TypeToken getToken() {
return typeToken;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((typeToken == null) ? 0 : typeToken.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PojoInjectionDescriptor other = (PojoInjectionDescriptor) obj;
if (typeToken == null) {
if (other.typeToken != null)
return false;
} else if (!typeToken.equals(other.typeToken))
return false;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy