@Override
  public void processMessage(final WebSocketMessage webSocketData) {

    final SecurityContext securityContext = getWebSocket().getSecurityContext();
    final int pageSize = webSocketData.getPageSize();
    final int page = webSocketData.getPage();

    final App app = StructrApp.getInstance(securityContext);

    try (final Tx tx = app.tx()) {

      // do search
      List<AbstractNode> filteredResults = getUnattachedNodes(app, securityContext, webSocketData);

      // save raw result count
      int resultCountBeforePaging = filteredResults.size();

      // set full result list
      webSocketData.setResult(PagingHelper.subList(filteredResults, pageSize, page, null));
      webSocketData.setRawResultCount(resultCountBeforePaging);

      // send only over local connection
      getWebSocket().send(webSocketData, true);

      tx.success();

    } catch (FrameworkException fex) {

      logger.warn("Exception occured", fex);
      getWebSocket()
          .send(
              MessageBuilder.status().code(fex.getStatus()).message(fex.getMessage()).build(),
              true);
    }
  }
Exemple #2
0
  public void send(final WebSocketMessage message, final boolean clearSessionId) {

    // return session status to client
    message.setSessionValid(isAuthenticated());

    // whether to clear the token (all command except LOGIN (for now) should absolutely do this!)
    if (clearSessionId) {

      message.setSessionId(null);
    }

    // set callback
    message.setCallback(callback);
    if (isAuthenticated() || "STATUS".equals(message.getCommand())) {

      String msg = gson.toJson(message, WebSocketMessage.class);

      logger.log(
          Level.FINE,
          "############################################################ SENDING \n{0}",
          msg);

      try {

        session.getRemote().sendString(msg);

      } catch (Throwable t) {
        logger.log(Level.WARNING, "Unable to send websocket message to remote client");
      }

    } else {

      logger.log(Level.WARNING, "NOT sending message to unauthenticated client.");
    }
  }
Exemple #3
0
  @Override
  public void processMessage(final WebSocketMessage webSocketData) {

    final GraphObject obj = getGraphObject(webSocketData.getId());
    String key = (String) webSocketData.getNodeData().get("key");

    if (obj != null) {

      PropertyKey propertyKey =
          StructrApp.getConfiguration().getPropertyKeyForJSONName(obj.getClass(), key);
      PropertyConverter converter = propertyKey.inputConverter(getWebSocket().getSecurityContext());

      Object value = obj.getProperty(propertyKey);
      if (converter != null) {

        try {
          value = converter.revert(value);

        } catch (FrameworkException ex) {

          getWebSocket()
              .send(MessageBuilder.status().code(400).message(ex.getMessage()).build(), true);
        }
      }

      webSocketData.setNodeData(key, value);

      // send only over local connection (no broadcast)
      getWebSocket().send(webSocketData, true);

    } else {

      getWebSocket().send(MessageBuilder.status().code(404).build(), true);
    }
  }
  @Override
  public void processMessage(final WebSocketMessage webSocketData) {

    final String type = (String) webSocketData.getNodeData().get("type");

    if (type == null) {
      logger.log(Level.WARNING, "Node type given not found");
      getWebSocket().send(MessageBuilder.status().code(400).build(), true);
    }

    final SecurityContext securityContext = getWebSocket().getSecurityContext();
    final App app = StructrApp.getInstance(securityContext);

    final SchemaNode typeNode;
    try {
      typeNode = app.nodeQuery(SchemaNode.class).andName(type).getFirst();

      if (typeNode != null) {

        webSocketData.setResult(Arrays.asList(typeNode));

        // send only over local connection (no broadcast)
        getWebSocket().send(webSocketData, true);
      }
    } catch (FrameworkException ex) {
      logger.log(Level.SEVERE, null, ex);
      getWebSocket().send(MessageBuilder.status().code(500).build(), true);
    }
  }
  @Override
  public void processMessage(WebSocketMessage webSocketData) {

    final App app = StructrApp.getInstance(getWebSocket().getSecurityContext());
    final String id = webSocketData.getId();
    final Map<String, Object> nodeData = webSocketData.getNodeData();
    final String source = (String) nodeData.get("source");
    final String name = (String) nodeData.get("name");

    // check for ID
    if (id == null) {

      getWebSocket()
          .send(
              MessageBuilder.status().code(422).message("Cannot create widget without id").build(),
              true);

      return;
    }

    // check if parent node with given ID exists
    DOMNode node = getDOMNode(id);

    if (node == null) {

      getWebSocket()
          .send(MessageBuilder.status().code(404).message("Node not found").build(), true);

      return;
    }

    try {

      // convertFromInput
      PropertyMap properties = new PropertyMap();

      properties.put(AbstractNode.type, Widget.class.getSimpleName());
      properties.put(AbstractNode.name, name);
      properties.put(Widget.source, source);

      app.create(Widget.class, properties);

    } catch (Throwable t) {

      logger.log(Level.WARNING, t.toString());

      // send exception
      getWebSocket().send(MessageBuilder.status().code(422).message(t.toString()).build(), true);
    }
  }
  /**
   * Return list of nodes which are not attached to a page and have no parent element (no incoming
   * CONTAINS rel)
   *
   * @param app
   * @param securityContext
   * @param webSocketData
   * @return
   * @throws FrameworkException
   */
  protected static List<AbstractNode> getUnattachedNodes(
      final App app, final SecurityContext securityContext, final WebSocketMessage webSocketData)
      throws FrameworkException {

    final String sortOrder = webSocketData.getSortOrder();
    final String sortKey = webSocketData.getSortKey();
    final PropertyKey sortProperty =
        StructrApp.getConfiguration().getPropertyKeyForJSONName(DOMNode.class, sortKey);
    final Query query =
        StructrApp.getInstance(securityContext)
            .nodeQuery()
            .includeDeletedAndHidden()
            .sort(sortProperty)
            .order("desc".equals(sortOrder));

    query.orTypes(DOMElement.class);
    query.orType(Content.class);
    query.orType(Template.class);

    // do search
    List<AbstractNode> filteredResults = new LinkedList();
    List<? extends GraphObject> resultList = null;

    try (final Tx tx = app.tx()) {

      resultList = query.getAsList();

    } catch (FrameworkException fex) {
      logger.warn("Exception occured", fex);
    }

    // determine which of the nodes have no incoming CONTAINS relationships and no page id
    for (GraphObject obj : resultList) {

      if (obj instanceof AbstractNode) {

        AbstractNode node = (AbstractNode) obj;

        if (!node.hasIncomingRelationships(DOMChildren.class)
            && node.getProperty(DOMNode.ownerDocument) == null
            && !(node instanceof ShadowDocument)) {

          filteredResults.add(node);
        }
      }
    }

    return filteredResults;
  }
  @Override
  public void processMessage(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.log(Level.WARNING, "Exception occured", fex);
      getWebSocket()
          .send(
              MessageBuilder.status().code(fex.getStatus()).message(fex.getMessage()).build(),
              true);
    }
  }
  @Override
  public void processMessage(WebSocketMessage webSocketData) {

    AbstractNode obj = getNode(webSocketData.getId());
    boolean rec = (Boolean) webSocketData.getNodeData().get("recursive");
    String principalId = (String) webSocketData.getNodeData().get("principalId");
    String permission = (String) webSocketData.getNodeData().get("permission");
    String action = (String) webSocketData.getNodeData().get("action");

    if (principalId == null) {

      logger.log(Level.SEVERE, "This command needs a principalId");
      getWebSocket().send(MessageBuilder.status().code(400).build(), true);
    }

    Principal principal = (Principal) getNode(principalId);

    if (principal == null) {

      logger.log(Level.SEVERE, "No principal found with id {0}", new Object[] {principalId});
      getWebSocket().send(MessageBuilder.status().code(400).build(), true);
    }

    webSocketData.getNodeData().remove("recursive");

    if (obj != null) {

      if (!getWebSocket()
          .getSecurityContext()
          .isAllowed(((AbstractNode) obj), Permission.accessControl)) {

        logger.log(
            Level.WARNING,
            "No access control permission for {0} on {1}",
            new Object[] {getWebSocket().getCurrentUser().toString(), obj.toString()});
        getWebSocket()
            .send(
                MessageBuilder.status().message("No access control permission").code(400).build(),
                true);
        return;
      }

      try {
        setPermission(obj, principal, action, permission, rec);

      } catch (FrameworkException ex) {

        logger.log(
            Level.SEVERE, "Unable to set permissions: {0}", ((FrameworkException) ex).toString());
        getWebSocket().send(MessageBuilder.status().code(400).build(), true);
      }

    } else {

      logger.log(Level.WARNING, "Graph object with uuid {0} not found.", webSocketData.getId());
      getWebSocket().send(MessageBuilder.status().code(404).build(), true);
    }
  }
Exemple #9
0
  @Override
  public void onWebSocketText(final String data) {

    if (data == null) {
      logger.log(Level.WARNING, "Empty text message received.");
      return;
    }

    logger.log(
        Level.FINE,
        "############################################################ RECEIVED \n{0}",
        data.substring(0, Math.min(data.length(), 1000)));

    // parse web socket data from JSON
    final WebSocketMessage webSocketData = gson.fromJson(data, WebSocketMessage.class);

    final App app = StructrApp.getInstance(securityContext);

    try (final Tx tx = app.tx()) {

      this.callback = webSocketData.getCallback();

      final String command = webSocketData.getCommand();
      final Class type = commandSet.get(command);

      final String sessionIdFromMessage = webSocketData.getSessionId();

      if (type != null) {

        if (sessionIdFromMessage != null) {

          // try to authenticated this connection by sessionId
          authenticate(sessionIdFromMessage);
        }

        // we only permit LOGIN commands if authentication based on sessionId was not successful
        if (!isAuthenticated() && !type.equals(LoginCommand.class)) {

          // send 401 Authentication Required
          send(MessageBuilder.status().code(401).message("").build(), true);

          return;
        }

        AbstractCommand abstractCommand = (AbstractCommand) type.newInstance();

        abstractCommand.setWebSocket(this);
        abstractCommand.setSession(session);
        abstractCommand.setIdProperty(idProperty);

        // store authenticated-Flag in webSocketData
        // so the command can access it
        webSocketData.setSessionValid(isAuthenticated());

        // process message
        try {

          abstractCommand.processMessage(webSocketData);

          // commit transaction
          tx.success();

        } catch (FrameworkException fex) {

          fex.printStackTrace(System.out);

          // send 400 Bad Request
          send(MessageBuilder.status().code(400).message(fex.toString()).build(), true);
        }

      } else {

        logger.log(Level.WARNING, "Unknow command {0}", command);

        // send 400 Bad Request
        send(MessageBuilder.status().code(400).message("Unknown command").build(), true);
      }

    } catch (FrameworkException | IllegalAccessException | InstantiationException t) {

      logger.log(Level.WARNING, "Unable to parse message.", t);
    }
  }
Exemple #10
0
  @Override
  public void processMessage(final WebSocketMessage webSocketData) {

    final SecurityContext securityContext = getWebSocket().getSecurityContext();
    final String id = webSocketData.getId();

    if (id != null) {

      final NodeInterface node = getNode(id);

      if (node != null) {

        if (node instanceof DOMNode) {

          // Use new DOM interface
          DOMNode domNode = (DOMNode) node;

          try {

            domNode.getParentNode().removeChild(domNode);

            // Remove node from page
            final PropertyMap changedProperties = new PropertyMap();
            changedProperties.put(DOMNode.syncedNodes, Collections.EMPTY_LIST);
            changedProperties.put(DOMNode.pageId, null);
            domNode.setProperties(securityContext, changedProperties);

          } catch (DOMException | FrameworkException ex) {

            logger.error("Could not remove node from page " + domNode, ex);
            getWebSocket()
                .send(MessageBuilder.status().code(422).message(ex.getMessage()).build(), true);
          }

        } else {

          final App app = StructrApp.getInstance(securityContext);

          try {

            // Old style: Delete all incoming CONTAINS rels
            for (AbstractRelationship rel : node.getIncomingRelationships()) {

              if ("CONTAINS".equals(rel.getType())) {

                app.delete(rel);
              }
            }

          } catch (Throwable t) {

            logger.error("Could not delete relationship", t);
            getWebSocket()
                .send(
                    MessageBuilder.status()
                        .code(400)
                        .message("Error in RemoveCommand: " + t.getMessage())
                        .build(),
                    true);
          }
        }

      } else {

        getWebSocket().send(MessageBuilder.status().code(404).build(), true);
      }

    } else {

      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(400)
                  .message("RemoveCommand called with empty id")
                  .build(),
              true);
    }
  }
  @Override
  public void processMessage(WebSocketMessage webSocketData) {

    final Map<String, Object> nodeData = webSocketData.getNodeData();
    final String parentId = (String) nodeData.get("parentId");
    final String pageId = webSocketData.getPageId();

    nodeData.remove("parentId");

    if (pageId != null) {

      // check for parent ID before creating any nodes
      if (parentId == null) {

        getWebSocket()
            .send(
                MessageBuilder.status()
                    .code(422)
                    .message("Cannot add node without parentId")
                    .build(),
                true);
        return;
      }

      // check if content node with given ID exists
      final DOMNode contentNode = getDOMNode(parentId);
      if (contentNode == null) {

        getWebSocket()
            .send(MessageBuilder.status().code(404).message("Parent node not found").build(), true);
        return;
      }

      final Document document = getPage(pageId);
      if (document != null) {

        final String tagName = (String) nodeData.get("tagName");
        nodeData.remove("tagName");

        final DOMNode parentNode = (DOMNode) contentNode.getParentNode();

        try {

          DOMNode elementNode = null;
          if (tagName != null && !tagName.isEmpty()) {

            elementNode = (DOMNode) document.createElement(tagName);
          }

          // append new node to parent parent node
          if (elementNode != null) {

            parentNode.appendChild(elementNode);
          }

          // append new node to parent parent node
          if (elementNode != null) {

            // append content node to new node
            elementNode.appendChild(contentNode);
          }

        } catch (DOMException dex) {

          // send DOM exception
          getWebSocket()
              .send(MessageBuilder.status().code(422).message(dex.getMessage()).build(), true);
        }

      } else {

        getWebSocket()
            .send(MessageBuilder.status().code(404).message("Page not found").build(), true);
      }

    } else {

      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Cannot create node without pageId")
                  .build(),
              true);
    }
  }
  @Override
  public void processMessage(final WebSocketMessage webSocketData) {

    String id = webSocketData.getId();
    Map<String, Object> nodeData = webSocketData.getNodeData();
    String parentId = (String) nodeData.get("parentId");

    // check node to append
    if (id == null) {

      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Cannot append node, no id is given")
                  .build(),
              true);

      return;
    }

    // check for parent ID
    if (parentId == null) {

      getWebSocket()
          .send(
              MessageBuilder.status().code(422).message("Cannot add node without parentId").build(),
              true);

      return;
    }

    // check if parent node with given ID exists
    AbstractNode parentNode = getNode(parentId);

    if (parentNode == null) {

      getWebSocket()
          .send(MessageBuilder.status().code(404).message("Parent node not found").build(), true);

      return;
    }

    if (parentNode instanceof DOMNode) {

      DOMNode parentDOMNode = getDOMNode(parentId);

      if (parentDOMNode == null) {

        getWebSocket()
            .send(
                MessageBuilder.status().code(422).message("Parent node is no DOM node").build(),
                true);

        return;
      }

      DOMNode node = (DOMNode) getDOMNode(id);

      // append node to parent
      if (node != null) {

        parentDOMNode.appendChild(node);
      }

    } else {

      // send exception
      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Cannot use given node, not instance of DOMNode")
                  .build(),
              true);
    }
  }
  @Override
  public JsonElement serialize(
      WebSocketMessage src, Type typeOfSrc, JsonSerializationContext context) {

    JsonObject root = new JsonObject();
    JsonObject jsonNodeData = new JsonObject();
    JsonObject jsonRelData = new JsonObject();
    JsonArray removedProperties = new JsonArray();
    JsonArray modifiedProperties = new JsonArray();

    if (src.getCommand() != null) {

      root.add("command", new JsonPrimitive(src.getCommand()));
    }

    if (src.getId() != null) {

      root.add("id", new JsonPrimitive(src.getId()));
    }

    if (src.getPageId() != null) {

      root.add("pageId", new JsonPrimitive(src.getPageId()));
    }

    if (src.getMessage() != null) {

      root.add("message", new JsonPrimitive(src.getMessage()));
    }

    if (src.getCode() != 0) {

      root.add("code", new JsonPrimitive(src.getCode()));
    }

    if (src.getSessionId() != null) {

      root.add("sessionId", new JsonPrimitive(src.getSessionId()));
    }

    if (src.getToken() != null) {

      root.add("token", new JsonPrimitive(src.getToken()));
    }

    if (src.getCallback() != null) {

      root.add("callback", new JsonPrimitive(src.getCallback()));
    }

    if (src.getButton() != null) {

      root.add("button", new JsonPrimitive(src.getButton()));
    }

    if (src.getParent() != null) {

      root.add("parent", new JsonPrimitive(src.getParent()));
    }

    if (src.getView() != null) {

      root.add("view", new JsonPrimitive(src.getView()));
    }

    if (src.getSortKey() != null) {

      root.add("sort", new JsonPrimitive(src.getSortKey()));
    }

    if (src.getSortOrder() != null) {

      root.add("order", new JsonPrimitive(src.getSortOrder()));
    }

    if (src.getPageSize() > 0) {

      root.add("pageSize", new JsonPrimitive(src.getPageSize()));
    }

    if (src.getPage() > 0) {

      root.add("page", new JsonPrimitive(src.getPage()));
    }

    JsonArray nodesWithChildren = new JsonArray();
    Set<String> nwc = src.getNodesWithChildren();

    if ((nwc != null) && !src.getNodesWithChildren().isEmpty()) {

      for (String nodeId : nwc) {

        nodesWithChildren.add(new JsonPrimitive(nodeId));
      }

      root.add("nodesWithChildren", nodesWithChildren);
    }

    // serialize session valid flag (output only)
    root.add("sessionValid", new JsonPrimitive(src.isSessionValid()));

    // UPDATE only, serialize only removed and modified properties and use the correct values
    if ((src.getGraphObject() != null)) {

      GraphObject graphObject = src.getGraphObject();

      if (!src.getModifiedProperties().isEmpty()) {

        for (PropertyKey modifiedKey : src.getModifiedProperties()) {

          modifiedProperties.add(toJsonPrimitive(modifiedKey));

          //					Object newValue = graphObject.getProperty(modifiedKey);
          //
          //					if (newValue != null) {
          //
          //						if (graphObject instanceof AbstractNode) {
          //
          //							src.getNodeData().put(modifiedKey.jsonName(), newValue);
          //						} else {
          //
          //							src.getRelData().put(modifiedKey.jsonName(), newValue);
          //						}
          //
          //					}

        }

        root.add("modifiedProperties", modifiedProperties);
      }

      if (!src.getRemovedProperties().isEmpty()) {

        for (PropertyKey removedKey : src.getRemovedProperties()) {

          removedProperties.add(toJsonPrimitive(removedKey));
        }

        root.add("removedProperties", removedProperties);
      }
    }

    // serialize node data
    if (src.getNodeData() != null) {

      for (Entry<String, Object> entry : src.getNodeData().entrySet()) {

        Object value = entry.getValue();
        String key = entry.getKey();

        if (value != null) {

          jsonNodeData.add(key, toJsonPrimitive(value));
        }
      }

      root.add("data", jsonNodeData);
    }

    // serialize relationship data
    if (src.getRelData() != null) {

      for (Entry<String, Object> entry : src.getRelData().entrySet()) {

        Object value = entry.getValue();
        String key = entry.getKey();

        if (value != null) {

          jsonRelData.add(key, toJsonPrimitive(value));
        }
      }

      root.add("relData", jsonRelData);
    }

    // serialize result list
    if (src.getResult() != null) {

      if (src.getView() != null) {

        try {
          propertyView.set(null, src.getView());

        } catch (FrameworkException fex) {

          logger.log(Level.WARNING, "Unable to set property view", fex);
        }

      } else {

        try {
          propertyView.set(null, PropertyView.Ui);

        } catch (FrameworkException fex) {

          logger.log(Level.WARNING, "Unable to set property view", fex);
        }
      }

      JsonArray result = new JsonArray();

      for (GraphObject obj : src.getResult()) {

        result.add(graphObjectSerializer.serialize(obj, System.currentTimeMillis()));
      }

      root.add("result", result);
      root.add("rawResultCount", toJsonPrimitive(src.getRawResultCount()));
    }

    // serialize result tree
    //		if (src.getResultTree() != null) {
    //
    //			TreeNode node = src.getResultTree();
    //
    //			root.add("root", buildTree(node, context));
    //
    //		}

    return root;
  }
  @Override
  public WebSocketMessage deserialize(
      JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {

    WebSocketMessage webSocketData = new WebSocketMessage();

    if (json instanceof JsonObject) {

      JsonObject root = json.getAsJsonObject();
      JsonObject nodeData = root.getAsJsonObject("data");
      JsonObject relData = root.getAsJsonObject("relData");

      if (root.has("command")) {

        webSocketData.setCommand(root.getAsJsonPrimitive("command").getAsString());
      }

      if (root.has("id")) {

        webSocketData.setId(root.getAsJsonPrimitive("id").getAsString());
      }

      if (root.has("pageId")) {

        webSocketData.setPageId(root.getAsJsonPrimitive("pageId").getAsString());
      }

      if (root.has("sessionId")) {

        webSocketData.setSessionId(root.getAsJsonPrimitive("sessionId").getAsString());
      }

      if (root.has("token")) {

        webSocketData.setToken(root.getAsJsonPrimitive("token").getAsString());
      }

      if (root.has("callback")) {

        webSocketData.setCallback(root.getAsJsonPrimitive("callback").getAsString());
      }

      if (root.has("button")) {

        webSocketData.setButton(root.getAsJsonPrimitive("button").getAsString());
      }

      if (root.has("parent")) {

        webSocketData.setParent(root.getAsJsonPrimitive("parent").getAsString());
      }

      if (root.has("view")) {

        webSocketData.setView(root.getAsJsonPrimitive("view").getAsString());
      }

      if (root.has("sort")) {

        webSocketData.setSortKey(root.getAsJsonPrimitive("sort").getAsString());
      }

      if (root.has("order")) {

        webSocketData.setSortOrder(root.getAsJsonPrimitive("order").getAsString());
      }

      if (root.has("pageSize")) {

        webSocketData.setPageSize(root.getAsJsonPrimitive("pageSize").getAsInt());
      }

      if (root.has("page")) {

        webSocketData.setPage(root.getAsJsonPrimitive("page").getAsInt());
      }

      if (nodeData != null) {

        for (Entry<String, JsonElement> entry : nodeData.entrySet()) {

          webSocketData.setNodeData(entry.getKey(), entry.getValue().getAsString());
        }
      }

      if (relData != null) {

        for (Entry<String, JsonElement> entry : relData.entrySet()) {

          webSocketData.setRelData(entry.getKey(), entry.getValue().getAsString());
        }
      }
    }

    return webSocketData;
  }
  // ~--- 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.getConfiguration().getPropertyKeyForJSONName(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);
    }
  }
  @Override
  public void processMessage(WebSocketMessage webSocketData) {

    String id = webSocketData.getId();
    Map<String, Object> nodeData = webSocketData.getNodeData();
    String parentId = (String) nodeData.get("parentId");

    // check node to append
    if (id == null) {

      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Cannot append node, no id is given")
                  .build(),
              true);

      return;
    }

    // check for parent ID
    if (parentId == null) {

      getWebSocket()
          .send(
              MessageBuilder.status().code(422).message("Cannot add node without parentId").build(),
              true);

      return;
    }

    // check if parent node with given ID exists
    AbstractNode parentNode = getNode(parentId);

    if (parentNode == null) {

      getWebSocket()
          .send(MessageBuilder.status().code(404).message("Parent node not found").build(), true);

      return;
    }

    if (parentNode instanceof Folder) {

      Folder folder = (Folder) parentNode;

      AbstractFile file = (AbstractFile) getNode(id);

      if (file != null) {
        try {
          // Remove from existing parent
          LinkedTreeNode currentParent = file.treeGetParent(RelType.CONTAINS);
          if (currentParent != null) {

            currentParent.treeRemoveChild(RelType.CONTAINS, file);
          }

          folder.treeAppendChild(RelType.CONTAINS, file);
        } catch (FrameworkException ex) {
          logger.log(Level.SEVERE, null, ex);
          getWebSocket()
              .send(MessageBuilder.status().code(422).message("Cannot append file").build(), true);
        }
      }

    } else {

      // send exception
      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Parent node is not instance of Folder")
                  .build(),
              true);
    }
  }
  @Override
  public void processMessage(WebSocketMessage webSocketData) {

    final Map<String, Object> nodeData = webSocketData.getNodeData();
    final String parentId = (String) nodeData.get("parentId");
    final String childContent = (String) nodeData.get("childContent");
    final String pageId = webSocketData.getPageId();

    nodeData.remove("parentId");

    if (pageId != null) {

      // check for parent ID before creating any nodes
      if (parentId == null) {

        getWebSocket()
            .send(
                MessageBuilder.status()
                    .code(422)
                    .message("Cannot add node without parentId")
                    .build(),
                true);
        return;
      }

      // check if parent node with given ID exists
      final DOMNode parentNode = getDOMNode(parentId);
      if (parentNode == null) {

        getWebSocket()
            .send(MessageBuilder.status().code(404).message("Parent node not found").build(), true);
        return;
      }

      final Document document = getPage(pageId);
      if (document != null) {

        final String tagName = (String) nodeData.get("tagName");
        final App app = StructrApp.getInstance();

        nodeData.remove("tagName");

        try {
          app.beginTx();

          DOMNode newNode;

          if (tagName != null && !tagName.isEmpty()) {

            newNode = (DOMNode) document.createElement(tagName);

          } else {

            newNode = (DOMNode) document.createTextNode("#text");
          }

          // append new node to parent
          if (newNode != null) {

            parentNode.appendChild(newNode);

            for (Entry entry : nodeData.entrySet()) {

              String key = (String) entry.getKey();
              Object val = entry.getValue();

              PropertyKey propertyKey =
                  StructrApp.getConfiguration()
                      .getPropertyKeyForDatabaseName(newNode.getClass(), key);
              if (propertyKey != null) {

                try {
                  Object convertedValue = val;

                  PropertyConverter inputConverter =
                      propertyKey.inputConverter(SecurityContext.getSuperUserInstance());
                  if (inputConverter != null) {

                    convertedValue = inputConverter.convert(val);
                  }

                  // newNode.unlockReadOnlyPropertiesOnce();
                  newNode.setProperty(propertyKey, convertedValue);

                } catch (FrameworkException fex) {

                  logger.log(
                      Level.WARNING,
                      "Unable to set node property {0} of node {1} to {2}: {3}",
                      new Object[] {propertyKey, newNode.getUuid(), val, fex.getMessage()});
                }
              }
            }

            // create a child text node if content is given
            if (StringUtils.isNotBlank(childContent)) {

              DOMNode childNode = (DOMNode) document.createTextNode(childContent);

              if (newNode != null) {

                newNode.appendChild(childNode);
              }
            }
          }
          app.commitTx();

        } catch (DOMException dex) {

          // send DOM exception
          getWebSocket()
              .send(MessageBuilder.status().code(422).message(dex.getMessage()).build(), true);

        } catch (FrameworkException ex) {

          Logger.getLogger(CreateAndAppendDOMNodeCommand.class.getName())
              .log(Level.SEVERE, null, ex);

        } finally {

          app.finishTx();
        }

      } else {

        getWebSocket()
            .send(MessageBuilder.status().code(404).message("Page not found").build(), true);
      }

    } else {

      getWebSocket()
          .send(
              MessageBuilder.status()
                  .code(422)
                  .message("Cannot create node without pageId")
                  .build(),
              true);
    }
  }