use of cern.modesti.schema.category.CategoryImpl in project modesti by jlsalmon.
the class SchemaInitialiser method loadSchemas.
/**
* Load all schemas inside plugins.
*
* @return the list of schemas that were found on the classpath
* @throws IOException
* @throws URISyntaxException
*/
private List<SchemaImpl> loadSchemas() throws IOException, URISyntaxException {
List<SchemaImpl> schemas = new ArrayList<>();
Map<String, List<SchemaImpl>> pluginSchemas = loadPluginSchemas();
Map<String, List<CategoryImpl>> pluginCategories = loadPluginCategories();
Map<String, List<DatasourceImpl>> pluginDatasources = loadPluginDatasources();
for (Map.Entry<String, List<SchemaImpl>> entry : pluginSchemas.entrySet()) {
for (SchemaImpl schema : entry.getValue()) {
List<Category> categories = new ArrayList<>();
List<Datasource> datasources = new ArrayList<>();
// Skip over abstract schemas
if (schema.isAbstract()) {
continue;
}
// Merge in the parent schema if it is specified
String parent = schema.getParent();
if (parent != null) {
Schema parentSchema = getSchema(pluginSchemas, parent);
if (parentSchema == null) {
throw new IllegalArgumentException(format("Schema %s extends from unknown parent schema %s", schema.getId(), parent));
}
categories.addAll(parentSchema.getCategories());
datasources.addAll(parentSchema.getDatasources());
schema.setIdProperty(parentSchema.getIdProperty());
schema.setSelectableStates(parentSchema.getSelectableStates());
schema.setRowCommentStates(parentSchema.getRowCommentStates());
}
// Attach categories that are specified in the schema
for (Category category : schema.getCategories()) {
boolean categoryFound = false;
for (Map.Entry<String, List<CategoryImpl>> categoryEntry : pluginCategories.entrySet()) {
if (categoryEntry.getValue().contains(category)) {
categories.add(categoryEntry.getValue().get(categoryEntry.getValue().indexOf(category)));
categoryFound = true;
}
}
if (!categoryFound) {
throw new IllegalArgumentException(format("Category %s was not found for schema %s", category.getId(), schema.getId()));
}
// TODO: support referencing another field by name to avoid duplicate field definitions
}
// Attach datasources that are specified in the schema
for (Datasource datasource : schema.getDatasources()) {
boolean datasourceFound = false;
for (Map.Entry<String, List<DatasourceImpl>> datasourceEntry : pluginDatasources.entrySet()) {
if (datasourceEntry.getValue().contains(datasource)) {
datasources.add(datasourceEntry.getValue().get(datasourceEntry.getValue().indexOf(datasource)));
datasourceFound = true;
}
}
if (!datasourceFound) {
throw new IllegalArgumentException(format("Datasource %s was not found for schema %s", datasource.getId(), schema.getId()));
}
}
// Process any overrides to the core categories
for (Category override : schema.getOverrides()) {
if (categories.contains(override)) {
Category overridden = mergeCategories(categories.get(categories.indexOf(override)), override);
categories.set(categories.indexOf(override), overridden);
}
}
// Process any overrides to the core datasources
for (Datasource override : schema.getDatasourceOverrides()) {
if (datasources.contains(override)) {
Category overridden = mergeCategories(datasources.get(datasources.indexOf(override)), override);
datasources.set(datasources.indexOf(override), new DatasourceImpl((DatasourceImpl) overridden));
}
}
schema.setCategories(categories);
schema.setDatasources(datasources);
// Invoke any post processors
Map<String, SchemaPostProcessor> postProcessors = applicationContext.getBeansOfType(SchemaPostProcessor.class);
for (SchemaPostProcessor postProcessor : postProcessors.values()) {
schema = (SchemaImpl) postProcessor.postProcess(schema);
}
schemas.add(schema);
}
}
String loadedPlugIns = schemas.stream().map(p -> p.getId()).collect(Collectors.joining(", "));
log.trace("loaded {} schemas [{}]", schemas.size(), loadedPlugIns);
return schemas;
}
use of cern.modesti.schema.category.CategoryImpl in project modesti by jlsalmon.
the class SchemaInitialiser method mergeCategories.
/**
* Merge two {@link Category} instances, copying the fields defined in the
* overriding category to the overridden category.
*
* @param overridden the base category to merge into
* @param override the overriding category to merge from
* @return a new category containing the result of the merge
*/
private Category mergeCategories(Category overridden, Category override) {
overridden = new CategoryImpl((CategoryImpl) overridden);
List<Field> newFields = new ArrayList<>();
List<Field> oldFields = overridden.getFields();
for (Field newField : override.getFields()) {
if (!oldFields.contains(newField)) {
newFields.add(newField);
} else {
oldFields.set(oldFields.indexOf(newField), mergeFields(oldFields.get(oldFields.indexOf(newField)), newField));
}
}
// Copy the editable state list.
if (override.getEditable() != null) {
overridden.setEditable(override.getEditable());
}
// Copy the constraint list
if (override.getConstraints() != null) {
overridden.setConstraints(override.getConstraints());
}
overridden.getFields().addAll(newFields);
return overridden;
}
Aggregations