Search in sources :

Example 66 with GraphObject

use of org.structr.core.GraphObject 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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) User(org.structr.web.entity.User) AbstractFile(org.structr.web.entity.AbstractFile) RelationshipType(org.structr.api.graph.RelationshipType) GraphObject(org.structr.core.GraphObject) PropertyMap(org.structr.core.property.PropertyMap) RelationshipInterface(org.structr.core.graph.RelationshipInterface) GraphObject(org.structr.core.GraphObject) WebSocketMessage(org.structr.websocket.message.WebSocketMessage) DOMNode(org.structr.web.entity.dom.DOMNode) NodeInterface(org.structr.core.graph.NodeInterface) PropertyKey(org.structr.core.property.PropertyKey)

Example 67 with GraphObject

use of org.structr.core.GraphObject in project structr by structr.

the class WebsocketController method broadcast.

private void broadcast(final WebSocketMessage webSocketData, final String exemptedSessionId) {
    // session must be valid to be received by the client
    webSocketData.setSessionValid(true);
    final String pagePath = (String) webSocketData.getNodeData().get("pagePath");
    final String encodedPath = URIUtil.encodePath(pagePath);
    final List<StructrWebSocket> clientsToRemove = new LinkedList<>();
    final List<? extends GraphObject> result = webSocketData.getResult();
    final String command = webSocketData.getCommand();
    final GraphObject obj = webSocketData.getGraphObject();
    String message;
    // create message
    for (StructrWebSocket socket : clients) {
        String clientPagePath = socket.getPagePath();
        if (clientPagePath != null && !clientPagePath.equals(encodedPath)) {
            continue;
        }
        Session session = socket.getSession();
        if (session != null && socket.isAuthenticated()) {
            final SecurityContext securityContext = socket.getSecurityContext();
            if (exemptedSessionId != null && exemptedSessionId.equals(securityContext.getSessionId())) {
                // session id is supposed to be exempted from this broadcast message
                continue;
            }
            // THEN skip sending a message
            if (obj instanceof AbstractNode) {
                final AbstractNode node = (AbstractNode) obj;
                if (node.isHidden() || !securityContext.isVisible(node)) {
                    continue;
                }
            } else {
                if (!socket.isPrivilegedUser(socket.getCurrentUser())) {
                    continue;
                }
            }
            if (result != null && !result.isEmpty() && BroadcastCommands.contains(command)) {
                final WebSocketMessage clientData = webSocketData.copy();
                clientData.setResult(filter(securityContext, result));
                message = gson.toJson(clientData, WebSocketMessage.class);
            } else {
                message = gson.toJson(webSocketData, WebSocketMessage.class);
            }
            try {
                session.getRemote().sendString(message);
            } catch (Throwable t) {
                if (t instanceof WebSocketException) {
                    WebSocketException wse = (WebSocketException) t;
                    if ("RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]".equals(wse.getMessage())) {
                        clientsToRemove.add(socket);
                    }
                }
                logger.debug("Error sending message to client.", t);
            }
        }
    }
    for (StructrWebSocket s : clientsToRemove) {
        unregisterClient(s);
        logger.warn("Client removed from broadcast list: {}", s);
    }
}
Also used : WebSocketException(org.eclipse.jetty.websocket.api.WebSocketException) AbstractNode(org.structr.core.entity.AbstractNode) SecurityContext(org.structr.common.SecurityContext) WebSocketMessage(org.structr.websocket.message.WebSocketMessage) GraphObject(org.structr.core.GraphObject) LinkedList(java.util.LinkedList) Session(org.eclipse.jetty.websocket.api.Session)

Example 68 with GraphObject

use of org.structr.core.GraphObject in project structr by structr.

the class WebappDataCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final Map<String, Object> data = webSocketData.getNodeData();
    final String category = (String) data.get("category");
    final String mode = (String) data.get("mode");
    final String name = (String) data.get("name");
    if (mode != null) {
        final List<GraphObject> result = new LinkedList<>();
        switch(mode) {
            case "list":
                final List<String> values = WebappDataCommand.listValues(category);
                if (values != null) {
                    final GraphObjectMap container = new GraphObjectMap();
                    container.put(namesProperty, values);
                    result.add(container);
                    webSocketData.setResult(result);
                    webSocketData.setRawResultCount(1);
                    getWebSocket().send(webSocketData, true);
                }
                break;
            case "get":
                try {
                    final String content = new String(Files.readAllBytes(locateFile(category, name).toPath()));
                    getWebSocket().send(MessageBuilder.finished().callback(callback).data("value", content).build(), true);
                } catch (IOException | FrameworkException ex) {
                    logger.error("", ex);
                }
                break;
            case "add":
                final String positions = (String) data.get("value");
                try {
                    final File layoutFile = locateFile(category, name);
                    if (layoutFile.exists()) {
                        getWebSocket().send(MessageBuilder.status().code(422).message("Category/name combination already exists!").build(), true);
                    } else {
                        createValue(category, name, positions);
                    }
                    getWebSocket().send(MessageBuilder.finished().callback(callback).build(), true);
                } catch (FrameworkException ex) {
                    logger.error("", ex);
                }
                break;
            case "delete":
                try {
                    deleteValue(category, name);
                    getWebSocket().send(MessageBuilder.finished().callback(callback).build(), true);
                } catch (FrameworkException ex) {
                    logger.error("", ex);
                }
                break;
            default:
                getWebSocket().send(MessageBuilder.status().code(422).message("Mode must be one of list, get, add or delete.").build(), true);
        }
    } else {
        getWebSocket().send(MessageBuilder.status().code(422).message("Mode must be one of list, get, add or delete.").build(), true);
    }
}
Also used : FrameworkException(org.structr.common.error.FrameworkException) GraphObjectMap(org.structr.core.GraphObjectMap) GraphObject(org.structr.core.GraphObject) IOException(java.io.IOException) GraphObject(org.structr.core.GraphObject) File(java.io.File) LinkedList(java.util.LinkedList)

Example 69 with GraphObject

use of org.structr.core.GraphObject in project structr by structr.

the class ListActiveElementsCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final SecurityContext securityContext = getWebSocket().getSecurityContext();
    final App app = StructrApp.getInstance(securityContext);
    final String id = webSocketData.getId();
    try (final Tx tx = app.tx()) {
        final Page page = app.get(Page.class, id);
        final List<GraphObject> result = new LinkedList<>();
        if (page != null) {
            collectActiveElements(result, page, Collections.EMPTY_SET, null, 0);
            // set full result list
            webSocketData.setResult(result);
            webSocketData.setRawResultCount(result.size());
            // send only over local connection
            getWebSocket().send(webSocketData, true);
        } else {
            getWebSocket().send(MessageBuilder.status().code(404).message("Page with ID " + id + " not found.").build(), true);
        }
    } catch (FrameworkException fex) {
        logger.warn("Exception occured", fex);
        getWebSocket().send(MessageBuilder.status().code(fex.getStatus()).message(fex.getMessage()).build(), true);
    }
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) SecurityContext(org.structr.common.SecurityContext) Page(org.structr.web.entity.dom.Page) GraphObject(org.structr.core.GraphObject)

Example 70 with GraphObject

use of org.structr.core.GraphObject 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

GraphObject (org.structr.core.GraphObject)151 FrameworkException (org.structr.common.error.FrameworkException)58 PropertyKey (org.structr.core.property.PropertyKey)39 LinkedList (java.util.LinkedList)35 SecurityContext (org.structr.common.SecurityContext)25 App (org.structr.core.app.App)25 StructrApp (org.structr.core.app.StructrApp)24 Tx (org.structr.core.graph.Tx)23 List (java.util.List)22 PropertyConverter (org.structr.core.converter.PropertyConverter)22 AbstractNode (org.structr.core.entity.AbstractNode)18 GraphObjectMap (org.structr.core.GraphObjectMap)17 NodeInterface (org.structr.core.graph.NodeInterface)17 LinkedHashSet (java.util.LinkedHashSet)15 PropertyMap (org.structr.core.property.PropertyMap)13 Map (java.util.Map)12 RestMethodResult (org.structr.rest.RestMethodResult)11 ConfigurationProvider (org.structr.schema.ConfigurationProvider)10 Result (org.structr.core.Result)9 ArrayList (java.util.ArrayList)8