use of org.terasology.reflection.metadata.DefaultClassMetadata in project Terasology by MovingBlocks.
the class PropertyProvider method createProperties.
public List<Property<?, ?>> createProperties(Object target) {
List<Property<?, ?>> properties = Lists.newArrayList();
try {
Class<?> type = target.getClass();
ReflectFactory reflectFactory = CoreRegistry.get(ReflectFactory.class);
CopyStrategyLibrary copyStrategies = new CopyStrategyLibrary(reflectFactory);
ClassMetadata<?, ?> classMetadata = new DefaultClassMetadata<>(new SimpleUri(), type, reflectFactory, copyStrategies);
for (Field field : getAllFields(type)) {
Annotation annotation = getFactory(field);
if (annotation != null) {
FieldMetadata<Object, ?> fieldMetadata = (FieldMetadata<Object, ?>) classMetadata.getField(field.getName());
PropertyFactory factory = factories.get(annotation.annotationType());
Property property = factory.create(target, fieldMetadata, field.getName(), annotation);
properties.add(property);
}
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return properties;
}
use of org.terasology.reflection.metadata.DefaultClassMetadata in project Terasology by MovingBlocks.
the class CopyStrategyLibrary method getStrategy.
// TODO: Consider CopyStrategyFactory system for Collections and similar
public CopyStrategy<?> getStrategy(Type genericType) {
Class<?> typeClass = ReflectionUtil.getClassOfType(genericType);
if (typeClass == null) {
logger.error("Cannot obtain class for type {}, using default strategy", genericType);
return defaultStrategy;
}
if (List.class.isAssignableFrom(typeClass)) {
// For lists, create the handler for the contained type and wrap in a list type handler
Type parameter = ReflectionUtil.getTypeParameter(genericType, 0);
if (parameter != null) {
CopyStrategy<?> contentStrategy = getStrategy(parameter);
return new ListCopyStrategy<>(contentStrategy);
}
logger.error("List field is not parametrized - using default strategy");
return new ListCopyStrategy<>(defaultStrategy);
} else if (Set.class.isAssignableFrom(typeClass)) {
// For sets:
Type parameter = ReflectionUtil.getTypeParameter(genericType, 0);
if (parameter != null) {
CopyStrategy<?> contentStrategy = getStrategy(parameter);
return new SetCopyStrategy<>(contentStrategy);
}
logger.error("Set field is not parametrized - using default strategy");
return new SetCopyStrategy<>(defaultStrategy);
} else if (Map.class.isAssignableFrom(typeClass)) {
// For Maps, create the handler for the value type
Type keyParameter = ReflectionUtil.getTypeParameter(genericType, 0);
CopyStrategy<?> keyStrategy;
if (keyParameter != null) {
keyStrategy = getStrategy(keyParameter);
} else {
logger.error("Map field is missing key parameter - using default strategy");
keyStrategy = defaultStrategy;
}
Type valueParameter = ReflectionUtil.getTypeParameter(genericType, 1);
CopyStrategy<?> valueStrategy;
if (valueParameter != null) {
valueStrategy = getStrategy(valueParameter);
} else {
logger.error("Map field is missing value parameter - using default strategy");
valueStrategy = defaultStrategy;
}
return new MapCopyStrategy<>(keyStrategy, valueStrategy);
} else if (strategies.containsKey(typeClass)) {
// For known types, just use the handler
return strategies.get(typeClass);
} else if (typeClass.getAnnotation(MappedContainer.class) != null) {
if (Modifier.isAbstract(typeClass.getModifiers()) || typeClass.isLocalClass() || (typeClass.isMemberClass() && !Modifier.isStatic(typeClass.getModifiers()))) {
logger.error("Type {} is not a valid mapped class", typeClass);
return defaultStrategy;
}
try {
ClassMetadata<?, ?> classMetadata = new DefaultClassMetadata<>(new SimpleUri(), typeClass, reflectFactory, this);
return new MappedContainerCopyStrategy<>(classMetadata);
} catch (NoSuchMethodException e) {
logger.error("Unable to create copy strategy for field of type {}: no publicly accessible default constructor", typeClass.getSimpleName());
return defaultStrategy;
}
} else {
logger.debug("Using default copy strategy for {}", typeClass);
strategies.put(typeClass, defaultStrategy);
return defaultStrategy;
}
}
use of org.terasology.reflection.metadata.DefaultClassMetadata in project Terasology by MovingBlocks.
the class MetadataBuilderTest method testTrivialMetadata.
@Test
public void testTrivialMetadata() throws Exception {
DefaultClassMetadata<Trivial> metadata = new DefaultClassMetadata<>(new SimpleUri(), Trivial.class, factory, copyStrategyLibrary);
assertNotNull(metadata);
assertEquals(0, metadata.getFieldCount());
assertTrue(metadata.isConstructable());
}
use of org.terasology.reflection.metadata.DefaultClassMetadata in project Terasology by MovingBlocks.
the class MetadataBuilderTest method testDetectsLackOfDefaultConstructor.
@Test
public void testDetectsLackOfDefaultConstructor() throws Exception {
DefaultClassMetadata<NoDefaultConstructor> metadata = new DefaultClassMetadata<>(new SimpleUri(), NoDefaultConstructor.class, factory, copyStrategyLibrary);
assertFalse(metadata.isConstructable());
}
use of org.terasology.reflection.metadata.DefaultClassMetadata in project Terasology by MovingBlocks.
the class TypeSerializationLibrary method getHandlerFor.
// TODO: Refactor
@SuppressWarnings("unchecked")
public TypeHandler<?> getHandlerFor(Type genericType) {
Class<?> typeClass = ReflectionUtil.getClassOfType(genericType);
if (typeClass == null) {
logger.error("Unabled to get class from type {}", genericType);
return null;
}
if (Enum.class.isAssignableFrom(typeClass)) {
return new EnumTypeHandler(typeClass);
} else if (List.class.isAssignableFrom(typeClass)) {
// For lists, createEntityRef the handler for the contained type and wrap in a list type handler
Type parameter = ReflectionUtil.getTypeParameter(genericType, 0);
if (parameter != null) {
TypeHandler<?> innerHandler = getHandlerFor(parameter);
if (innerHandler != null) {
return new ListTypeHandler<>(innerHandler);
}
}
logger.error("List field is not parametrized, or holds unsupported type");
return null;
} else if (Set.class.isAssignableFrom(typeClass)) {
// For sets:
Type parameter = ReflectionUtil.getTypeParameter(genericType, 0);
if (parameter != null) {
TypeHandler<?> innerHandler = getHandlerFor(parameter);
if (innerHandler != null) {
return new SetTypeHandler<>(innerHandler);
}
}
logger.error("Set field is not parametrized, or holds unsupported type");
return null;
} else if (Map.class.isAssignableFrom(typeClass)) {
// For Maps, createEntityRef the handler for the value type (and maybe key too?)
Type keyParameter = ReflectionUtil.getTypeParameter(genericType, 0);
Type contentsParameter = ReflectionUtil.getTypeParameter(genericType, 1);
if (keyParameter != null && contentsParameter != null && String.class == keyParameter) {
TypeHandler<?> valueHandler = getHandlerFor(contentsParameter);
if (valueHandler != null) {
return new StringMapTypeHandler<>(valueHandler);
}
}
logger.error("Map field is not parametrized, does not have a String key, or holds unsupported values");
} else if (typeHandlers.containsKey(typeClass)) {
// For known types, just use the handler
return typeHandlers.get(typeClass);
} else if (typeClass.getAnnotation(MappedContainer.class) != null && !Modifier.isAbstract(typeClass.getModifiers()) && !typeClass.isLocalClass() && !(typeClass.isMemberClass() && !Modifier.isStatic(typeClass.getModifiers()))) {
try {
ClassMetadata<?, ?> metadata = new DefaultClassMetadata<>(new SimpleUri(), typeClass, reflectFactory, copyStrategies);
MappedContainerTypeHandler<?> mappedHandler = new MappedContainerTypeHandler(typeClass, getFieldHandlerMap(metadata));
typeHandlers.put(typeClass, mappedHandler);
return mappedHandler;
} catch (NoSuchMethodException e) {
logger.error("Unable to register field of type {}: no publicly accessible default constructor", typeClass.getSimpleName());
return null;
}
} else {
logger.error("Unable to register field of type {}: not a supported type or MappedContainer", typeClass.getSimpleName());
}
return null;
}
Aggregations