use of org.structr.core.entity.SchemaNode in project structr by structr.
the class SchemaService method calculateHierarchy.
// ----- private methods -----
private static void calculateHierarchy() {
try (final Tx tx = StructrApp.getInstance().tx()) {
final List<SchemaNode> schemaNodes = StructrApp.getInstance().nodeQuery(SchemaNode.class).getAsList();
final Set<String> alreadyCalculated = new HashSet<>();
final Map<String, SchemaNode> map = new LinkedHashMap<>();
// populate lookup map
for (final SchemaNode schemaNode : schemaNodes) {
map.put(schemaNode.getName(), schemaNode);
}
// calc hierarchy
for (final SchemaNode schemaNode : schemaNodes) {
final int relCount = schemaNode.getProperty(SchemaNode.relatedFrom).size() + schemaNode.getProperty(SchemaNode.relatedTo).size();
final int level = recursiveGetHierarchyLevel(map, alreadyCalculated, schemaNode, 0);
schemaNode.setProperty(SchemaNode.hierarchyLevel, level);
schemaNode.setProperty(SchemaNode.relCount, relCount);
}
tx.success();
} catch (FrameworkException fex) {
logger.warn("", fex);
}
}
use of org.structr.core.entity.SchemaNode in project structr by structr.
the class SchemaService method reloadSchema.
public static boolean reloadSchema(final ErrorBuffer errorBuffer, final String initiatedBySessionId) {
final ConfigurationProvider config = StructrApp.getConfiguration();
final App app = StructrApp.getInstance();
boolean success = true;
// compiling must only be done once
if (compiling.compareAndSet(false, true)) {
try {
final Map<String, Map<String, PropertyKey>> removedClasses = new HashMap<>(config.getTypeAndPropertyMapping());
final Map<String, GraphQLType> graphQLTypes = new LinkedHashMap<>();
final NodeExtender nodeExtender = new NodeExtender(initiatedBySessionId);
final Set<String> dynamicViews = new LinkedHashSet<>();
try (final Tx tx = app.tx()) {
// collect auto-generated schema nodes
SchemaService.ensureBuiltinTypesExist();
// add schema nodes from database
for (final SchemaNode schemaInfo : app.nodeQuery(SchemaNode.class).getAsList()) {
schemaInfo.handleMigration();
final String sourceCode = SchemaHelper.getSource(schemaInfo, errorBuffer);
if (sourceCode != null) {
final String className = schemaInfo.getClassName();
// only load dynamic node if there were no errors while generating
// the source code (missing modules etc.)
nodeExtender.addClass(className, sourceCode);
dynamicViews.addAll(schemaInfo.getDynamicViews());
// initialize GraphQL engine as well
schemaInfo.initializeGraphQL(graphQLTypes);
}
}
// collect relationship classes
for (final SchemaRelationshipNode schemaRelationship : app.nodeQuery(SchemaRelationshipNode.class).getAsList()) {
nodeExtender.addClass(schemaRelationship.getClassName(), schemaRelationship.getSource(errorBuffer));
dynamicViews.addAll(schemaRelationship.getDynamicViews());
// initialize GraphQL engine as well
schemaRelationship.initializeGraphQL(graphQLTypes);
}
// this is a very critical section :)
synchronized (SchemaService.class) {
// clear propagating relationship cache
SchemaRelationshipNode.clearPropagatingRelationshipTypes();
// compile all classes at once and register
final Map<String, Class> newTypes = nodeExtender.compile(errorBuffer);
for (final Class newType : newTypes.values()) {
// instantiate classes to execute static initializer of helpers
try {
// do full reload
config.registerEntityType(newType);
newType.newInstance();
} catch (Throwable ignore) {
}
}
// calculate difference between previous and new classes
removedClasses.keySet().removeAll(StructrApp.getConfiguration().getTypeAndPropertyMapping().keySet());
}
// create properties and views etc.
for (final SchemaNode schemaNode : app.nodeQuery(SchemaNode.class).getAsList()) {
schemaNode.createBuiltInSchemaEntities(errorBuffer);
}
success = !errorBuffer.hasError();
if (success) {
// prevent inheritance map from leaking
SearchCommand.clearInheritanceMap();
AccessPathCache.invalidate();
// clear relationship instance cache
AbstractNode.clearRelationshipTemplateInstanceCache();
// clear permission cache
AbstractNode.clearPermissionResolutionCache();
// inject views in configuration provider
config.registerDynamicViews(dynamicViews);
if (Services.calculateHierarchy() || !Services.isTesting()) {
calculateHierarchy();
}
if (Services.updateIndexConfiguration() || !Services.isTesting()) {
updateIndexConfiguration(removedClasses);
}
tx.success();
final GraphQLObjectType.Builder queryTypeBuilder = GraphQLObjectType.newObject();
// register types in "Query" type
for (final Entry<String, GraphQLType> entry : graphQLTypes.entrySet()) {
final String className = entry.getKey();
final GraphQLType type = entry.getValue();
// register type in query type
queryTypeBuilder.field(GraphQLFieldDefinition.newFieldDefinition().name(className).type(new GraphQLList(type)).argument(GraphQLArgument.newArgument().name("id").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("type").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("name").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("_page").type(Scalars.GraphQLInt).build()).argument(GraphQLArgument.newArgument().name("_pageSize").type(Scalars.GraphQLInt).build()).argument(GraphQLArgument.newArgument().name("_sort").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("_desc").type(Scalars.GraphQLBoolean).build()));
}
// exchange graphQL schema after successful build
synchronized (SchemaService.class) {
graphQLSchema = GraphQLSchema.newSchema().query(queryTypeBuilder.name("Query").build()).build(new LinkedHashSet<>(graphQLTypes.values()));
}
}
} catch (FrameworkException fex) {
logger.error("Unable to compile dynamic schema: {}", fex.getMessage());
success = false;
errorBuffer.getErrorTokens().addAll(fex.getErrorBuffer().getErrorTokens());
} catch (Throwable t) {
t.printStackTrace();
logger.error("Unable to compile dynamic schema: {}", t.getMessage());
success = false;
}
if (!success) {
if (Settings.SchemAutoMigration.getValue()) {
// handle migration in separate transaction
try (final Tx tx = app.tx()) {
// try to handle certain errors automatically
handleAutomaticMigration(errorBuffer);
tx.success();
} catch (FrameworkException fex) {
}
} else {
logger.error("Unable to compile dynamic schema, and automatic migration is not enabled. Please set application.schema.automigration = true in structr.conf to enable modification of existing schema classes.");
}
}
} finally {
// compiling done
compiling.set(false);
}
}
return success;
}
use of org.structr.core.entity.SchemaNode in project structr by structr.
the class StructrNodeTypeDefinition method createSchemaNode.
@Override
SchemaNode createSchemaNode(final App app, final PropertyMap createProperties) throws FrameworkException {
// re-use existing schema nodes here!
final SchemaNode existingNode = app.nodeQuery(SchemaNode.class).andName(getName()).getFirst();
if (existingNode != null) {
return existingNode;
}
createProperties.put(SchemaNode.name, getName());
return app.create(SchemaNode.class, createProperties);
}
use of org.structr.core.entity.SchemaNode in project structr by structr.
the class StructrRelationshipTypeDefinition method resolveEndpointTypesForDatabaseSchemaCreation.
void resolveEndpointTypesForDatabaseSchemaCreation(final App app) throws FrameworkException {
// this method is called when the creation of type and relationship
// nodes is completed and all references can be resolved
final SchemaNode sourceSchemaNode = resolveSchemaNode(app, sourceType);
final SchemaNode targetSchemaNode = resolveSchemaNode(app, targetType);
if (sourceSchemaNode != null && targetSchemaNode != null) {
final AbstractSchemaNode thisSchemaRelationship = getSchemaNode();
if (thisSchemaRelationship != null) {
thisSchemaRelationship.setProperty(SchemaRelationshipNode.sourceNode, sourceSchemaNode);
thisSchemaRelationship.setProperty(SchemaRelationshipNode.targetNode, targetSchemaNode);
} else {
throw new IllegalStateException("Unable to resolve schema node endpoints for type " + getName());
}
} else {
throw new IllegalStateException("Unable to resolve schema node endpoints for type " + getName());
}
}
use of org.structr.core.entity.SchemaNode in project structr by structr.
the class DeleteSchemaNodeWhenMissingPackage method handleMigration.
@Override
public void handleMigration(final ErrorToken errorToken) throws FrameworkException {
final Object messageObject = errorToken.getDetail();
if (messageObject != null) {
final String message = (String) messageObject;
final Matcher matcher = PATTERN.matcher(message);
if (matcher.matches()) {
logger.info("Identified missing package {}, deleting entity {}", matcher.group(1), errorToken.getType());
final App app = StructrApp.getInstance();
final String name = errorToken.getType();
final SchemaNode schemaNode = app.nodeQuery(SchemaNode.class).andName(name).getFirst();
if (schemaNode != null) {
logger.info("Deleting erroneous schema entity {}", schemaNode.getName());
app.delete(schemaNode);
} else {
logger.info("No SchemaNode with name {} found, cannot delete.", name);
}
}
}
}
Aggregations