use of org.structr.core.graph.RelationshipInterface in project structr by structr.
the class StructrUiTest method createTestRelationships.
protected List<RelationshipInterface> createTestRelationships(final Class relType, final int number) throws FrameworkException {
List<GenericNode> nodes = createTestNodes(GenericNode.class, 2);
final GenericNode startNode = nodes.get(0);
final GenericNode endNode = nodes.get(1);
List<RelationshipInterface> rels = new LinkedList<>();
for (int i = 0; i < number; i++) {
rels.add(app.create(startNode, endNode, relType));
}
return rels;
}
use of org.structr.core.graph.RelationshipInterface in project structr by structr.
the class WebsocketController method getMessageForEvent.
// ----- private methods -----
private WebSocketMessage getMessageForEvent(final SecurityContext securityContext, final ModificationEvent modificationEvent) throws FrameworkException {
final String callbackId = modificationEvent.getCallbackId();
if (modificationEvent.isNode()) {
final NodeInterface node = (NodeInterface) modificationEvent.getGraphObject();
if (modificationEvent.isDeleted()) {
final WebSocketMessage message = createMessage("DELETE", callbackId);
message.setId(modificationEvent.getRemovedProperties().get(GraphObject.id));
message.setCode(200);
return message;
}
if (modificationEvent.isCreated()) {
final WebSocketMessage message = createMessage("CREATE", callbackId);
message.setGraphObject(node);
message.setResult(Arrays.asList(new GraphObject[] { node }));
message.setCode(201);
return message;
}
if (modificationEvent.isModified()) {
final WebSocketMessage message = createMessage("UPDATE", callbackId);
// at login the securityContext is still null
if (securityContext != null) {
// only include changed properties (+ id and type)
LinkedHashSet<String> propertySet = new LinkedHashSet();
propertySet.add("id");
propertySet.add("type");
for (Iterator<PropertyKey> it = modificationEvent.getModifiedProperties().keySet().iterator(); it.hasNext(); ) {
final String jsonName = ((PropertyKey) it.next()).jsonName();
if (!propertySet.contains(jsonName)) {
propertySet.add(jsonName);
}
}
for (Iterator<PropertyKey> it = modificationEvent.getRemovedProperties().keySet().iterator(); it.hasNext(); ) {
final String jsonName = ((PropertyKey) it.next()).jsonName();
if (!propertySet.contains(jsonName)) {
propertySet.add(jsonName);
}
}
if (propertySet.size() > 2) {
securityContext.setCustomView(propertySet);
}
}
message.setGraphObject(node);
message.setResult(Arrays.asList(new GraphObject[] { node }));
message.setId(node.getUuid());
message.getModifiedProperties().addAll(modificationEvent.getModifiedProperties().keySet());
message.getRemovedProperties().addAll(modificationEvent.getRemovedProperties().keySet());
message.setNodeData(modificationEvent.getData(securityContext));
message.setCode(200);
if (securityContext != null) {
// Clear custom view here. This is necessary because the security context is reused for all websocket frames.
securityContext.clearCustomView();
}
return message;
}
} else {
// handle relationship
final RelationshipInterface relationship = (RelationshipInterface) modificationEvent.getGraphObject();
final RelationshipType relType = modificationEvent.getRelationshipType();
// special treatment of CONTAINS relationships
if ("CONTAINS".equals(relType.name())) {
if (modificationEvent.isDeleted()) {
final WebSocketMessage message = createMessage("REMOVE_CHILD", callbackId);
message.setNodeData("parentId", relationship.getSourceNodeId());
message.setId(relationship.getTargetNodeId());
message.setCode(200);
return message;
}
if (modificationEvent.isCreated()) {
final WebSocketMessage message = new WebSocketMessage();
final NodeInterface startNode = relationship.getSourceNode();
final NodeInterface endNode = relationship.getTargetNode();
// don't send a notification
if (startNode == null || endNode == null) {
return null;
}
message.setResult(Arrays.asList(new GraphObject[] { endNode }));
message.setId(endNode.getUuid());
message.setNodeData("parentId", startNode.getUuid());
message.setCode(200);
message.setCommand("APPEND_CHILD");
if (endNode instanceof DOMNode) {
org.w3c.dom.Node refNode = ((DOMNode) endNode).getNextSibling();
if (refNode != null) {
message.setCommand("INSERT_BEFORE");
message.setNodeData("refId", ((AbstractNode) refNode).getUuid());
}
} else if (endNode instanceof User) {
message.setCommand("APPEND_USER");
message.setNodeData("refId", startNode.getUuid());
} else if (endNode instanceof AbstractFile) {
message.setCommand("APPEND_FILE");
message.setNodeData("refId", startNode.getUuid());
}
return message;
}
}
if (modificationEvent.isDeleted()) {
final WebSocketMessage message = createMessage("DELETE", callbackId);
message.setId(modificationEvent.getRemovedProperties().get(GraphObject.id));
message.setCode(200);
return message;
}
if (modificationEvent.isModified()) {
final WebSocketMessage message = createMessage("UPDATE", callbackId);
message.getModifiedProperties().addAll(modificationEvent.getModifiedProperties().keySet());
message.getRemovedProperties().addAll(modificationEvent.getRemovedProperties().keySet());
message.setNodeData(modificationEvent.getData(securityContext));
message.setGraphObject(relationship);
message.setId(relationship.getUuid());
message.setCode(200);
final PropertyMap relProperties = relationship.getProperties();
// final NodeInterface startNode = relationship.getSourceNode();
// final NodeInterface endNode = relationship.getTargetNode();
// relProperties.put(new StringProperty("startNodeId"), startNode.getUuid());
// relProperties.put(new StringProperty("endNodeId"), endNode.getUuid());
final Map<String, Object> properties = PropertyMap.javaTypeToInputType(securityContext, relationship.getClass(), relProperties);
message.setRelData(properties);
return message;
}
}
return null;
}
use of org.structr.core.graph.RelationshipInterface in project structr by structr.
the class CreateRelationshipCommand method processMessage.
@Override
public void processMessage(final WebSocketMessage webSocketData) {
final Map<String, Object> properties = webSocketData.getRelData();
final String sourceId = (String) properties.get("sourceId");
final String targetId = (String) properties.get("targetId");
final String relType = (String) properties.get("relType");
final AbstractNode sourceNode = getNode(sourceId);
final AbstractNode targetNode = getNode(targetId);
if ((sourceNode != null) && (targetNode != null)) {
final SecurityContext securityContext = getWebSocket().getSecurityContext();
final App app = StructrApp.getInstance(securityContext);
try {
final Class relationClass = StructrApp.getConfiguration().getRelationClassForCombinedType(sourceNode.getType(), relType, targetNode.getType());
final RelationshipInterface rel = app.create(sourceNode, targetNode, relationClass);
TransactionCommand.registerRelCallback(rel, callback);
if (rel != null) {
webSocketData.setResult(Arrays.asList(rel));
getWebSocket().send(webSocketData, true);
}
} catch (FrameworkException t) {
getWebSocket().send(MessageBuilder.status().code(400).message(t.getMessage()).build(), true);
}
} else {
getWebSocket().send(MessageBuilder.status().code(400).message("The CREATE_RELATIONSHIP command needs source and target!").build(), true);
}
}
use of org.structr.core.graph.RelationshipInterface in project structr by structr.
the class RemoveFromCollectionCommand method processMessage.
// ~--- methods --------------------------------------------------------
@Override
public void processMessage(final WebSocketMessage webSocketData) {
final String keyString = (String) webSocketData.getNodeData().get("key");
if (keyString == null) {
logger.error("Unable to remove given object from collection: key is null");
getWebSocket().send(MessageBuilder.status().code(400).build(), true);
}
final String idToRemove = (String) webSocketData.getNodeData().get("idToRemove");
if (idToRemove == null) {
logger.error("Unable to remove given object from collection: idToRemove is null");
getWebSocket().send(MessageBuilder.status().code(400).build(), true);
}
GraphObject obj = getNode(webSocketData.getId());
if (obj != null) {
if (!((AbstractNode) obj).isGranted(Permission.write, getWebSocket().getSecurityContext())) {
getWebSocket().send(MessageBuilder.status().message("No write permission").code(400).build(), true);
logger.warn("No write permission for {} on {}", new Object[] { getWebSocket().getCurrentUser().toString(), obj.toString() });
return;
}
}
if (obj == null) {
// No node? Try to find relationship
obj = getRelationship(webSocketData.getId());
}
GraphObject objToRemove = getNode(idToRemove);
if (obj != null && objToRemove != null) {
try {
PropertyKey key = StructrApp.key(obj.getClass(), keyString);
if (key != null) {
List collection = (List) obj.getProperty(key);
collection.remove(objToRemove);
obj.setProperties(obj.getSecurityContext(), new PropertyMap(key, collection));
if (obj instanceof NodeInterface) {
TransactionCommand.registerNodeCallback((NodeInterface) obj, callback);
} else if (obj instanceof RelationshipInterface) {
TransactionCommand.registerRelCallback((RelationshipInterface) obj, callback);
}
}
} catch (FrameworkException ex) {
logger.error("Unable to set properties: {}", ((FrameworkException) ex).toString());
getWebSocket().send(MessageBuilder.status().code(400).build(), true);
}
} else {
logger.warn("Graph object with uuid {} not found.", webSocketData.getId());
getWebSocket().send(MessageBuilder.status().code(404).build(), true);
}
}
use of org.structr.core.graph.RelationshipInterface in project structr by structr.
the class DOMElement method renderContent.
static void renderContent(final DOMElement thisElement, final RenderContext renderContext, final int depth) throws FrameworkException {
if (thisElement.isDeleted() || thisElement.isHidden() || !thisElement.displayForLocale(renderContext) || !thisElement.displayForConditions(renderContext)) {
return;
}
// final variables
final SecurityContext securityContext = renderContext.getSecurityContext();
final AsyncBuffer out = renderContext.getBuffer();
final EditMode editMode = renderContext.getEditMode(securityContext.getUser(false));
final boolean isVoid = thisElement.isVoidElement();
final String _tag = thisElement.getTag();
// non-final variables
Result localResult = renderContext.getResult();
boolean anyChildNodeCreatesNewLine = false;
thisElement.renderStructrAppLib(out, securityContext, renderContext, depth);
if (depth > 0 && !thisElement.avoidWhitespace()) {
out.append(DOMNode.indent(depth, renderContext));
}
if (StringUtils.isNotBlank(_tag)) {
if (EditMode.DEPLOYMENT.equals(editMode)) {
// comment accordingly.
if (DOMNode.renderDeploymentExportComments(thisElement, out, false)) {
// restore indentation
if (depth > 0 && !thisElement.avoidWhitespace()) {
out.append(DOMNode.indent(depth, renderContext));
}
}
}
thisElement.openingTag(out, _tag, editMode, renderContext, depth);
try {
// in body?
if (lowercaseBodyName.equals(thisElement.getTagName())) {
renderContext.setInBody(true);
}
// only render children if we are not in a shared component scenario and not in deployment mode
if (thisElement.getSharedComponent() == null || !EditMode.DEPLOYMENT.equals(editMode)) {
// fetch children
final List<RelationshipInterface> rels = thisElement.getChildRelationships();
if (rels.isEmpty()) {
// No child relationships, maybe this node is in sync with another node
final DOMElement _syncedNode = (DOMElement) thisElement.getSharedComponent();
if (_syncedNode != null) {
rels.addAll(_syncedNode.getChildRelationships());
}
}
// apply configuration for shared component if present
final String _sharedComponentConfiguration = thisElement.getProperty(StructrApp.key(DOMElement.class, "sharedComponentConfiguration"));
if (StringUtils.isNotBlank(_sharedComponentConfiguration)) {
Scripting.evaluate(renderContext, thisElement, "${" + _sharedComponentConfiguration + "}", "shared component configuration");
}
for (final RelationshipInterface rel : rels) {
final DOMNode subNode = (DOMNode) rel.getTargetNode();
if (subNode instanceof DOMElement) {
anyChildNodeCreatesNewLine = (anyChildNodeCreatesNewLine || !(subNode.avoidWhitespace()));
}
subNode.render(renderContext, depth + 1);
}
}
} catch (Throwable t) {
out.append("Error while rendering node ").append(thisElement.getUuid()).append(": ").append(t.getMessage());
logger.warn("", t);
}
// render end tag, if needed (= if not singleton tags)
if (StringUtils.isNotBlank(_tag) && (!isVoid)) {
// only insert a newline + indentation before the closing tag if any child-element used a newline
final DOMElement _syncedNode = (DOMElement) thisElement.getSharedComponent();
final boolean isTemplate = _syncedNode != null && EditMode.DEPLOYMENT.equals(editMode);
if (anyChildNodeCreatesNewLine || isTemplate) {
out.append(DOMNode.indent(depth, renderContext));
}
if (_syncedNode != null && EditMode.DEPLOYMENT.equals(editMode)) {
out.append("</structr:component>");
} else if (isTemplate) {
out.append("</structr:template>");
} else {
out.append("</").append(_tag).append(">");
}
}
}
// Set result for this level again, if there was any
if (localResult != null) {
renderContext.setResult(localResult);
}
}
Aggregations