@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); } }
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."); } }
@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); } }
@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); } }
@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); } }