/** * This method is for use in situations where metadata is being used generically and the actual type of the value cannot be * * @param object The instance of this class to copy * @return A copy of the given object, or null if object is not of the type described by this metadata. */ public T copyRaw(Object object) { if (getType().isInstance(object)) { return copy(getType().cast(object)); } return null; }
@Override public void register(SimpleUri uri, Class<? extends T> clazz) { ClassMetadata<? extends T, ?> metadata = createMetadata(clazz, reflectFactory, copyStrategyLibrary, uri); if (metadata != null) { classLookup.put(clazz, metadata); ClassMetadata<? extends T, ?> prev = uriLookup.put(uri.getObjectName(), uri.getModuleName(), metadata); if (prev != null && !prev.equals(metadata)) { logger.warn("Duplicate entry for '{}': {} and {}", uri, prev.getType(), metadata.getType()); } } }
private <T> Map<Class<? extends T>, Integer> generateIds(ClassLibrary<T> classLibrary) { Map<Class<? extends T>, Integer> result = Maps.newHashMap(); for (ClassMetadata<? extends T, ?> metadata : classLibrary) { int index = result.size(); result.put(metadata.getType(), index); int fieldId = 0; for (FieldMetadata<?, ?> field : metadata.getFields()) { if (fieldId >= 256) { logger.error("Class {} has too many fields (>255), serialization will be incomplete", metadata.getUri()); break; } field.setId((byte) fieldId); fieldId++; } } return result; }
@Override public <U extends WorldGeneratorPlugin> List<U> instantiateAllOfType(Class<U> ofType) { List<U> result = Lists.newArrayList(); for (ClassMetadata classMetadata : library) { if (ofType.isAssignableFrom(classMetadata.getType()) && classMetadata.isConstructable() && classMetadata.getType().getAnnotation(RegisterPlugin.class) != null) { U item = ofType.cast(classMetadata.newInstance()); if (item != null) { result.add(item); } } } return result; } }
UIWidget element = elementMetadata.newInstance(); if (id != null) { FieldMetadata<?, ?> fieldMetadata = elementMetadata.getField(ID_FIELD); if (fieldMetadata == null) { logger.warn("UIWidget type {} lacks id field", elementMetadata.getUri()); } else { fieldMetadata.setValue(element, id); for (FieldMetadata<? extends UIWidget, ?> field : elementMetadata.getFields()) { if (jsonObject.has(field.getSerializationName())) { unknownFields.remove(field.getSerializationName()); if (field.getName().equals(CONTENTS_FIELD) && UILayout.class.isAssignableFrom(elementMetadata.getType())) { continue; if (UILayout.class.isAssignableFrom(elementMetadata.getType())) { UILayout<LayoutHint> layout = (UILayout<LayoutHint>) element; ReflectionUtil.getTypeParameter(elementMetadata.getType().getGenericSuperclass(), 0); if (jsonObject.has(CONTENTS_FIELD)) { for (JsonElement child : jsonObject.getAsJsonArray(CONTENTS_FIELD)) {
/** * Deserializes a Collection of name-values onto an object * * @param target The object to deserialize onto * @param values The collection of values to apply to the object * @param check A check to filter which fields to deserialize */ public void deserializeOnto(Object target, PersistedDataMap values, DeserializeFieldCheck check, DeserializationContext context) { for (Map.Entry<String, PersistedData> field : values.entrySet()) { FieldMetadata<?, ?> fieldInfo = classMetadata.getField(field.getKey()); if (fieldInfo != null && check.shouldDeserialize(classMetadata, fieldInfo)) { deserializeOnto(target, fieldInfo, field.getValue(), context); } else if (fieldInfo == null) { logger.warn("Cannot deserialize unknown field '{}' onto '{}'", field.getKey(), classMetadata.getUri()); } } }
private <T> Map<Class<? extends T>, Integer> applySerializationInfo(List<NetData.SerializationInfo> infoList, ClassLibrary<T> classLibrary) { Map<Class<? extends T>, Integer> idTable = Maps.newHashMap(); for (NetData.SerializationInfo info : infoList) { ClassMetadata<? extends T, ?> metadata = classLibrary.getMetadata(new SimpleUri(info.getName())); if (metadata != null) { idTable.put(metadata.getType(), info.getId()); for (int i = 0; i < info.getFieldIds().size(); ++i) { FieldMetadata<?, ?> field = metadata.getField(info.getFieldName(i)); if (field != null) { field.setId(info.getFieldIds().byteAt(i)); } else { logger.error("Server has unknown field '{}' on '{}'", info.getFieldName(i), info.getName()); } } } else { logger.error("Server has unknown class '{}'", info.getName()); } } return idTable; }
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; }
private Map<FieldMetadata<?, ?>, TypeHandler> getFieldHandlerMap(ClassMetadata<?, ?> type) { Map<FieldMetadata<?, ?>, TypeHandler> handlerMap = Maps.newHashMap(); for (FieldMetadata<?, ?> field : type.getFields()) { TypeHandler<?> handler = getHandlerFor(field.getField().getGenericType()); if (handler != null) { handlerMap.put(field, handler); } else { logger.info("Unsupported field: '{}.{}'", type.getUri(), field.getName()); } } return handlerMap; }
public AbstractClassLibrary(AbstractClassLibrary<T> factory, CopyStrategyLibrary copyStrategies) { this.reflectFactory = factory.reflectFactory; this.copyStrategyLibrary = copyStrategies; for (Table.Cell<Name, Name, ClassMetadata<? extends T, ?>> cell: factory.uriLookup.cellSet()) { Name objectName = cell.getRowKey(); Name moduleName = cell.getColumnKey(); ClassMetadata<? extends T, ?> oldMetaData = cell.getValue(); Class<? extends T> clazz = oldMetaData.getType(); SimpleUri uri = oldMetaData.getUri(); ClassMetadata<? extends T, ?> metadata = createMetadata(clazz, factory.reflectFactory, copyStrategies, uri); if (metadata != null) { classLookup.put(clazz, metadata); uriLookup.put(objectName, moduleName, metadata); } else { throw new RuntimeException("Failed to create copy of class library"); } } }
/** * returns the class representing the block family based off the registered id. * * @param uri * @return */ public Class<? extends BlockFamily> getBlockFamily(String uri) { ClassMetadata<? extends BlockFamily, ?> resolved = library.resolve(uri); if (uri == null || uri.isEmpty() || resolved == null) { logger.error(" Failed to resolve Blockfamily {}", uri); return SymmetricFamily.class; } return resolved.getType(); }
@Override public T copy(T value) { if (value != null) { return classMetadata.copy(value); } return null; } }
/** * @return A new instance of this class. */ public T newInstance() { Preconditions.checkState(isConstructable(), "Cannot construct '" + this + "' - no accessible default constructor"); return constructor.construct(); }
/** * Creates a class metatdata * * @param uri The uri that identifies this type * @param type The type to create the metadata for * @param factory A reflection library to provide class construction and field get/set functionality * @param copyStrategyLibrary A copy strategy library * @throws NoSuchMethodException If the class has no default constructor */ public ClassMetadata(SimpleUri uri, Class<T> type, ReflectFactory factory, CopyStrategyLibrary copyStrategyLibrary, Predicate<Field> includedFieldPredicate) throws NoSuchMethodException { if (System.getSecurityManager() != null) { System.getSecurityManager().checkPermission(CREATE_CLASS_METADATA); } this.uri = uri; this.clazz = type; if (!type.isInterface() && !Modifier.isAbstract(type.getModifiers())) { this.constructor = factory.createConstructor(type); } else { this.constructor = null; } addFields(copyStrategyLibrary, factory, includedFieldPredicate); }
/** * Scans the class this metadata describes, adding all fields to the class' metadata. * * @param copyStrategyLibrary The library of copy strategies * @param factory The reflection provider */ private void addFields(CopyStrategyLibrary copyStrategyLibrary, ReflectFactory factory, Predicate<Field> includedFieldsPredicate) { for (Field field : ReflectionUtils.getAllFields(clazz, includedFieldsPredicate)) { if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) { continue; } CopyStrategy<?> copyStrategy = copyStrategyLibrary.getStrategy(field.getGenericType()); try { FIELD metadata = createField(field, copyStrategy, factory); if (metadata != null) { fields.put(metadata.getName().toLowerCase(Locale.ENGLISH), metadata); } } catch (InaccessibleFieldException e) { logger.error("Could not create metadata for field '{}' of type '{}', may be private.'", field, clazz); } } }
public ReflectionProvider(T target, Context context) { try { ReflectFactory reflectFactory = context.get(ReflectFactory.class); CopyStrategyLibrary copyStrategies = context.get(CopyStrategyLibrary.class); ClassMetadata<T, ?> classMetadata = new DefaultClassMetadata<>(new SimpleUri(), (Class<T>) target.getClass(), reflectFactory, copyStrategies); for (Field field : getAllFields(target.getClass(), and(withAnnotation(Range.class), or(withType(Float.TYPE), withType(Float.class))))) { Range range = field.getAnnotation(Range.class); FieldMetadata<T, Float> fieldMetadata = (FieldMetadata<T, Float>) classMetadata.getField(field.getName()); Property property = new FloatProperty(target, fieldMetadata, range.min(), range.max()); properties.add(property); } } catch (NoSuchMethodException e) { logger.error("Cannot provide provide inspection for {}, does not have a default constructor", target.getClass()); } }
@Override public String toString() { if (uri.isValid()) { return uri.toString(); } return getType().toString(); }
@Override public <TYPE extends T> TYPE copy(TYPE object) { ClassMetadata<TYPE, ?> info = getMetadata(object); if (info != null) { return info.copy(object); } return null; }