package io.github.ibuildthecloud.gdapi.factory.impl; import io.cattle.platform.archaius.util.ArchaiusUtil; import io.github.ibuildthecloud.gdapi.factory.SchemaFactory; import io.github.ibuildthecloud.gdapi.model.Field; import io.github.ibuildthecloud.gdapi.model.FieldType; import io.github.ibuildthecloud.gdapi.model.Filter; import io.github.ibuildthecloud.gdapi.model.Schema; import io.github.ibuildthecloud.gdapi.model.impl.SchemaImpl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import com.netflix.config.DynamicBooleanProperty; public class SubSchemaFactory extends AbstractSchemaFactory implements SchemaFactory { private static DynamicBooleanProperty SERIALIZE = ArchaiusUtil.getBoolean("serialize.schemas"); SchemaFactory schemaFactory; String id; Map<String, Schema> schemaMap; List<SchemaImpl> schemaList = new ArrayList<SchemaImpl>(); List<SchemaPostProcessor> postProcessors = new ArrayList<SchemaPostProcessor>(); boolean init = false; public synchronized void init() { if (init) { return; } schemaMap = new HashMap<String, Schema>(); if (schemaFactory instanceof SubSchemaFactory) { ((SubSchemaFactory)schemaFactory).init(); } List<SchemaImpl> result = new ArrayList<SchemaImpl>(); for (Schema schema : schemaFactory.listSchemas()) { if (schema instanceof SchemaImpl) { /* Copy */ SchemaImpl impl = new SchemaImpl((SchemaImpl)schema); for (SchemaPostProcessor post : postProcessors) { impl = post.postProcessRegister(impl, this); if (impl == null) { break; } } if (impl != null) { result.add(impl); schemaMap.put(impl.getId(), impl); } } } schemaList = result; for (SchemaImpl schema : schemaList) { for (SchemaPostProcessor post : postProcessors) { schema = post.postProcess(schema, this); } } for (SchemaImpl schema : schemaList) { prune(schema); } if (SERIALIZE.get()) { serializeSchema(listSchemas(), getId()); synchronized (schemaFactory) { serializeSchema(schemaFactory.listSchemas(), schemaFactory.getId()); } } init = true; } protected static void serializeSchema(List<Schema> schemaList, String id) { try(FileOutputStream fos = new FileOutputStream(new File(id + ".ser"))) { ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(schemaList); oos.close(); } catch (IOException e) { throw new IllegalStateException(e); } } protected void prune(SchemaImpl schema) { Map<String, Field> fields = schema.getResourceFields(); Map<String, Filter> filters = schema.getCollectionFilters(); for (String name : new HashSet<String>(fields.keySet())) { Field field = fields.get(name); List<FieldType> subTypeEnums = field.getSubTypeEnums(); List<String> subTypes = field.getSubTypes(); for (int i = 0; i < subTypeEnums.size(); i++) { if (subTypeEnums.get(i) == FieldType.TYPE && !schemaMap.containsKey(subTypes.get(i)) && !"type".equals(subTypes.get(i))) { fields.remove(name); filters.remove(name); break; } } } Iterator<String> childrenIter = schema.getChildren().iterator(); while (childrenIter.hasNext()) { if (!schemaMap.containsKey(childrenIter.next())) { childrenIter.remove(); } } } @Override public String getId() { return id; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public List<Schema> listSchemas() { return (List)schemaList; } @Override public Schema getSchema(Class<?> clz) { return getSchema(schemaFactory.getSchemaName(clz)); } @Override public Schema getSchema(String type) { Schema parentSchema = schemaFactory.getSchema(type); return parentSchema == null ? null : schemaMap.get(parentSchema.getId()); } @Override public Class<?> getSchemaClass(String type) { Schema schema = getSchema(type); return schema == null ? null : schemaFactory.getSchemaClass(type); } @Override public Schema registerSchema(Object obj) { throw new UnsupportedOperationException(); } @Override public Schema parseSchema(String name) { throw new UnsupportedOperationException(); } public SchemaFactory getSchemaFactory() { return schemaFactory; } public List<SchemaPostProcessor> getPostProcessors() { return postProcessors; } public void setPostProcessors(List<SchemaPostProcessor> postProcessors) { this.postProcessors = postProcessors; } public void setId(String id) { this.id = id; } public void setSchemaFactory(SchemaFactory schemaFactory) { this.schemaFactory = schemaFactory; } }