use of org.structr.api.graph.Node in project structr by structr.
the class NodeRelationshipsCommand method execute.
// ~--- methods --------------------------------------------------------
/**
* Fetch relationships for the given source node.
*
* @param sourceNode
* @param relType can be null
* @param dir
*
* @return a list of relationships
* @throws FrameworkException
*/
public List<RelationshipInterface> execute(NodeInterface sourceNode, RelationshipType relType, Direction dir) throws FrameworkException {
RelationshipFactory factory = new RelationshipFactory(securityContext);
List<RelationshipInterface> result = new LinkedList<>();
Node node = sourceNode.getNode();
Iterable<Relationship> rels;
if (node == null) {
return Collections.EMPTY_LIST;
}
if (relType != null) {
rels = node.getRelationships(dir, relType);
} else {
rels = node.getRelationships(dir);
}
try {
for (Relationship r : rels) {
result.add(factory.instantiate(r));
}
} catch (RuntimeException e) {
logger.warn("Exception occured: ", e.getMessage());
/**
* ********* FIXME
*
* Here an exception occurs:
*
* org.neo4j.kernel.impl.nioneo.store.InvalidRecordException: Node[5] is neither firstNode[37781] nor secondNode[37782] for Relationship[188125]
* at org.neo4j.kernel.impl.nioneo.xa.ReadTransaction.getMoreRelationships(ReadTransaction.java:131)
* at org.neo4j.kernel.impl.nioneo.xa.NioNeoDbPersistenceSource$ReadOnlyResourceConnection.getMoreRelationships(NioNeoDbPersistenceSource.java:280)
* at org.neo4j.kernel.impl.persistence.PersistenceManager.getMoreRelationships(PersistenceManager.java:100)
* at org.neo4j.kernel.impl.core.NodeManager.getMoreRelationships(NodeManager.java:585)
* at org.neo4j.kernel.impl.core.NodeImpl.getMoreRelationships(NodeImpl.java:358)
* at org.neo4j.kernel.impl.core.IntArrayIterator.hasNext(IntArrayIterator.java:115)
*/
}
return result;
}
use of org.structr.api.graph.Node in project structr by structr.
the class CypherQueryCommand method handleObject.
final Object handleObject(final NodeFactory nodeFactory, final RelationshipFactory relFactory, final String key, final Object value, boolean includeHiddenAndDeleted, boolean publicOnly, int level) throws FrameworkException {
GraphObject graphObject = null;
if (value instanceof Node) {
graphObject = nodeFactory.instantiate((Node) value, includeHiddenAndDeleted, publicOnly);
} else if (value instanceof Relationship) {
graphObject = relFactory.instantiate((Relationship) value);
} else if (value instanceof Map) {
final Map<String, Object> valueMap = (Map<String, Object>) value;
graphObject = new GraphObjectMap();
for (final Entry<String, Object> valueEntry : valueMap.entrySet()) {
final String valueKey = valueEntry.getKey();
final Object valueValue = valueEntry.getValue();
graphObject.setProperty(new GenericProperty(valueKey), handleObject(nodeFactory, relFactory, valueKey, valueValue, includeHiddenAndDeleted, publicOnly, level + 1));
}
} else if (value instanceof Collection) {
final Collection<Object> valueCollection = (Collection<Object>) value;
final List<Object> collection = new LinkedList<>();
for (final Object valueEntry : valueCollection) {
collection.add(handleObject(nodeFactory, relFactory, null, valueEntry, includeHiddenAndDeleted, publicOnly, level + 1));
}
return collection;
} else if (level == 0) {
graphObject = new GraphObjectMap();
graphObject.setProperty(new GenericProperty(key), value);
} else {
return value;
}
return graphObject;
}
use of org.structr.api.graph.Node in project structr by structr.
the class BulkChangeNodePropertyKeyCommand method execute.
// ~--- methods --------------------------------------------------------
@Override
public void execute(final Map<String, Object> properties) throws FrameworkException {
final DatabaseService graphDb = (DatabaseService) arguments.get("graphDb");
final SecurityContext superUserContext = SecurityContext.getSuperUserInstance();
final NodeFactory nodeFactory = new NodeFactory(superUserContext);
String type = null;
final String oldKey = (String) properties.get("oldKey");
final String newKey = (String) properties.get("newKey");
if (graphDb != null && StringUtils.isNotBlank(oldKey) && StringUtils.isNotBlank(newKey)) {
Iterator<AbstractNode> nodeIterator = null;
if (properties.containsKey(AbstractNode.type.dbName())) {
type = (String) properties.get(AbstractNode.type.dbName());
nodeIterator = Iterables.map(nodeFactory, graphDb.getNodesByLabel(type)).iterator();
properties.remove(AbstractNode.type.dbName());
} else {
nodeIterator = Iterables.map(nodeFactory, graphDb.getAllNodes()).iterator();
}
final long count = bulkGraphOperation(securityContext, nodeIterator, 1000, "ChangeNodePropertyKey", new BulkGraphOperation<AbstractNode>() {
@Override
public void handleGraphObject(SecurityContext securityContext, AbstractNode node) {
for (Entry entry : properties.entrySet()) {
String key = (String) entry.getKey();
PropertyKey propertyKey = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(node.getClass(), key);
if (propertyKey != null) {
Node dbNode = node.getNode();
if (dbNode.hasProperty(newKey)) {
logger.error("Node {} has already a property with key {}", new Object[] { node, newKey });
throw new IllegalStateException("Node has already a property of the new key");
}
if (dbNode.hasProperty(oldKey)) {
dbNode.setProperty(newKey, dbNode.getProperty(oldKey));
dbNode.removeProperty(oldKey);
}
node.updateInIndex();
}
}
}
@Override
public void handleThrowable(SecurityContext securityContext, Throwable t, AbstractNode node) {
logger.warn("Unable to set properties of node {}: {}", new Object[] { node.getUuid(), t.getMessage() });
}
@Override
public void handleTransactionFailure(SecurityContext securityContext, Throwable t) {
logger.warn("Unable to set node properties: {}", t.getMessage());
}
});
logger.info("Fixed {} nodes ...", count);
} else {
logger.info("No values for oldKey and/or newKey found, aborting.");
}
logger.info("Done");
}
use of org.structr.api.graph.Node in project structr by structr.
the class MaintenanceTest method testBulkCreateLabelsCommand.
@Test
public void testBulkCreateLabelsCommand() {
try {
final DatabaseService graphDb = app.getDatabaseService();
final Set<Label> expectedLabels = new LinkedHashSet<>();
expectedLabels.add(graphDb.forName(Label.class, "Principal"));
expectedLabels.add(graphDb.forName(Label.class, "Group"));
expectedLabels.add(graphDb.forName(Label.class, "AccessControllable"));
expectedLabels.add(graphDb.forName(Label.class, "AbstractNode"));
expectedLabels.add(graphDb.forName(Label.class, "NodeInterface"));
expectedLabels.add(graphDb.forName(Label.class, "CMISInfo"));
expectedLabels.add(graphDb.forName(Label.class, "CMISItemInfo"));
if (graphDb.getTenantIdentifier() != null) {
expectedLabels.add(graphDb.forName(Label.class, graphDb.getTenantIdentifier()));
}
// intentionally create raw Neo4j transaction and create nodes in there
try (Transaction tx = graphDb.beginTx()) {
for (int i = 0; i < 100; i++) {
final Node test = graphDb.createNode(Collections.EMPTY_SET, Collections.EMPTY_MAP);
// set ID and type so that the rebuild index command identifies it as a Structr node.
test.setProperty("type", "Group");
test.setProperty("id", UUID.randomUUID().toString().replace("-", ""));
}
// this is important.... :)
tx.success();
}
/*
* This test will fail with the new Neo4j 3.0 Bolt interface, because
* there is no separation between a (Lucene-based) index and the
* database values any more. Nodes are selected by their 'type'
* property and will always be found even if NOT created using Structr
* methods.
// nodes should not be found yet..
try (final Tx tx = app.tx()) {
// check nodes, we should find no Groups here
assertEquals(0, app.nodeQuery(Group.class).getResult().size());
}
*/
// test rebuild index and create labels
// app.command(BulkRebuildIndexCommand.class).execute(new LinkedHashMap<>());
app.command(BulkCreateLabelsCommand.class).execute(new LinkedHashMap<>());
// nodes should now be visible to Structr
try (final Tx tx = app.tx()) {
// check nodes, we should find 100 Groups here
assertEquals(100, app.nodeQuery(Group.class).getResult().size());
// check nodes
for (final Group group : app.nodeQuery(Group.class)) {
final Set<Label> labels = Iterables.toSet(group.getNode().getLabels());
assertEquals("Invalid number of labels", expectedLabels.size(), labels.size());
assertTrue("Invalid labels found", labels.containsAll(expectedLabels));
}
tx.success();
}
} catch (FrameworkException fex) {
logger.warn("", fex);
fail("Unexpected exception.");
}
}
use of org.structr.api.graph.Node 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);
}
Aggregations