@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 <T> Comparable getComparableProperty(final PropertyKey<T> key) { if (key != null) { final T propertyValue = getProperty(key, false, null); // get "raw" property without converter // check property converter PropertyConverter converter = key.databaseConverter(securityContext, this); if (converter != null) { try { return converter.convertForSorting(propertyValue); } catch (FrameworkException fex) { logger.log( Level.WARNING, "Unable to convert property {0} of type {1}: {2}", new Object[] {key.dbName(), getClass().getSimpleName(), fex.getMessage()}); } } // conversion failed, may the property value itself is comparable if (propertyValue instanceof Comparable) { return (Comparable) propertyValue; } // last try: convertFromInput to String to make comparable if (propertyValue != null) { return propertyValue.toString(); } } return null; }
@Override public T getProperty( final SecurityContext securityContext, final GraphObject obj, final boolean applyConverter, final Predicate<GraphObject> predicate) { Object value = null; final PropertyContainer propertyContainer = obj.getPropertyContainer(); if (propertyContainer != null) { // this may throw a java.lang.IllegalStateException: Relationship[<id>] has been deleted in // this tx if (propertyContainer.hasProperty(dbName())) { value = propertyContainer.getProperty(dbName()); } } if (applyConverter) { // apply property converters PropertyConverter converter = databaseConverter(securityContext, obj); if (converter != null) { try { value = converter.revert(value); } catch (Throwable t) { logger.warn( "Unable to convert property {} of type {}: {}", new Object[] {dbName(), getClass().getSimpleName(), t}); logger.warn("", t); } } } // no value found, use schema default if (value == null) { value = defaultValue(); } return (T) value; }
private void extractAndSetValue( final NodeInterface obj, final Document doc, final String selector, final String mappedType, final String mappedAttribute, final String mappedAttributeFormat, final SourcePage subPage) throws FrameworkException { // If the sub pattern has a mapped attribute, set the extracted value if (StringUtils.isNotEmpty(mappedAttribute)) { // Extract the value for this sub pattern's selector final String ex = doc.select(selector).text(); final ConfigurationProvider config = StructrApp.getConfiguration(); final PropertyKey key = config.getPropertyKeyForJSONName(type(mappedType), mappedAttribute); if (key != null) { Object convertedValue = ex; final PropertyConverter inputConverter = key.inputConverter(securityContext); if (inputConverter != null) { final String locale = getProperty(mappedAttributeLocaleProperty); DecimalFormat decimalFormat = null; if (key instanceof DoubleProperty) { if (StringUtils.isNotBlank(locale)) { decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance(new Locale(locale)); } else if (StringUtils.isNotBlank(mappedAttributeFormat)) { decimalFormat = new DecimalFormat(mappedAttributeFormat); } if (decimalFormat != null) { convertedValue = decimalFormat.format(convertedValue); } } else { convertedValue = inputConverter.convert(ex); } } obj.setProperty(key, convertedValue); } // If the sub pattern has no mapped attribute but a sub page defined, query the patterns of // the sub page } else if (subPage != null) { final String pageUrl = subPage.getProperty(SourcePage.url); final URI uri; try { uri = new URI(pageUrl); } catch (URISyntaxException ex) { throw new FrameworkException(422, "Unable to parse sub page url: " + pageUrl); } // This is the URL of the linked page derived from the enclosing selector final String subUrl = uri.getScheme() + "://" + uri.getAuthority() + doc.select(selector).attr("href"); // Extract the content of the linked page final String subContent = getContent(subUrl); // Parse the content into a document final Document subDoc = Jsoup.parse(subContent); final List<SourcePattern> subPagePatterns = subPage.getProperty(SourcePage.patterns); // Loop through all patterns of the sub page for (final SourcePattern subPagePattern : subPagePatterns) { final Map<String, Object> params = new HashMap<>(); params.put("document", subDoc); params.put("object", obj); subPagePattern.extract(params); // final String subPagePatternSelector = // subPagePattern.getProperty(SourcePattern.selectorProperty); // // // // Extract // final String subEx = subDoc.select(subPagePatternSelector).text(); // final String subPagePatternType = // subPagePattern.getProperty(SourcePattern.mappedTypeProperty); // // if (subPagePatternType != null) { // // // final Elements subParts = subDoc.select(subPagePatternSelector); // // final Long j = 1L; // // for (final Element subPart : subParts) { // // final NodeInterface subObj = create(subPagePatternType); // // final List<SourcePattern> subPagePatternPatterns = // subPagePattern.getProperty(SourcePattern.subPatternsProperty); // // for (final SourcePattern subPageSubPattern : subPagePatternPatterns) { // // // final String subPagePatternSelector = // subPageSubPattern.getProperty(SourcePattern.selectorProperty); // // // // final String subPageSubPatternSelector = subPagePatternSelector + ":nth-child(" + j // + ") > " + subPagePatternSelector; // // extractAndSetValue(subObj, subDoc, subSelector, mappedType, // subPatternMappedAttribute); // // // final String subSubEx = subDoc.select(subPageSubPatternSelector).text(); // // if (subSubEx != null && subSubEx != = '' && subPageSubPattern.mappedAttribute != // null) { // // final PropertyKey key = config.getPropertyKeyForJSONName(type(mappedType), // subPatternMappedAttribute); // if (key != null) { // // subObj.setProperty(key, subSubEx); // } // // } // // final String subPagePatternMappedAttribute = // subPagePattern.getProperty(SourcePattern.mappedAttributeProperty); // // final PropertyKey key = config.getPropertyKeyForJSONName(type(mappedType), // subPagePatternMappedAttribute); // if (key != null) { // // obj.setProperty(key, subSubEx); // } // // } // // } else { // // if (subEx != null && subEx != = '' && subPagePattern.mappedAttribute != null) { // obj[subPagePattern.mappedAttribute] = subEx; // } } } }
@Override public Object setProperty( final SecurityContext securityContext, final GraphObject obj, final T value) throws FrameworkException { final PropertyConverter converter = databaseConverter(securityContext, obj); final Object convertedValue; if (converter != null) { convertedValue = converter.convert(value); } else { convertedValue = value; } final PropertyContainer propertyContainer = obj.getPropertyContainer(); if (propertyContainer != null) { if (!TransactionCommand.inTransaction()) { throw new NotInTransactionException("setProperty outside of transaction"); } boolean internalSystemPropertiesUnlocked = (obj instanceof CreationContainer); // notify only non-system properties // collect modified properties if (obj instanceof AbstractNode) { if (!unvalidated) { TransactionCommand.nodeModified( securityContext.getCachedUser(), (AbstractNode) obj, AbstractPrimitiveProperty.this, propertyContainer.hasProperty(dbName()) ? propertyContainer.getProperty(dbName()) : null, value); } internalSystemPropertiesUnlocked = ((AbstractNode) obj).internalSystemPropertiesUnlocked; } else if (obj instanceof AbstractRelationship) { if (!unvalidated) { TransactionCommand.relationshipModified( securityContext.getCachedUser(), (AbstractRelationship) obj, AbstractPrimitiveProperty.this, propertyContainer.hasProperty(dbName()) ? propertyContainer.getProperty(dbName()) : null, value); } internalSystemPropertiesUnlocked = ((AbstractRelationship) obj).internalSystemPropertiesUnlocked; } // catch all sorts of errors and wrap them in a FrameworkException try { // save space if (convertedValue == null) { propertyContainer.removeProperty(dbName()); } else { if (!isSystemInternal() || internalSystemPropertiesUnlocked) { propertyContainer.setProperty(dbName(), convertedValue); } else { logger.warn( "Tried to set internal system property {} to {}. Action was denied.", new Object[] {dbName(), convertedValue}); } } updateAccessInformation(securityContext, propertyContainer); } catch (Throwable t) { // throw FrameworkException with the given cause final FrameworkException fex = new FrameworkException( 500, "Unable to set property " + jsonName() + " on entity with ID " + obj.getUuid() + ": " + t.toString()); fex.initCause(t); throw fex; } if (isIndexed()) { // do indexing, needs to be done after // setProperty to make spatial index // work if (!isPassivelyIndexed()) { index(obj, convertedValue); } } } return null; }
@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); } }