Search in sources :

Example 11 with SchemaNode

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);
    }
}
Also used : SchemaNode(org.structr.core.entity.SchemaNode) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) LinkedHashMap(java.util.LinkedHashMap)

Example 12 with SchemaNode

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;
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) LinkedHashSet(java.util.LinkedHashSet) NodeExtender(org.structr.schema.compiler.NodeExtender) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) GraphQLType(graphql.schema.GraphQLType) LinkedHashMap(java.util.LinkedHashMap) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) GraphQLList(graphql.schema.GraphQLList) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) SchemaNode(org.structr.core.entity.SchemaNode) GraphQLObjectType(graphql.schema.GraphQLObjectType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 13 with SchemaNode

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);
}
Also used : SchemaNode(org.structr.core.entity.SchemaNode)

Example 14 with SchemaNode

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());
    }
}
Also used : AbstractSchemaNode(org.structr.core.entity.AbstractSchemaNode) SchemaNode(org.structr.core.entity.SchemaNode) AbstractSchemaNode(org.structr.core.entity.AbstractSchemaNode)

Example 15 with SchemaNode

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);
            }
        }
    }
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) SchemaNode(org.structr.core.entity.SchemaNode) Matcher(java.util.regex.Matcher)

Aggregations

SchemaNode (org.structr.core.entity.SchemaNode)54 Tx (org.structr.core.graph.Tx)44 FrameworkException (org.structr.common.error.FrameworkException)41 Test (org.junit.Test)34 App (org.structr.core.app.App)18 StructrApp (org.structr.core.app.StructrApp)18 NodeAttribute (org.structr.core.graph.NodeAttribute)14 LinkedList (java.util.LinkedList)13 PropertyMap (org.structr.core.property.PropertyMap)13 NodeInterface (org.structr.core.graph.NodeInterface)12 PropertyKey (org.structr.core.property.PropertyKey)11 StructrTest (org.structr.common.StructrTest)10 SchemaMethod (org.structr.core.entity.SchemaMethod)10 SchemaRelationshipNode (org.structr.core.entity.SchemaRelationshipNode)9 StringProperty (org.structr.core.property.StringProperty)9 List (java.util.List)8 ConfigurationProvider (org.structr.schema.ConfigurationProvider)8 SchemaProperty (org.structr.core.entity.SchemaProperty)7 LinkedHashSet (java.util.LinkedHashSet)6 FrontendTest (org.structr.web.basic.FrontendTest)6