@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;
  }
예제 #2
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;
        //					}
      }
    }
  }
  @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);
    }
  }