Beispiel #1
0
  @Override
  public T instantiateDummy(final Relationship entity, final String entityType)
      throws FrameworkException {

    Map<String, Class<? extends RelationshipInterface>> entities =
        StructrApp.getConfiguration().getRelationshipEntities();
    Class<T> relClass = (Class<T>) entities.get(entityType);
    T newRel = null;

    if (relClass != null) {

      try {

        newRel = relClass.newInstance();
        newRel.init(factoryProfile.getSecurityContext(), entity);

        // let rel. know of its instantiation so it can cache its start- and end node ID.
        newRel.onRelationshipInstantiation();

      } catch (Throwable t) {

        newRel = null;
      }
    }

    return newRel;
  }
Beispiel #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);
    }
  }
  @Override
  public void indexPassiveProperties() {

    for (PropertyKey key :
        StructrApp.getConfiguration().getPropertySet(entityType, PropertyView.All)) {

      if (key.isPassivelyIndexed()) {

        key.index(this, this.getPropertyForIndexing(key));
      }
    }
  }
  /**
   * 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;
  }
  public Transformation(
      final Class type,
      final String sourceName,
      final String targetName,
      final String inputFunction,
      final String outputFunction) {

    this.sourceName = sourceName;
    this.targetName = targetName;
    this.inputFunction = inputFunction;
    this.outputFunction = outputFunction;

    this.sourceProperty = StructrApp.getConfiguration().getPropertyKeyForJSONName(type, sourceName);
    this.targetProperty = new GenericProperty(targetName);
  }
Beispiel #6
0
  private Class type(final String typeString) throws FrameworkException {

    Class type = null;

    final ConfigurationProvider config = StructrApp.getConfiguration();
    if (typeString != null) {

      type = config.getNodeEntityClass(typeString);
    }

    if (type == null) {

      throw new FrameworkException(422, "Unknown type '" + typeString + "'");
    }

    return type;
  }
Beispiel #7
0
  @Override
  public T instantiateWithType(
      final Relationship relationship, final Class<T> relClass, final boolean isCreation)
      throws FrameworkException {

    logger.log(Level.FINEST, "Instantiate relationship with type {0}", relClass.getName());

    SecurityContext securityContext = factoryProfile.getSecurityContext();
    T newRel = null;

    try {

      newRel = relClass.newInstance();

    } catch (Throwable t) {
      newRel = null;
    }

    if (newRel == null) {
      newRel = (T) StructrApp.getConfiguration().getFactoryDefinition().createGenericRelationship();
    }

    newRel.init(securityContext, relationship);

    // try to set correct type property on relationship entity
    final String type = newRel.getProperty(GraphObject.type);
    if (type == null || (type != null && !type.equals(relClass.getSimpleName()))) {

      newRel.unlockReadOnlyPropertiesOnce();
      newRel.setProperty(GraphObject.type, relClass.getSimpleName());
    }

    newRel.onRelationshipInstantiation();

    return newRel;
  }
  // ----- interface GraphObject -----
  @Override
  public Iterable<PropertyKey> getPropertyKeys(final String propertyView) {

    return StructrApp.getConfiguration().getPropertySet(this.getClass(), propertyView);
  }
Beispiel #9
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 List<GraphObject> getData(
      final SecurityContext securityContext,
      final RenderContext renderContext,
      final String restQuery)
      throws FrameworkException {

    Map<Pattern, Class<? extends Resource>> resourceMap = new LinkedHashMap<>();

    ResourceProvider resourceProvider =
        renderContext == null ? null : renderContext.getResourceProvider();
    if (resourceProvider == null) {
      try {
        resourceProvider = UiResourceProvider.class.newInstance();
      } catch (Throwable t) {
        logger.log(Level.SEVERE, "Couldn't establish a resource provider", t);
        return Collections.EMPTY_LIST;
      }
    }

    // inject resources
    resourceMap.putAll(resourceProvider.getResources());

    Value<String> propertyView = new ThreadLocalPropertyView();
    propertyView.set(securityContext, PropertyView.Ui);

    // initialize variables
    // mimic HTTP request
    HttpServletRequest request =
        new HttpServletRequestWrapper(
            renderContext == null ? securityContext.getRequest() : renderContext.getRequest()) {

          @Override
          public Enumeration<String> getParameterNames() {
            return new IteratorEnumeration(getParameterMap().keySet().iterator());
          }

          @Override
          public String getParameter(String key) {
            String[] p = getParameterMap().get(key);
            return p != null ? p[0] : null;
          }

          @Override
          public Map<String, String[]> getParameterMap() {
            String[] parts = StringUtils.split(getQueryString(), "&");
            Map<String, String[]> parameterMap = new HashMap();
            for (String p : parts) {
              String[] kv = StringUtils.split(p, "=");
              if (kv.length > 1) {
                parameterMap.put(kv[0], new String[] {kv[1]});
              }
            }
            return parameterMap;
          }

          @Override
          public String getQueryString() {
            return StringUtils.substringAfter(restQuery, "?");
          }

          @Override
          public String getPathInfo() {
            return StringUtils.substringBefore(restQuery, "?");
          }

          @Override
          public StringBuffer getRequestURL() {
            return new StringBuffer(restQuery);
          }
        };

    // update request in security context
    securityContext.setRequest(request);

    // HttpServletResponse response = renderContext.getResponse();
    Resource resource =
        ResourceHelper.applyViewTransformation(
            request,
            securityContext,
            ResourceHelper.optimizeNestedResourceChain(
                ResourceHelper.parsePath(
                    securityContext, request, resourceMap, propertyView, GraphObject.id),
                GraphObject.id),
            propertyView);

    // TODO: decide if we need to rest the REST request here
    // securityContext.checkResourceAccess(request, resource.getResourceSignature(),
    // resource.getGrant(request, response), PropertyView.Ui);
    // add sorting & paging
    String pageSizeParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_SIZE);
    String pageParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_NUMBER);
    String offsetId = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_OFFSET_ID);
    String sortOrder = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_ORDER);
    String sortKeyName = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_KEY);
    boolean sortDescending = (sortOrder != null && "desc".equals(sortOrder.toLowerCase()));
    int pageSize = parseInt(pageSizeParameter, NodeFactory.DEFAULT_PAGE_SIZE);
    int page = parseInt(pageParameter, NodeFactory.DEFAULT_PAGE);
    PropertyKey sortKey = null;

    // set sort key
    if (sortKeyName != null) {

      Class<? extends GraphObject> type = resource.getEntityClass();
      if (type == null) {

        // fallback to default implementation
        // if no type can be determined
        type = AbstractNode.class;
      }
      sortKey = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(type, sortKeyName);
    }

    // do action
    Result result = resource.doGet(sortKey, sortDescending, pageSize, page, offsetId);
    result.setIsCollection(resource.isCollectionResource());
    result.setIsPrimitiveArray(resource.isPrimitiveArray());

    // Integer rawResultCount = (Integer) Services.getAttribute(NodeFactory.RAW_RESULT_COUNT +
    // Thread.currentThread().getId());
    PagingHelper.addPagingParameter(result, pageSize, page);

    List<GraphObject> res = result.getResults();

    if (renderContext != null) {
      renderContext.setResult(result);
    }

    return res != null ? res : Collections.EMPTY_LIST;
  }
  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;
  }
  // ~--- 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) {

    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);
    }
  }