package org.deephacks.confit.internal.core.schema; import org.deephacks.confit.Config; import org.deephacks.confit.model.Bean; import org.deephacks.confit.model.BeanId; import org.deephacks.confit.model.Schema; import org.deephacks.confit.serialization.Conversion; import org.deephacks.confit.spi.SchemaManager; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.deephacks.confit.model.Events.CFG101_SCHEMA_NOT_EXIST; import static org.deephacks.confit.model.Events.CFG102_NOT_CONFIGURABLE; /** * In memory SchemaManager. */ public class DefaultSchemaManager extends SchemaManager { private static final HashMap<String, Schema> NAME_TO_SCHEMA = new HashMap<>(); private static final HashMap<Class<?>, Schema> CLASS_TO_SCHEMA = new HashMap<>(); private static final Conversion CONVERSION = Conversion.get(); public DefaultSchemaManager() { } @Override public synchronized Map<String, Schema> getSchemas() { return NAME_TO_SCHEMA; } @Override public void setSchema(Collection<Bean> beans) { setSchema(beans, new ArrayList<BeanId>()); } private void setSchema(Collection<Bean> beans, List<BeanId> seen) { for (Bean bean : beans) { if (contains(seen, bean.getId())) { continue; } seen.add(bean.getId()); Schema schema = NAME_TO_SCHEMA.get(bean.getId().getSchemaName()); if (schema == null) { throw CFG101_SCHEMA_NOT_EXIST(bean.getId().getSchemaName()); } bean.set(schema); for (BeanId id : bean.getReferences()) { schema = NAME_TO_SCHEMA.get(id.getSchemaName()); id.set(schema); Bean refBean = id.getBean(); if (refBean != null) { setSchema(Arrays.asList(refBean), seen); } } } } private boolean contains(List<BeanId> seen, BeanId id) { for (BeanId anId : seen) { if (anId == id) { return true; } } return false; } @Override public Schema getSchema(String schemaName) { Schema schema = NAME_TO_SCHEMA.get(schemaName); if (schema == null) { throw CFG101_SCHEMA_NOT_EXIST(schemaName); } return schema; } @Override public Schema getSchema(Class<?> cls) { Schema schema = CLASS_TO_SCHEMA.get(cls); if(schema == null) { register(cls); schema = CLASS_TO_SCHEMA.get(cls); } return schema; } @Override public void register(Class<?>... classes) { for (Class<?> cls : classes) { if (CLASS_TO_SCHEMA.get(cls) != null) { continue; } Config config = cls.getAnnotation(Config.class); if (config == null) { throw CFG102_NOT_CONFIGURABLE(cls); } String schemaName = config.name(); if (schemaName == null || "".equals(schemaName)) { schemaName = cls.getName(); } Schema schema = CONVERSION.convert(cls, Schema.class); CLASS_TO_SCHEMA.put(cls, schema); NAME_TO_SCHEMA.put(schemaName, schema); for (Class<?> refCls : schema.getReferenceSchemaTypes()) { if (CLASS_TO_SCHEMA.get(refCls) != null) { register(cls); } } } } @Override public Schema remove(Class<?> cls) { return CLASS_TO_SCHEMA.remove(cls); } @Override public void validateSchema(Collection<Bean> beans) { SchemaValidator.validateSchema(beans); } @Override public Object convertBean(Bean bean) { Schema schema = getSchema(bean.getId().getSchemaName()); return CONVERSION.convert(bean, schema.getClassType()); } @Override public Collection<Object> convertBeans(Collection<Bean> beans) { ArrayList<Object> objects = new ArrayList<>(); for (Bean bean : beans) { objects.add(convertBean(bean)); } return objects; } @Override public Collection<Bean> convertObjects(Collection<Object> objects) { return CONVERSION.convert(objects, Bean.class); } @Override public Bean convertObject(Object object) { return CONVERSION.convert(object, Bean.class); } }