package io.cattle.platform.api.schema; import io.cattle.platform.util.type.InitializationTask; import io.github.ibuildthecloud.gdapi.factory.SchemaFactory; import io.github.ibuildthecloud.gdapi.factory.impl.AbstractSchemaFactory; import io.github.ibuildthecloud.gdapi.factory.impl.SubSchemaFactory; import io.github.ibuildthecloud.gdapi.json.JsonMapper; import io.github.ibuildthecloud.gdapi.model.Field; import io.github.ibuildthecloud.gdapi.model.Schema; import io.github.ibuildthecloud.gdapi.model.impl.FieldImpl; import io.github.ibuildthecloud.gdapi.model.impl.SchemaImpl; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; public class FileSchemaFactory extends AbstractSchemaFactory implements InitializationTask { @Inject JsonMapper jsonMapper; @Inject @Named("CoreSchemaFactory") SchemaFactory schemaFactory; String file, id; Map<String, Schema> schemaMap = new TreeMap<>(); Map<String, Class<?>> schemaClasses = new HashMap<>(); List<Schema> schemas = new ArrayList<>(); boolean init; @Override public synchronized void start() { if (init) { return; } if (schemaFactory instanceof SubSchemaFactory) { ((SubSchemaFactory) schemaFactory).init(); } ClassLoader cl = Thread.currentThread().getContextClassLoader(); try(InputStream is = cl.getResourceAsStream(file)) { ObjectInputStream ois = new ObjectInputStream(is); @SuppressWarnings("unchecked") List<Schema> serializedSchemas = (List<Schema>) ois.readObject(); for (Schema schema : serializedSchemas) { ((SchemaImpl) schema).setType("schema"); schema.getActions().clear(); schema.getLinks().clear(); copyAccessors(schema); schemaMap.put(schema.getId().toLowerCase(), schema); if (StringUtils.isNotBlank(schema.getPluralName())) { schemaMap.put(schema.getPluralName().toLowerCase(), schema); } schemas.add(schema); } } catch (IOException e) { throw new IllegalStateException(e); } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } init = true; } @PostConstruct protected void init() { if (this.id == null) { this.id = "v1-" + StringUtils.substringAfterLast(file, "/").split("[.]")[0]; } } protected void copyAccessors(Schema schema) { SchemaFactory parentSchemaFactory = schemaFactory; Class<?> clz = parentSchemaFactory.getSchemaClass(schema.getId()); if (clz == null) { return; } schemaClasses.put(schema.getId().toLowerCase(), clz); Schema parentSchema = parentSchemaFactory.getSchema(clz); for (Map.Entry<String, Field> entry : schema.getResourceFields().entrySet()) { ((FieldImpl) entry.getValue()).setName(entry.getKey()); Field parentField = parentSchema.getResourceFields().get(entry.getKey()); if (parentField == null || !(parentField instanceof FieldImpl)) { continue; } ((FieldImpl) entry.getValue()).setReadMethod(((FieldImpl) parentField).getReadMethod()); } } public String getFile() { return file; } public void setFile(String file) { this.file = file; } @Override public String getId() { return id; } @Override public List<Schema> listSchemas() { return schemas; } @Override public Schema getSchema(String type) { if (type == null) { return null; } return schemaMap.get(type.toLowerCase()); } @Override public Schema getSchema(Class<?> clz) { Schema s = schemaFactory.getSchema(clz); return s == null ? null : getSchema(s.getId()); } @Override public Class<?> getSchemaClass(String type) { Schema schema = getSchema(type); return schema == null ? null : schemaFactory.getSchemaClass(schema.getId()); } @Override public Schema registerSchema(Object obj) { throw new UnsupportedOperationException(); } @Override public Schema parseSchema(String name) { throw new UnsupportedOperationException(); } public void setId(String id) { this.id = id; } public SchemaFactory getSchemaFactory() { return schemaFactory; } public void setSchemaFactory(SchemaFactory schemaFactory) { this.schemaFactory = schemaFactory; } }