Search in sources :

Example 21 with SchemaNode

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

the class SchemaImporter method analyzeSchema.

public void analyzeSchema() {
    final App app = StructrApp.getInstance();
    final FileBasedHashLongMap<NodeInfo> nodeIdMap = new FileBasedHashLongMap<>(userHome + File.separator + ".structrSchemaAnalyzer");
    final DatabaseService graphDb = app.getDatabaseService();
    final ConfigurationProvider configuration = Services.getInstance().getConfigurationProvider();
    final Set<NodeInfo> nodeTypes = new LinkedHashSet<>();
    final Set<RelationshipInfo> relationships = new LinkedHashSet<>();
    final Map<String, SchemaNode> schemaNodes = new LinkedHashMap<>();
    final Map<String, List<TypeInfo>> typeInfoTypeMap = new LinkedHashMap<>();
    final List<TypeInfo> reducedTypeInfos = new LinkedList<>();
    final List<TypeInfo> typeInfos = new LinkedList<>();
    Iterator<Relationship> relIterator = null;
    Iterator<Node> nodeIterator = null;
    info("Fetching all nodes iterator..");
    try (final Tx tx = app.tx()) {
        nodeIterator = Iterables.filter(new StructrAndSpatialPredicate(false, false, true), graphDb.getAllNodes()).iterator();
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Starting to analyze nodes..");
    bulkGraphOperation(SecurityContext.getSuperUserInstance(), nodeIterator, 100000, "Analyzing nodes", new BulkGraphOperation<Node>() {

        @Override
        public void handleGraphObject(final SecurityContext securityContext, final Node node) throws FrameworkException {
            final NodeInfo nodeInfo = new NodeInfo(node);
            // hashcode of nodeInfo is derived from its property and type signature!
            nodeTypes.add(nodeInfo);
            // add node ID to our new test datastructure
            nodeIdMap.add(nodeInfo, node.getId());
        }
    });
    info("Identifying common base classes..");
    try (final Tx tx = app.tx(true, false, false)) {
        // nodeTypes now contains all existing node types and their property sets
        identifyCommonBaseClasses(app, nodeTypes, nodeIdMap, typeInfos);
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Collecting type information..");
    try (final Tx tx = app.tx(true, false, false)) {
        // group type infos by type
        collectTypeInfos(typeInfos, typeInfoTypeMap);
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Aggregating type information..");
    try (final Tx tx = app.tx(true, false, false)) {
        // reduce type infos with more than one type
        reduceTypeInfos(typeInfoTypeMap, reducedTypeInfos);
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Identifying property sets..");
    try (final Tx tx = app.tx(true, false, false)) {
        // intersect property sets of type infos
        intersectPropertySets(reducedTypeInfos);
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Sorting result..");
    try (final Tx tx = app.tx(true, false, false)) {
        // sort type infos
        Collections.sort(reducedTypeInfos, new HierarchyComparator(false));
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    final Map<String, TypeInfo> reducedTypeInfoMap = new LinkedHashMap<>();
    for (final TypeInfo info : reducedTypeInfos) {
        final String type = info.getPrimaryType();
        // map TypeInfo to type for later use
        reducedTypeInfoMap.put(type, info);
        info("Starting with setting of type and ID for type {}", type);
        bulkGraphOperation(SecurityContext.getSuperUserInstance(), info.getNodeIds().iterator(), 10000, "Setting type and ID", new BulkGraphOperation<Long>() {

            @Override
            public void handleGraphObject(SecurityContext securityContext, Long nodeId) throws FrameworkException {
                final Node node = graphDb.getNodeById(nodeId);
                node.setProperty(GraphObject.id.dbName(), NodeServiceCommand.getNextUuid());
                node.setProperty(GraphObject.type.dbName(), type);
            }
        });
    }
    info("Fetching all relationships iterator..");
    try (final Tx tx = app.tx(true, false, false)) {
        relIterator = Iterables.filter(new StructrAndSpatialPredicate(false, false, true), graphDb.getAllRelationships()).iterator();
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    info("Starting with analyzing relationships..");
    bulkGraphOperation(SecurityContext.getSuperUserInstance(), relIterator, 10000, "Analyzing relationships", new BulkGraphOperation<Relationship>() {

        @Override
        public void handleGraphObject(SecurityContext securityContext, Relationship rel) throws FrameworkException {
            final Node startNode = rel.getStartNode();
            final Node endNode = rel.getEndNode();
            // make sure node has been successfully identified above
            if (startNode.hasProperty("type") && endNode.hasProperty("type")) {
                final String relationshipType = rel.getType().name();
                final String startNodeType = (String) startNode.getProperty("type");
                final String endNodeType = (String) endNode.getProperty("type");
                relationships.add(new RelationshipInfo(startNodeType, endNodeType, relationshipType));
                // create combined type on imported relationship
                if (startNodeType != null && endNodeType != null) {
                    final String combinedType = getCombinedType(startNodeType, relationshipType, endNodeType);
                    logger.debug("Combined relationship type {} found for rel type {}, start node type {}, end node type {}", new Object[] { combinedType, relationshipType, startNodeType, endNodeType });
                    rel.setProperty(GraphObject.type.dbName(), combinedType);
                }
                // create ID on imported relationship
                rel.setProperty(GraphObject.id.dbName(), NodeServiceCommand.getNextUuid());
            }
        }
    });
    info("Grouping relationships..");
    // group relationships by type
    final Map<String, List<RelationshipInfo>> relTypeInfoMap = new LinkedHashMap<>();
    for (final RelationshipInfo relInfo : relationships) {
        // final String relType         = relInfo.getRelType();
        final String combinedType = getCombinedType(relInfo.getStartNodeType(), relInfo.getRelType(), relInfo.getEndNodeType());
        List<RelationshipInfo> infos = relTypeInfoMap.get(combinedType);
        if (infos == null) {
            infos = new LinkedList<>();
            relTypeInfoMap.put(combinedType, infos);
        }
        infos.add(relInfo);
    }
    info("Aggregating relationship information..");
    final List<RelationshipInfo> reducedRelationshipInfos = new ArrayList<>();
    if (Settings.InheritanceDetection.getValue()) {
        // reduce relationship infos into one
        for (final List<RelationshipInfo> infos : relTypeInfoMap.values()) {
            reducedRelationshipInfos.addAll(reduceNodeTypes(infos, reducedTypeInfoMap));
        }
    } else {
        reducedRelationshipInfos.addAll(relationships);
    }
    info("Starting with schema node creation..");
    bulkGraphOperation(SecurityContext.getSuperUserInstance(), reducedTypeInfos.iterator(), 100000, "Creating schema nodes", new BulkGraphOperation<TypeInfo>() {

        @Override
        public void handleGraphObject(SecurityContext securityContext, TypeInfo typeInfo) throws FrameworkException {
            final String type = typeInfo.getPrimaryType();
            if (!"ReferenceNode".equals(type)) {
                final Map<String, Class> props = typeInfo.getPropertySet();
                final PropertyMap propertyMap = new PropertyMap();
                // add properties
                for (final Map.Entry<String, Class> propertyEntry : props.entrySet()) {
                    final String propertyName = propertyEntry.getKey();
                    final Class propertyType = propertyEntry.getValue();
                    // handle array types differently
                    String propertyTypeName = propertyType.getSimpleName();
                    if (propertyType.isArray()) {
                        // remove "[]" from the end and append "Array" to match the appropriate parser
                        propertyTypeName = propertyTypeName.substring(0, propertyTypeName.length() - 2).concat("Array");
                    }
                    propertyMap.put(new StringProperty("_".concat(propertyName)), propertyTypeName);
                }
                // set node type which is in "name" property
                propertyMap.put(AbstractNode.name, type);
                // check if there is an existing Structr entity with the same type
                // and make the dynamic class extend the existing class if yes.
                final Class existingType = configuration.getNodeEntityClass(type);
                if (existingType != null) {
                    propertyMap.put(SchemaNode.extendsClass, existingType.getName());
                } else if (!typeInfo.getOtherTypes().isEmpty()) {
                    // only the first supertype is supported
                    propertyMap.put(SchemaNode.extendsClass, typeInfo.getSuperclass(reducedTypeInfoMap));
                }
                final SchemaNode existingNode = app.nodeQuery(SchemaNode.class).andName(type).getFirst();
                if (existingNode != null) {
                    for (final Entry<PropertyKey, Object> entry : propertyMap.entrySet()) {
                        existingNode.setProperty(entry.getKey(), entry.getValue());
                    }
                    schemaNodes.put(type, existingNode);
                } else {
                    // create schema node
                    schemaNodes.put(type, app.create(SchemaNode.class, propertyMap));
                }
            }
        }
    });
    info("Starting with schema relationship creation..");
    bulkGraphOperation(SecurityContext.getSuperUserInstance(), reducedRelationshipInfos.iterator(), 100000, "Creating schema relationships", new BulkGraphOperation<RelationshipInfo>() {

        @Override
        public void handleGraphObject(SecurityContext securityContext, RelationshipInfo template) throws FrameworkException {
            final String startNodeType = template.getStartNodeType();
            final String endNodeType = template.getEndNodeType();
            if (startNodeType != null && endNodeType != null) {
                final SchemaNode startNode = schemaNodes.get(startNodeType);
                final SchemaNode endNode = schemaNodes.get(endNodeType);
                if (startNode != null && endNode != null) {
                    final String relationshipType = template.getRelType();
                    final PropertyMap propertyMap = new PropertyMap();
                    propertyMap.put(SchemaRelationshipNode.sourceId, startNode.getUuid());
                    propertyMap.put(SchemaRelationshipNode.targetId, endNode.getUuid());
                    propertyMap.put(SchemaRelationshipNode.relationshipType, relationshipType);
                    app.create(SchemaRelationshipNode.class, propertyMap);
                } else {
                    info("Unable to create schema relationship node for {} -> {}, no schema nodes found", startNodeType, endNodeType);
                }
            }
        }
    });
    info("Starting with index rebuild..");
    // rebuild index
    app.command(BulkRebuildIndexCommand.class).execute(Collections.EMPTY_MAP);
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) LinkedHashSet(java.util.LinkedHashSet) ConfigurationProvider(org.structr.schema.ConfigurationProvider) Node(org.structr.api.graph.Node) AbstractNode(org.structr.core.entity.AbstractNode) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) SchemaNode(org.structr.core.entity.SchemaNode) ArrayList(java.util.ArrayList) StructrAndSpatialPredicate(org.structr.common.StructrAndSpatialPredicate) StringProperty(org.structr.core.property.StringProperty) LinkedHashMap(java.util.LinkedHashMap) Entry(java.util.Map.Entry) SchemaRelationshipNode(org.structr.core.entity.SchemaRelationshipNode) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) DatabaseService(org.structr.api.DatabaseService) LinkedList(java.util.LinkedList) BulkRebuildIndexCommand(org.structr.core.graph.BulkRebuildIndexCommand) SchemaNode(org.structr.core.entity.SchemaNode) PropertyMap(org.structr.core.property.PropertyMap) Relationship(org.structr.api.graph.Relationship) SecurityContext(org.structr.common.SecurityContext) GraphObject(org.structr.core.GraphObject) LinkedHashMap(java.util.LinkedHashMap) PropertyMap(org.structr.core.property.PropertyMap) Map(java.util.Map)

Example 22 with SchemaNode

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

the class PropertyViewRestTest method testOutputDepthScriptingProperty.

@Test
public void testOutputDepthScriptingProperty() {
    try (final Tx tx = app.tx()) {
        final SchemaNode node = app.create(SchemaNode.class, new NodeAttribute<>(AbstractNode.name, "ScriptTest"), new NodeAttribute<>(new StringProperty("_depth"), "Function(depth)"), new NodeAttribute<>(new StringProperty("__public"), "name, depth, children, parents"));
        app.create(SchemaRelationshipNode.class, new NodeAttribute<>(SchemaRelationshipNode.sourceNode, node), new NodeAttribute<>(SchemaRelationshipNode.targetNode, node), new NodeAttribute<>(SchemaRelationshipNode.relationshipType, "test"), new NodeAttribute<>(SchemaRelationshipNode.sourceJsonName, "parents"), new NodeAttribute<>(SchemaRelationshipNode.targetJsonName, "children"));
        tx.success();
    } catch (Throwable t) {
        t.printStackTrace();
        fail("Unexpected exception.");
    }
    // the new test setup method requires a whole new test class for
    // configuration changes, so this test class is a duplicate of
    // the existing StructrRestTest.. :(
    String resource = "/ScriptTest";
    // create entity
    final String uuid = getUuidFromLocation(RestAssured.given().contentType("application/json; charset=UTF-8").header("Accept", "application/json; charset=UTF-8").body(" { 'name' : 'ScriptTest1' } ").expect().statusCode(201).when().post(resource).getHeader("Location"));
    // create second entity
    RestAssured.given().contentType("application/json; charset=UTF-8").header("Accept", "application/json; charset=UTF-8").body(" { 'name' : 'ScriptTest2', 'parents': [{ 'id': '" + uuid + "' }] } ").expect().statusCode(201).when().post(resource).getHeader("Location");
    // test default view with properties in it
    RestAssured.given().contentType("application/json; charset=UTF-8").header("Accept", "application/json; charset=UTF-8").filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(200)).expect().statusCode(200).body("query_time", notNullValue()).body("serialization_time", notNullValue()).body("result_count", equalTo(2)).body("result", hasSize(2)).body("result[0].type", equalTo("ScriptTest")).body("result[0].depth", equalTo(0)).body("result[0].name", equalTo("ScriptTest1")).body("result[0].children[0].type", equalTo("ScriptTest")).body("result[0].children[0].depth", equalTo(1)).body("result[0].children[0].name", equalTo("ScriptTest2")).body("result[0].children[0].parents[0].type", equalTo("ScriptTest")).body("result[0].children[0].parents[0].depth", equalTo(2)).body("result[0].children[0].parents[0].name", equalTo("ScriptTest1")).body("result[0].children[0].parents[0].children[0].type", equalTo("ScriptTest")).body("result[0].children[0].parents[0].children[0].depth", equalTo(3)).body("result[0].children[0].parents[0].children[0].name", equalTo("ScriptTest2")).body("result[1].type", equalTo("ScriptTest")).body("result[1].depth", equalTo(0)).body("result[1].name", equalTo("ScriptTest2")).body("result[1].parents[0].type", equalTo("ScriptTest")).body("result[1].parents[0].depth", equalTo(1)).body("result[1].parents[0].name", equalTo("ScriptTest1")).when().get(resource);
    RestAssured.given().contentType("application/json; charset=UTF-8").header("Accept", "application/json; charset=UTF-8").filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(200)).expect().statusCode(200).body("query_time", notNullValue()).body("serialization_time", notNullValue()).body("result_count", equalTo(1)).body("result.type", equalTo("ScriptTest")).body("result.depth", equalTo(0)).body("result.name", equalTo("ScriptTest1")).body("result.children[0].type", equalTo("ScriptTest")).body("result.children[0].depth", equalTo(1)).body("result.children[0].name", equalTo("ScriptTest2")).body("result.children[0].parents[0].type", equalTo("ScriptTest")).body("result.children[0].parents[0].depth", equalTo(2)).body("result.children[0].parents[0].name", equalTo("ScriptTest1")).body("result.children[0].parents[0].children[0].type", equalTo("ScriptTest")).body("result.children[0].parents[0].children[0].depth", equalTo(3)).body("result.children[0].parents[0].children[0].name", equalTo("ScriptTest2")).when().get(resource.concat("/").concat(uuid));
}
Also used : SchemaNode(org.structr.core.entity.SchemaNode) Tx(org.structr.core.graph.Tx) StringProperty(org.structr.core.property.StringProperty) Test(org.junit.Test)

Example 23 with SchemaNode

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

the class AdvancedSearchTest method testSearchDynamicNodes.

@Test
public void testSearchDynamicNodes() {
    try {
        SchemaNode node = null;
        // setup
        try (final Tx tx = app.tx()) {
            node = app.create(SchemaNode.class, new NodeAttribute(SchemaNode.name, "TestType"));
            node.setProperty(new StringProperty("_test"), "Integer");
            tx.success();
        }
        // fetch dynamic type info
        final Class dynamicType = StructrApp.getConfiguration().getNodeEntityClass("TestType");
        final PropertyKey testKey = StructrApp.key(dynamicType, "test");
        // modify schema node but keep reference to "old" type
        try (final Tx tx = app.tx()) {
            node.setProperty(new StringProperty("_test2"), "String");
            tx.success();
        }
        // create test nodes
        try (final Tx tx = app.tx()) {
            app.create(dynamicType, new NodeAttribute(testKey, 10));
            app.create(dynamicType, new NodeAttribute(testKey, 11));
            app.create(dynamicType, new NodeAttribute(testKey, 12));
            tx.success();
        }
        // query test nodes
        try (final Tx tx = app.tx()) {
            /*
				 * If this test fails, the method "allSubtypes" in SearchCommand was not able to identify
				 * a dynamic type as being assignable to itself. This can happen when the reference to an
				 * existing dynamic type is used after the type has been modified, because the class
				 * instances produced by the dynamic schema ClassLoader are not equal even if they have
				 * the same name and package etc.
				 */
            assertEquals("Query for dynamic node should return exactly one result: ", 1, app.nodeQuery(dynamicType).and(testKey, 10).getAsList().size());
            tx.success();
        }
    } catch (FrameworkException ex) {
        logger.warn("", ex);
        fail("Unexpected exception");
    }
}
Also used : SchemaNode(org.structr.core.entity.SchemaNode) NodeAttribute(org.structr.core.graph.NodeAttribute) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) StringProperty(org.structr.core.property.StringProperty) PropertyKey(org.structr.core.property.PropertyKey) Test(org.junit.Test) IndexingTest(org.structr.rest.common.IndexingTest)

Example 24 with SchemaNode

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

use of org.structr.core.entity.SchemaNode 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)

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