Search in sources :

Example 1 with SchemaRelationshipNode

use of org.structr.core.entity.SchemaRelationshipNode in project structr by structr.

the class SchemaHelper method getSource.

public static String getSource(final AbstractSchemaNode schemaNode, final ErrorBuffer errorBuffer) throws FrameworkException {
    final Collection<StructrModule> modules = StructrApp.getConfiguration().getModules().values();
    final App app = StructrApp.getInstance();
    final Map<String, List<ActionEntry>> methods = new LinkedHashMap<>();
    final Map<String, Set<String>> viewProperties = new LinkedHashMap<>();
    final List<String> propertyValidators = new LinkedList<>();
    final Set<String> existingPropertyNames = new LinkedHashSet<>();
    final Set<String> compoundIndexKeys = new LinkedHashSet<>();
    final Set<String> propertyNames = new LinkedHashSet<>();
    final Set<String> relationshipPropertyNames = new LinkedHashSet<>();
    final Set<Validator> validators = new LinkedHashSet<>();
    final Set<String> implementedInterfaces = new LinkedHashSet<>();
    final List<String> importStatements = new LinkedList<>();
    final Set<String> enums = new LinkedHashSet<>();
    final StringBuilder src = new StringBuilder();
    final StringBuilder mixinCodeBuffer = new StringBuilder();
    final Class baseType = AbstractNode.class;
    final String _className = schemaNode.getProperty(SchemaNode.name);
    final String _extendsClass = schemaNode.getProperty(SchemaNode.extendsClass);
    final String superClass = _extendsClass != null ? _extendsClass : baseType.getSimpleName();
    final boolean extendsAbstractNode = _extendsClass == null;
    // check superclass
    if (!extendsAbstractNode && !superClass.startsWith("org.structr.dynamic.") && !SchemaHelper.hasType(superClass)) {
        // we can only detect if a type is missing that is usually provided by a module; we
        // can not detect whether a dynamic type is missing because those are only available
        // after compiling the whole set of schema nodes
        logger.warn("Dynamic type {} cannot be used, superclass {} not defined.", schemaNode.getName(), superClass);
        return null;
    }
    // import mixins, check that all types exist and return null otherwise (causing this class to be ignored)
    SchemaHelper.collectInterfaces(schemaNode, implementedInterfaces);
    // package name
    src.append("package org.structr.dynamic;\n\n");
    // include import statements from mixins
    SchemaHelper.formatImportStatements(schemaNode, src, baseType, importStatements);
    if (schemaNode.getProperty(SchemaNode.isInterface)) {
        // create interface
        src.append("public interface ");
        src.append(_className);
        // output implemented interfaces
        if (!implementedInterfaces.isEmpty()) {
            src.append(" extends ");
            src.append(StringUtils.join(implementedInterfaces, ", "));
        }
    } else {
        // create class
        src.append("public ");
        if (schemaNode.getProperty(SchemaNode.isAbstract)) {
            src.append("abstract ");
        }
        src.append("class ");
        src.append(_className);
        src.append(" extends ");
        src.append(superClass);
        // output implemented interfaces
        if (!implementedInterfaces.isEmpty()) {
            src.append(" implements ");
            src.append(StringUtils.join(implementedInterfaces, ", "));
        }
    }
    src.append(" {\n\n");
    // output related node definitions, collect property views
    for (final SchemaRelationshipNode outRel : schemaNode.getProperty(SchemaNode.relatedTo)) {
        final String propertyName = outRel.getPropertyName(_className, existingPropertyNames, true);
        propertyNames.add(propertyName);
        src.append(outRel.getPropertySource(propertyName, true));
        // schema changes are expected to be added to "ui" view.
        if (!outRel.getProperty(SchemaRelationshipNode.isPartOfBuiltInSchema)) {
            addPropertyToView(PropertyView.Ui, propertyName, viewProperties);
        }
        relationshipPropertyNames.add(propertyName);
    }
    // output related node definitions, collect property views
    for (final SchemaRelationshipNode inRel : schemaNode.getProperty(SchemaNode.relatedFrom)) {
        final String propertyName = inRel.getPropertyName(_className, existingPropertyNames, false);
        propertyNames.add(propertyName);
        src.append(inRel.getPropertySource(propertyName, false));
        // schema changes are expected to be added to "ui" view.
        if (!inRel.getProperty(SchemaRelationshipNode.isPartOfBuiltInSchema)) {
            SchemaHelper.addPropertyToView(PropertyView.Ui, propertyName, viewProperties);
        }
        relationshipPropertyNames.add(propertyName);
    }
    src.append(SchemaHelper.extractProperties(schemaNode, propertyNames, validators, compoundIndexKeys, enums, viewProperties, propertyValidators, errorBuffer));
    SchemaHelper.extractViews(schemaNode, viewProperties, relationshipPropertyNames, errorBuffer);
    SchemaHelper.extractMethods(schemaNode, methods);
    // output possible enum definitions
    for (final String enumDefition : enums) {
        src.append(enumDefition);
    }
    for (Entry<String, Set<String>> entry : viewProperties.entrySet()) {
        final String viewName = entry.getKey();
        final Set<String> view = entry.getValue();
        if (!view.isEmpty()) {
            schemaNode.addDynamicView(viewName);
            SchemaHelper.formatView(src, _className, viewName, viewName, view);
        }
    }
    if (schemaNode.getProperty(defaultSortKey) != null) {
        String order = schemaNode.getProperty(defaultSortOrder);
        if (order == null || "desc".equals(order)) {
            order = "GraphObjectComparator.DESCENDING";
        } else {
            order = "GraphObjectComparator.ASCENDING";
        }
        src.append("\n\t@Override\n");
        src.append("\tpublic PropertyKey getDefaultSortKey() {\n");
        src.append("\t\treturn ").append(schemaNode.getProperty(defaultSortKey)).append("Property;\n");
        src.append("\t}\n");
        src.append("\n\t@Override\n");
        src.append("\tpublic String getDefaultSortOrder() {\n");
        src.append("\t\treturn ").append(order).append(";\n");
        src.append("\t}\n");
    }
    SchemaHelper.formatValidators(src, validators, compoundIndexKeys, extendsAbstractNode, propertyValidators);
    SchemaHelper.formatMethods(schemaNode, src, methods, implementedInterfaces);
    // insert dynamic code here
    src.append(mixinCodeBuffer);
    // insert source code from module
    for (final StructrModule module : modules) {
        module.insertSourceCode(schemaNode, src);
    }
    src.append("}\n");
    return src.toString();
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) AbstractNode(org.structr.core.entity.AbstractNode) LinkedList(java.util.LinkedList) LinkedHashMap(java.util.LinkedHashMap) StructrModule(org.structr.module.StructrModule) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) List(java.util.List) LinkedList(java.util.LinkedList) Validator(org.structr.schema.parser.Validator)

Example 2 with SchemaRelationshipNode

use of org.structr.core.entity.SchemaRelationshipNode 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 3 with SchemaRelationshipNode

use of org.structr.core.entity.SchemaRelationshipNode in project structr by structr.

the class PushSchemaCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final Map<String, Object> properties = webSocketData.getNodeData();
    final String username = (String) properties.get("username");
    final String password = (String) properties.get("password");
    final String host = (String) properties.get("host");
    final Long port = (Long) properties.get("port");
    final String key = (String) properties.get("key");
    if (host != null && port != null && username != null && password != null && key != null) {
        final App app = StructrApp.getInstance();
        try (final Tx tx = app.tx()) {
            // create push transmission to be filled later
            final PushTransmission tms = new PushTransmission();
            for (final SchemaNode node : app.nodeQuery(SchemaNode.class).getAsList()) {
                if (isFalseOrNull(node.getProperty(SchemaNode.isBuiltinType))) {
                    tms.getExportSet().add(node);
                }
            }
            for (final SchemaRelationshipNode rel : app.nodeQuery(SchemaRelationshipNode.class).getAsList()) {
                tms.getExportSet().add(rel);
            }
            // push schema
            CloudService.doRemote(webSocket.getSecurityContext(), tms, new HostInfo(username, password, host, port.intValue()), new WebsocketProgressListener(getWebSocket(), key, callback));
            tx.success();
        } catch (FrameworkException fex) {
            getWebSocket().send(MessageBuilder.status().code(400).message(fex.getMessage()).build(), true);
        }
    } else {
        getWebSocket().send(MessageBuilder.status().code(400).message("The PUSH_SCHEMA command needs username, password, host, port and key!").build(), true);
    }
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) SchemaNode(org.structr.core.entity.SchemaNode) PushTransmission(org.structr.cloud.transmission.PushTransmission) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) WebsocketProgressListener(org.structr.cloud.WebsocketProgressListener) HostInfo(org.structr.cloud.HostInfo)

Example 4 with SchemaRelationshipNode

use of org.structr.core.entity.SchemaRelationshipNode in project structr by structr.

the class OWLParserv2 method parse.

public void parse(final String fileName, final String blobsDirectory) {
    boolean success = true;
    try (final App app = StructrApp.getInstance()) {
        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new java.io.File(fileName));
        System.out.println("Parsing XML document..");
        logger.println("Parsing XML document..");
        // parse XML document
        parseDocument(doc.getDocumentElement(), 0);
        System.out.println("Filtering unwanted classes..");
        logger.println("Filtering unwanted classes..");
        // filter unwanted objects by their IDs
        filter(owlClassesByURI.values());
        filter(owlPropertiesByURI.values());
        if (importSchema) {
            // initialize class hierarchies
            System.out.println("Resolving " + owlClassesByURI.size() + " OWL superclasses..");
            logger.println("Resolving " + owlClassesByURI.size() + " OWL superclasses..");
            for (final OWLClass owlClass : owlClassesByURI.values()) {
                owlClass.resolveSuperclasses(owlClassesByURI);
            }
            for (final OWLClass owlClass : owlClassesByURI.values()) {
                owlClass.resolveRelatedTypes(owlClassesByURI);
            }
            for (final OWLClass owlClass : owlClassesByURI.values()) {
                owlClass.resolveRelationshipTypes(owlClassesByURI);
            }
            // initialize classes with datatype properties
            System.out.println("Resolving " + owlPropertiesByURI.size() + " datatype properties..");
            logger.println("Resolving " + owlPropertiesByURI.size() + " datatype properties..");
            for (final OWLProperty owlProperty : owlPropertiesByURI.values()) {
                owlProperty.resolveSuperclasses(owlPropertiesByURI);
                owlProperty.resolveClassProperties(owlClassesByURI);
            }
            final JsonSchema schema = StructrSchema.newInstance(URI.create("http://localhost/test/#"));
            // create common base class
            final JsonType baseType = schema.addType("BaseNode");
            final JsonType nameType = schema.addType("LocalizedName");
            nameType.addStringProperty("locale").setIndexed(true);
            nameType.addStringProperty("name").setIndexed(true);
            baseType.addStringProperty("originId").setIndexed(true);
            baseType.addDateProperty("createdAt").setIndexed(true);
            baseType.addDateProperty("modifiedAt").setIndexed(true);
            baseType.addFunctionProperty("isFallbackLang", "ui").setContentType("application/x-structr-script").setReadFunction("(empty(get_or_null(first(filter(this.names, equal(data.locale, substring(locale, 0, 2)))), 'name')))").setIndexed(true);
            baseType.addFunctionProperty("localizedName", "ui").setContentType("application/x-structr-script").setReadFunction("(if (equal('zh', substring(locale, 0, 2)),(if (empty(first(filter(this.names, equal(data.locale, 'zh')))),if (empty(first(filter(this.names, equal(data.locale, 'en')))),get_or_null(first(filter(this.names, equal(data.locale, 'de'))), 'name'),get(first(filter(this.names, equal(data.locale, 'en'))), 'name')),get(first(filter(this.names, equal(data.locale, 'zh'))), 'name'))),if (equal('de', substring(locale, 0, 2)),(if (empty(first(filter(this.names, equal(data.locale, 'de')))),if (empty(first(filter(this.names, equal(data.locale, 'en')))),get_or_null(first(filter(this.names, equal(data.locale, 'zh'))), 'name'),get(first(filter(this.names, equal(data.locale, 'en'))), 'name')),get(first(filter(this.names, equal(data.locale, 'de'))), 'name'))),(if (empty(first(filter(this.names, equal(data.locale, 'en')))),if (empty(first(filter(this.names, equal(data.locale, 'de')))),get_or_null(first(filter(this.names, equal(data.locale, 'zh'))), 'name'),get(first(filter(this.names, equal(data.locale, 'de'))), 'name')),get(first(filter(this.names, equal(data.locale, 'en'))), 'name'))))))").setIndexed(true);
            baseType.addFunctionProperty("nameDE", "ui").setContentType("application/x-structr-script").setReadFunction("get_or_null(first(filter(this.names, equal(data.locale, 'de'))), 'name')").setWriteFunction("(store('node', first(filter(this.names, equal(data.locale, 'de')))),if (empty(retrieve('node')),set(this, 'names', merge(this.names, create('LocalizedName', 'locale', 'de', 'name', value))),(if (empty(value),delete(retrieve('node')),set(retrieve('node'), 'name', value)))))").setIndexed(true);
            baseType.addFunctionProperty("nameEN", "ui").setContentType("application/x-structr-script").setReadFunction("get_or_null(first(filter(this.names, equal(data.locale, 'en'))), 'name')").setWriteFunction("(store('node', first(filter(this.names, equal(data.locale, 'en')))),if (empty(retrieve('node')),set(this, 'names', merge(this.names, create('LocalizedName', 'locale', 'en', 'name', value))),(if (empty(value),delete(retrieve('node')),set(retrieve('node'), 'name', value)))))").setIndexed(true);
            baseType.addFunctionProperty("nameZH", "ui").setContentType("application/x-structr-script").setReadFunction("get_or_null(first(filter(this.names, equal(data.locale, 'zh'))), 'name')").setWriteFunction("(store('node', first(filter(this.names, equal(data.locale, 'zh')))),if (empty(retrieve('node')),set(this, 'names', merge(this.names, create('LocalizedName', 'locale', 'zh', 'name', value))),(if (empty(value),delete(retrieve('node')),set(retrieve('node'), 'name', value)))))").setIndexed(true);
            final JsonReferenceType names = ((JsonObjectType) baseType).relate((JsonObjectType) nameType, "HasName", Cardinality.OneToMany);
            names.setSourcePropertyName("isNameOf");
            names.setTargetPropertyName("names");
            final JsonReferenceType extensions = ((JsonObjectType) baseType).relate((JsonObjectType) baseType, "ExtendedBy", Cardinality.ManyToMany);
            extensions.setSourcePropertyName("extends");
            extensions.setTargetPropertyName("extendedBy");
            baseType.addStringProperty("name").setIndexed(true);
            System.out.println("Creating schema..");
            logger.println("Creating schema..");
            try (final Tx tx = StructrApp.getInstance().tx()) {
                for (final OWLClass owlClass : owlClassesByURI.values()) {
                    final String name = owlClass.getStructrName(true);
                    if (name != null && schema.getType(name) == null && owlClass.isPrimary()) {
                        logger.println("Creating type " + name + "..");
                        schema.addType(name);
                    }
                }
                StructrSchema.replaceDatabaseSchema(app, schema);
                tx.success();
            } catch (FrameworkException fex) {
                System.out.println(fex.getErrorBuffer().getErrorTokens());
            }
            // resolve inheritance
            System.out.println("Resolving class inheritance..");
            logger.println("Resolving class inheritance..");
            try (final Tx tx = StructrApp.getInstance().tx()) {
                for (final OWLClass owlClass : owlClassesByURI.values()) {
                    final String name = owlClass.getStructrName(true);
                    final JsonType type = schema.getType(name);
                    final OWLClass superclass = owlClass.getSuperclass();
                    // type can be null if it is inverseOf another type
                    if (type != null) {
                        if (superclass != null) {
                            final JsonType superType = schema.getType(superclass.getStructrName(true));
                            if (superType != null) {
                                type.setExtends(superType);
                            } else {
                                type.setExtends(baseType);
                            }
                        } else {
                            type.setExtends(baseType);
                        }
                        for (final Name localizedName : owlClass.getNames()) {
                            app.create(Localization.class, new NodeAttribute(StructrApp.key(Localization.class, "name"), name), new NodeAttribute(StructrApp.key(Localization.class, "localizedName"), localizedName.name), new NodeAttribute(StructrApp.key(Localization.class, "locale"), localizedName.lang));
                        }
                    }
                }
                StructrSchema.replaceDatabaseSchema(app, schema);
                tx.success();
            } catch (FrameworkException fex) {
                System.out.println(fex.getErrorBuffer().getErrorTokens());
            }
            // resolve relationship types
            System.out.println("Resolving relationship types..");
            logger.println("Resolving relationship types..");
            try (final Tx tx = StructrApp.getInstance().tx()) {
                for (final OWLClass possibleOutgoingRelationshipType : owlClassesByURI.values()) {
                    final OWLClass possibleIncomingRelationshipType = possibleOutgoingRelationshipType.getInverse();
                    if (possibleOutgoingRelationshipType.isPrimary() && possibleIncomingRelationshipType != null) {
                        // this is a relationship
                        final List<OWLClass> sourceTypes = possibleOutgoingRelationshipType.getActualSourceTypes();
                        final List<OWLClass> targetTypes = possibleOutgoingRelationshipType.getActualTargetTypes();
                        for (final OWLClass sourceType : sourceTypes) {
                            for (final OWLClass targetType : targetTypes) {
                                final String sourceName = possibleOutgoingRelationshipType.getStructrName(false);
                                final String targetName = possibleIncomingRelationshipType.getStructrName(false);
                                final String sourceTypeName = sourceType.getStructrName(true);
                                final String targetTypeName = targetType.getStructrName(true);
                                final JsonType sourceJsonType = schema.getType(sourceTypeName);
                                final JsonType targetJsonType = schema.getType(targetTypeName);
                                if (sourceJsonType != null && targetJsonType != null) {
                                    final String relationshipTypeName = possibleOutgoingRelationshipType.getStructrName(true);
                                    final JsonObjectType relType = schema.addType(relationshipTypeName);
                                    final JsonObjectType srcType = (JsonObjectType) sourceJsonType;
                                    final JsonObjectType tgtType = (JsonObjectType) targetJsonType;
                                    srcType.relate(relType, sourceName, Cardinality.OneToMany, sourceType.getStructrName(false), sourceName);
                                    relType.relate(tgtType, targetName, Cardinality.ManyToOne, targetName, targetType.getStructrName(false));
                                    possibleOutgoingRelationshipType.setIsRelationship(true);
                                }
                            }
                        }
                    }
                }
                StructrSchema.replaceDatabaseSchema(app, schema);
                tx.success();
            } catch (FrameworkException fex) {
                System.out.println(fex.getErrorBuffer().getErrorTokens());
            }
            System.out.println("Adding properties to types");
            logger.println("Adding properties to types");
            try (final Tx tx = StructrApp.getInstance().tx()) {
                for (final OWLClass owlClass : owlClassesByURI.values()) {
                    final String typeName = owlClass.getStructrName(true);
                    JsonType type = schema.getType(typeName);
                    // type not found, try to set property on inverse type
                    if (type == null) {
                        final OWLClass inverse = owlClass.getInverse();
                        if (inverse != null) {
                            type = schema.getType(inverse.getStructrName(true));
                        }
                    }
                    if (type != null) {
                        for (final OWLProperty prop : owlClass.getAllProperties()) {
                            addProperty(type, prop, prop.getStructrName(false));
                        }
                    } else {
                        System.out.println("Class: no type found for " + owlClass.getId());
                    }
                }
                StructrSchema.replaceDatabaseSchema(app, schema);
                tx.success();
            }
            System.out.println("Adding metdata to node types");
            logger.println("Adding metdata to node types");
            try (final Tx tx = StructrApp.getInstance().tx()) {
                for (final OWLClass owlClass : owlClassesByURI.values()) {
                    final String name = owlClass.getStructrName(true);
                    final SchemaNode schemaNode = app.nodeQuery(SchemaNode.class).andName(name).getFirst();
                    String icon = owlClass.getIcon();
                    if (schemaNode != null) {
                        // part after the second dash
                        if (icon != null && icon.contains("-")) {
                            // start with
                            final int pos = icon.indexOf("-", 7);
                            if (pos > -1) {
                                icon = icon.substring(pos + 1);
                            }
                        }
                        schemaNode.setProperty(SchemaNode.icon, icon);
                    }
                }
                tx.success();
            } catch (FrameworkException fex) {
                System.out.println(fex.getErrorBuffer().getErrorTokens());
            }
            // create instances
            System.out.println("Resolving instances..");
            logger.println("Resolving instances..");
            final Iterator<OWLInstance> instancesIterator = owlInstances.values().iterator();
            final List<OWLInstance> newInstances = new LinkedList<>();
            int count = 0;
            while (instancesIterator.hasNext()) {
                try (final Tx tx = StructrApp.getInstance().tx()) {
                    while (instancesIterator.hasNext()) {
                        final OWLInstance instance = instancesIterator.next();
                        final OWLClass owlType = instance.getType();
                        if (owlType != null) {
                            instance.createDatabaseNode(app);
                            instance.resolveProperties();
                            instance.resolveExtensions(app, owlClassesByFragment, owlInstances, newInstances);
                        }
                        if (++count == 100) {
                            count = 0;
                            break;
                        }
                    }
                    tx.success();
                }
            }
            // add newly created extension instances to global map
            for (final OWLInstance newInstance : newInstances) {
                owlInstances.put(newInstance.getId(), newInstance);
            }
            System.out.println("Resolving instance relationships..");
            logger.println("Resolving instance relationships..");
            final Iterator<OWLInstance> relationshipsIterator = owlInstances.values().iterator();
            count = 0;
            while (relationshipsIterator.hasNext()) {
                try (final Tx tx = StructrApp.getInstance().tx()) {
                    while (relationshipsIterator.hasNext()) {
                        final OWLInstance instance = relationshipsIterator.next();
                        final OWLClass owlType = instance.getType();
                        if (owlType != null) {
                            instance.resolveRelationships(schema, owlClassesByFragment, owlInstances, rdfDescriptions, owlPropertiesByName);
                        }
                        if (++count == 100) {
                            count = 0;
                            break;
                        }
                    }
                    tx.success();
                }
            }
        }
        final java.io.File blobs = new java.io.File(blobsDirectory);
        if (blobs.exists()) {
            final ConfigurationProvider config = StructrApp.getConfiguration();
            final List<Tuple<Class, PropertyKey>> mapping = createPropertyKeyMapping(config);
            final Set<Path> files = new LinkedHashSet<>();
            int count = 0;
            // collect all files
            Files.walkFileTree(blobs.toPath(), new Visitor(files));
            if (createFileRelationships) {
                System.out.println("Resolving file relationships..");
                logger.println("Resolving file relationships..");
                // iterate over files to identify relationships and extend schema
                final Iterator<Path> pathIteratorForSchemaExtension = files.iterator();
                try (final Tx tx = StructrApp.getInstance().tx()) {
                    while (pathIteratorForSchemaExtension.hasNext()) {
                        final Path file = pathIteratorForSchemaExtension.next();
                        final String name = file.getFileName().toString();
                        final int pos = name.indexOf(".", 7);
                        final String idPart = name.substring(6, pos == -1 ? name.length() : pos);
                        if (name.startsWith("KBlob-") && name.length() > 23) {
                            for (final Tuple<Class, PropertyKey> entry : mapping) {
                                final Class type = entry.getKey();
                                final PropertyKey key = entry.getValue();
                                Object value = idPart;
                                if (key instanceof ArrayProperty) {
                                    value = new String[] { idPart };
                                }
                                final Query<NodeInterface> query = app.nodeQuery().andType(type).and(key, value, false);
                                final List<NodeInterface> nodes = query.getAsList();
                                if (nodes.size() == 1) {
                                    System.out.println("                ##########: " + nodes.size() + " results..");
                                    // create schema relationship from schema type to file (once)
                                    // import file
                                    // link file
                                    final SchemaNode schemaNode = app.nodeQuery(SchemaNode.class).andName(type.getSimpleName()).getFirst();
                                    if (schemaNode != null) {
                                        System.out.println("                ##########: found SchemaNode " + schemaNode.getUuid() + " (" + schemaNode.getName() + ")");
                                        final SchemaNode fileSchemaNode = app.nodeQuery(SchemaNode.class).andName(File.class.getSimpleName()).getFirst();
                                        if (fileSchemaNode != null) {
                                            final String capitalJsonName = StringUtils.capitalize(key.jsonName());
                                            final String targetJsonName = "has" + capitalJsonName;
                                            final String sourceJsonName = "is" + capitalJsonName + "Of" + type.getSimpleName();
                                            final SchemaRelationshipNode link = app.nodeQuery(SchemaRelationshipNode.class).and(SchemaRelationshipNode.sourceNode, schemaNode).and(SchemaRelationshipNode.targetNode, fileSchemaNode).and(SchemaRelationshipNode.relationshipType, key.jsonName()).getFirst();
                                            if (link == null) {
                                                System.out.println("Creating link from " + schemaNode + " to " + fileSchemaNode + ", " + sourceJsonName + ", " + targetJsonName);
                                                app.create(SchemaRelationshipNode.class, new NodeAttribute(SchemaRelationshipNode.sourceNode, schemaNode), new NodeAttribute(SchemaRelationshipNode.targetNode, fileSchemaNode), new NodeAttribute(SchemaRelationshipNode.relationshipType, key.jsonName()), new NodeAttribute(SchemaRelationshipNode.sourceMultiplicity, "1"), new NodeAttribute(SchemaRelationshipNode.targetMultiplicity, key instanceof ArrayProperty ? "*" : "1"), new NodeAttribute(SchemaRelationshipNode.sourceJsonName, sourceJsonName), new NodeAttribute(SchemaRelationshipNode.targetJsonName, targetJsonName));
                                            } else {
                                                System.out.println("Link relationship already exists: " + link);
                                            }
                                        } else {
                                            System.out.println("NO SchemaNode found for type File!");
                                        }
                                    } else {
                                        System.out.println("NO SchemaNode found for type " + type.getSimpleName() + "!");
                                    }
                                // no need to search further
                                // break;
                                }
                            }
                        }
                    }
                    tx.success();
                }
            }
            if (importFiles) {
                System.out.println("Importing files..");
                logger.println("Importing files..");
                final SecurityContext superUserSecurityContext = SecurityContext.getSuperUserInstance();
                final Iterator<Path> pathIteratorForRelationshipCreation = files.iterator();
                while (pathIteratorForRelationshipCreation.hasNext()) {
                    try (final Tx tx = StructrApp.getInstance().tx()) {
                        while (pathIteratorForRelationshipCreation.hasNext()) {
                            final Path file = pathIteratorForRelationshipCreation.next();
                            final String name = file.getFileName().toString();
                            final int pos = name.indexOf(".", 7);
                            final String idPart = name.substring(6, pos == -1 ? name.length() : pos);
                            boolean found = false;
                            if (name.startsWith("KBlob-") && name.length() > 23) {
                                for (final Tuple<Class, PropertyKey> entry : mapping) {
                                    final Class type = entry.getKey();
                                    final PropertyKey key = entry.getValue();
                                    final boolean isMultiple = (key instanceof ArrayProperty);
                                    Object value = idPart;
                                    if (isMultiple) {
                                        value = new String[] { idPart };
                                    }
                                    final Query<NodeInterface> query = app.nodeQuery().andType(type).and(key, value, false);
                                    final List<NodeInterface> nodes = query.getAsList();
                                    if (nodes.size() == 1) {
                                        final String capitalJsonName = StringUtils.capitalize(key.jsonName());
                                        final String targetJsonName = "has" + capitalJsonName;
                                        final NodeInterface node = nodes.get(0);
                                        final PropertyKey fileRelationshipKey = StructrApp.key(type, targetJsonName);
                                        if (fileRelationshipKey != null) {
                                            try (final InputStream is = new FileInputStream(file.toFile())) {
                                                // import file..
                                                final Class fileType = ImageHelper.isImageType(name) ? Image.class : File.class;
                                                if (isMultiple) {
                                                    final String[] possibleNames = (String[]) node.getProperty(key);
                                                    String actualName = name;
                                                    for (final String possibleName : possibleNames) {
                                                        if (possibleName.startsWith(name)) {
                                                            actualName = possibleName.substring(name.length() + 1);
                                                            break;
                                                        }
                                                    }
                                                    logger.println("        Importing " + name + " => " + actualName);
                                                    final File importedFile = FileHelper.createFile(superUserSecurityContext, is, null, fileType, actualName);
                                                    final List<File> fileList = (List<File>) node.getProperty(fileRelationshipKey);
                                                    fileList.add(importedFile);
                                                    node.setProperty(fileRelationshipKey, fileList);
                                                } else {
                                                    final String possibleName = (String) node.getProperty(key);
                                                    String actualName = name;
                                                    if (possibleName != null) {
                                                        actualName = possibleName.substring(name.length() + 1);
                                                    }
                                                    logger.println("        Importing " + name + " => " + actualName);
                                                    final File importedFile = FileHelper.createFile(superUserSecurityContext, is, null, fileType, actualName);
                                                    node.setProperty(fileRelationshipKey, importedFile);
                                                }
                                            } catch (Throwable t) {
                                                t.printStackTrace();
                                            }
                                        } else {
                                            System.out.println("############################# INVALID KEY " + type.getSimpleName() + "." + targetJsonName + ", not found??!");
                                            logger.println("############################# INVALID KEY " + type.getSimpleName() + "." + targetJsonName + ", not found??!");
                                        }
                                        found = true;
                                        // no need to search further
                                        break;
                                    }
                                }
                            }
                            if (!found) {
                                System.out.println("Found NO document for file " + name + ", importing without association");
                                logger.println("Found NO document for file " + name + ", importing without association");
                                try (final InputStream is = new FileInputStream(file.toFile())) {
                                    // import file..
                                    final Class fileType = ImageHelper.isImageType(name) ? Image.class : File.class;
                                    FileHelper.createFile(superUserSecurityContext, is, null, fileType, name);
                                } catch (Throwable t) {
                                    t.printStackTrace();
                                }
                            }
                            if (++count == 100) {
                                count = 0;
                                break;
                            }
                        }
                        tx.success();
                    }
                }
            }
        }
    } catch (Throwable t) {
        t.printStackTrace();
        success = false;
    }
    if (success) {
        System.out.println("Import successful");
        logger.println("Import successful");
    }
    logger.flush();
    logger.close();
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) LinkedHashSet(java.util.LinkedHashSet) JsonSchema(org.structr.schema.json.JsonSchema) Document(org.w3c.dom.Document) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) List(java.util.List) LinkedList(java.util.LinkedList) NodeInterface(org.structr.core.graph.NodeInterface) ArrayProperty(org.structr.core.property.ArrayProperty) Tx(org.structr.core.graph.Tx) LinkedList(java.util.LinkedList) FileInputStream(java.io.FileInputStream) File(org.structr.web.entity.File) JsonType(org.structr.schema.json.JsonType) FileVisitor(java.nio.file.FileVisitor) ConfigurationProvider(org.structr.schema.ConfigurationProvider) Path(java.nio.file.Path) JsonReferenceType(org.structr.schema.json.JsonReferenceType) NodeAttribute(org.structr.core.graph.NodeAttribute) FrameworkException(org.structr.common.error.FrameworkException) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JsonObjectType(org.structr.schema.json.JsonObjectType) SchemaNode(org.structr.core.entity.SchemaNode) SecurityContext(org.structr.common.SecurityContext) PropertyKey(org.structr.core.property.PropertyKey)

Example 5 with SchemaRelationshipNode

use of org.structr.core.entity.SchemaRelationshipNode in project structr by structr.

the class ListSchemaPropertiesCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final String view = (String) webSocketData.getNodeData().get("view");
    final String id = webSocketData.getId();
    final List<GraphObject> result = new LinkedList();
    if (view != null) {
        if (id != null) {
            AbstractNode schemaObject = getNode(id);
            if (schemaObject != null) {
                final ConfigurationProvider config = StructrApp.getConfiguration();
                String typeName = schemaObject.getProperty(AbstractNode.name);
                if (typeName == null && schemaObject instanceof SchemaRelationshipNode) {
                    typeName = ((SchemaRelationshipNode) schemaObject).getClassName();
                }
                Class type = config.getNodeEntityClass(typeName);
                if (type == null || GenericNode.class.equals(type)) {
                    type = config.getRelationshipEntityClass(typeName);
                }
                if (type != null) {
                    final Set<PropertyKey> allProperties = config.getPropertySet(type, PropertyView.All);
                    final Set<PropertyKey> viewProperties = config.getPropertySet(type, view);
                    final Set<PropertyKey> parentProperties = config.getPropertySet(type.getSuperclass(), view);
                    for (final PropertyKey key : allProperties) {
                        final String declaringClass = key.getDeclaringClass() != null ? key.getDeclaringClass().getSimpleName() : "GraphObject";
                        final String propertyName = key.jsonName();
                        final GraphObjectMap property = new GraphObjectMap();
                        final Class valueType = key.valueType();
                        String valueTypeName = "Unknown";
                        boolean _isDisabled = false;
                        if (valueType != null) {
                            valueTypeName = valueType.getSimpleName();
                        }
                        // (since it has to be configured there instead of locally)
                        if (parentProperties.contains(key)) {
                            _isDisabled = true;
                        }
                        property.put(AbstractNode.name, propertyName);
                        property.put(isSelected, viewProperties.contains(key));
                        property.put(isDisabled, _isDisabled);
                        property.put(SchemaProperty.propertyType, valueTypeName);
                        property.put(SchemaProperty.notNull, key.isNotNull());
                        property.put(SchemaProperty.unique, key.isUnique());
                        property.put(SchemaProperty.isDynamic, key.isDynamic());
                        property.put(SchemaProperty.declaringClass, declaringClass);
                        // store in result
                        result.add(property);
                    }
                } else {
                    getWebSocket().send(MessageBuilder.status().code(404).message("Type " + typeName + " not found.").build(), true);
                }
            } else {
                getWebSocket().send(MessageBuilder.status().code(404).message("Schema node with ID " + id + " not found.").build(), true);
            }
        } else {
            getWebSocket().send(MessageBuilder.status().code(422).message("LIST_SCHEMA_PROPERTIES needs an ID.").build(), true);
        }
    } else {
        getWebSocket().send(MessageBuilder.status().code(422).message("LIST_SCHEMA_PROPERTIES needs a view name in nodeData.").build(), true);
    }
    webSocketData.setView(PropertyView.Ui);
    webSocketData.setResult(result);
    webSocketData.setRawResultCount(1);
    // send only over local connection
    getWebSocket().send(webSocketData, true);
}
Also used : AbstractNode(org.structr.core.entity.AbstractNode) ConfigurationProvider(org.structr.schema.ConfigurationProvider) GenericNode(org.structr.core.entity.GenericNode) GraphObject(org.structr.core.GraphObject) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) GraphObjectMap(org.structr.core.GraphObjectMap) PropertyKey(org.structr.core.property.PropertyKey)

Aggregations

SchemaRelationshipNode (org.structr.core.entity.SchemaRelationshipNode)11 SchemaNode (org.structr.core.entity.SchemaNode)8 App (org.structr.core.app.App)7 StructrApp (org.structr.core.app.StructrApp)7 Tx (org.structr.core.graph.Tx)7 FrameworkException (org.structr.common.error.FrameworkException)6 LinkedHashSet (java.util.LinkedHashSet)3 LinkedList (java.util.LinkedList)3 NodeAttribute (org.structr.core.graph.NodeAttribute)3 PropertyKey (org.structr.core.property.PropertyKey)3 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Test (org.junit.Test)2 AbstractNode (org.structr.core.entity.AbstractNode)2 NodeInterface (org.structr.core.graph.NodeInterface)2 ConfigurationProvider (org.structr.schema.ConfigurationProvider)2 GraphQLList (graphql.schema.GraphQLList)1 GraphQLObjectType (graphql.schema.GraphQLObjectType)1 GraphQLType (graphql.schema.GraphQLType)1 FileInputStream (java.io.FileInputStream)1