@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);
  }
Example #2
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);
    }
  }
  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;
  }
Example #14
0
  @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);
    }
  }
Example #17
0
  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;
        //					}
      }
    }
  }