@Override public <T> void setProperty(final PropertyKey<T> key, final T value) throws FrameworkException { // check for read-only properties // if (StructrApp.getConfiguration().isReadOnlyProperty(type, key) || // (StructrApp.getConfiguration().isWriteOnceProperty(type, key) && (dbRelationship != null) && // dbRelationship.hasProperty(key.name()))) { if (key.isReadOnly() || (key.isWriteOnce() && (dbRelationship != null) && dbRelationship.hasProperty(key.dbName()))) { if (readOnlyPropertiesUnlocked || securityContext.isSuperUser()) { // permit write operation once and // lock read-only properties again readOnlyPropertiesUnlocked = false; } else { throw new FrameworkException(getClass().getSimpleName(), new ReadOnlyPropertyToken(key)); } } key.setProperty(securityContext, this, value); }
@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); } }
public Object execute(Object... parameters) throws FrameworkException { final NodeFactory nodeFactory = new NodeFactory(securityContext); switch (parameters.length) { case 1: { final Index<Node> index = getIndexFromArguments(NodeIndex.user, arguments); // we have only a simple user name if (parameters[0] instanceof String) { final String userName = (String) parameters[0]; for (final Node n : index.get(AbstractNode.name.dbName(), userName)) { final NodeInterface s = nodeFactory.instantiate(n); if (s.getType().equals(Principal.class.getSimpleName())) { return s; } } } } break; case 3: { final String userNickName = (String) parameters[0]; final PropertyKey key = (PropertyKey) parameters[1]; final NodeIndex idx = (NodeIndex) parameters[2]; final Index<Node> index = getIndexFromArguments(idx, arguments); IndexHits<Node> indexHits = null; synchronized (index) { // see: http://docs.neo4j.org/chunked/milestone/indexing-create-advanced.html indexHits = index.query(key.dbName(), "\"" + userNickName + "\""); } try { for (final Node n : indexHits) { final Object u = nodeFactory.instantiate(n); if (u != null) { return u; } } } finally { indexHits.close(); } } break; default: break; } return null; }
public void updateChangeLog( final Principal user, final Verb verb, final PropertyKey key, final Object previousValue, final Object newValue) { if (changeLogEnabled && changeLog != null && key != null) { final String name = key.jsonName(); if (!hiddenPropertiesInAuditLog.contains(name) && !(key.isUnvalidated() || key.isReadOnly())) { final JsonObject obj = new JsonObject(); obj.add("time", toElement(System.currentTimeMillis())); obj.add("userId", toElement(user.getUuid())); obj.add("userName", toElement(user.getName())); obj.add("verb", toElement(verb)); obj.add("key", toElement(key.jsonName())); obj.add("prev", toElement(previousValue)); obj.add("val", toElement(newValue)); changeLog.append(obj.toString()); changeLog.append("\n"); } } }
@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; }
protected boolean hasPropertyValue(Node node, PropertyKey propertyKey, Object propertyValue) { if (node != null && node.hasProperty(propertyKey.dbName())) { Object value = node.getProperty(propertyKey.dbName()); return value.equals(propertyValue); } return false; }
// ----- protected methods ----- protected boolean hasPropertyValue( Relationship rel, PropertyKey propertyKey, Object propertyValue) { if (rel != null && rel.hasProperty(propertyKey.dbName())) { Object value = rel.getProperty(propertyKey.dbName()); return value.equals(propertyValue); } return false; }
@Override public void indexPassiveProperties() { for (PropertyKey key : StructrApp.getConfiguration().getPropertySet(entityType, PropertyView.All)) { if (key.isPassivelyIndexed()) { key.index(this, this.getPropertyForIndexing(key)); } } }
private <T> T getProperty( final PropertyKey<T> key, boolean applyConverter, final org.neo4j.helpers.Predicate<GraphObject> predicate) { // early null check, this should not happen... if (key == null || key.dbName() == null) { return null; } return key.getProperty(securityContext, this, applyConverter, predicate); }
@Override public void removeProperty(final PropertyKey key) throws FrameworkException { dbRelationship.removeProperty(key.dbName()); // remove from index removeFromIndex(key); }
/** * Call validators. This must be synchronized globally * * @param securityContext * @param errorBuffer * @return valid */ private boolean validate(SecurityContext securityContext, ErrorBuffer errorBuffer) { boolean valid = true; for (PropertyKey key : removedProperties.keySet()) { List<PropertyValidator> validators = key.getValidators(); for (PropertyValidator validator : validators) { Object value = object.getProperty(key); valid &= validator.isValid(securityContext, object, key, value, errorBuffer); } } // explicitly call isValid() return valid && object.isValid(errorBuffer); }
public void removeFromIndex(PropertyKey key) { for (Index<Relationship> index : Services.getInstance().getService(NodeService.class).getRelationshipIndices()) { synchronized (index) { index.remove(dbRelationship, key.dbName()); } } }
@Override public JsonElement getContent() { JsonObject obj = new JsonObject(); JsonObject vals = new JsonObject(); for (Entry<PropertyKey, Object> entry : attributes.entrySet()) { PropertyKey key = entry.getKey(); Object value = entry.getValue(); if (value == null) { vals.add(key.jsonName(), new JsonNull()); } else { vals.add(key.jsonName(), new JsonPrimitive(value.toString())); } } obj.add(getErrorToken(), vals); return obj; }
@Override public java.lang.Object getPropertyForIndexing(final PropertyKey key) { if (key.equals(Content.content)) { String value = getProperty(Content.content); if (value != null) { return Search.escapeForLucene(value); } } return super.getPropertyForIndexing(key); }
private synchronized < A extends NodeInterface, B extends NodeInterface, R extends Relation<A, B, ?, ?>> R createRelationship( final A fromNode, final B toNode, final Class<R> relType, final PropertyMap properties) throws FrameworkException { final RelationshipFactory<R> factory = new RelationshipFactory(securityContext); final R template = instantiate(relType); final Node startNode = fromNode.getNode(); final Node endNode = toNode.getNode(); final Relationship rel = startNode.createRelationshipTo(endNode, template); final R newRel = factory.instantiate(rel); final Date now = new Date(); // logger.log(Level.INFO, "CREATING relationship {0}-[{1}]->{2}", new Object[] { // fromNode.getType(), newRel.getRelType(), toNode.getType() } ); if (newRel != null) { newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(GraphObject.type, relType.getSimpleName()); // set UUID newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(GraphObject.id, getNextUuid()); // set created date newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(AbstractRelationship.createdDate, now); // set last modified date newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty(AbstractRelationship.lastModifiedDate, now); // Try to get the cascading delete flag from the domain specific relationship type newRel.unlockReadOnlyPropertiesOnce(); newRel.setProperty( AbstractRelationship.cascadeDelete, factory.instantiate(rel).getCascadingDeleteFlag()); // notify transaction handler TransactionCommand.relationshipCreated(newRel); if (properties != null) { for (Entry<PropertyKey, Object> entry : properties.entrySet()) { PropertyKey key = entry.getKey(); // on creation, writing of read-only properties should be possible if (key.isReadOnly() || key.isWriteOnce()) { newRel.unlockReadOnlyPropertiesOnce(); } newRel.setProperty(entry.getKey(), entry.getValue()); } } // notify relationship of its creation newRel.onRelationshipCreation(); // iterate post creation transformations for (Transformation<GraphObject> transformation : StructrApp.getConfiguration().getEntityCreationTransformations(newRel.getClass())) { transformation.apply(securityContext, newRel); } } return newRel; }
@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); } }
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; // } } } }