protected int processEntityContext()

in ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java [140:301]


  protected int processEntityContext(
      final EntityInvocationHandler handler,
      int pos,
      final TransactionItems items,
      final List<EntityLinkDesc> delayedUpdates,
      final PersistenceChanges changeset) {
    int posNumber = pos;
    items.put(handler, null);

    final ClientEntity entity = handler.getEntity();
    entity.getNavigationLinks().clear();

    final AttachedEntityStatus currentStatus = service.getContext().entityContext().getStatus(handler);
    LOG.debug("Process '{}({})'", handler, currentStatus);

    if (AttachedEntityStatus.DELETED != currentStatus) {
      entity.getProperties().clear();
      CoreUtils.addProperties(service.getClient(), handler.getPropertyChanges(), entity);

      entity.getAnnotations().clear();
      CoreUtils.addAnnotations(service.getClient(), handler.getAnnotations(), entity);

      for (Map.Entry<String, AnnotatableInvocationHandler> entry : handler.getPropAnnotatableHandlers().entrySet()) {
        CoreUtils.addAnnotations(service.getClient(),
            entry.getValue().getAnnotations(), entity.getProperty(entry.getKey()));
      }
    }

    for (Map.Entry<NavigationProperty, Object> property : handler.getLinkChanges().entrySet()) {
      final ClientLinkType type = Collection.class.isAssignableFrom(property.getValue().getClass())
          ? ClientLinkType.ENTITY_SET_NAVIGATION
          : ClientLinkType.ENTITY_NAVIGATION;

      final Set<EntityInvocationHandler> toBeLinked = new HashSet<EntityInvocationHandler>();

      for (Object proxy : type == ClientLinkType.ENTITY_SET_NAVIGATION
          ? (Collection<?>) property.getValue() : Collections.singleton(property.getValue())) {

        final EntityInvocationHandler target = (EntityInvocationHandler) Proxy.getInvocationHandler(proxy);

        final AttachedEntityStatus status;
        if (!service.getContext().entityContext().isAttached(target)) {
          status = resolveNavigationLink(property.getKey(), target);
        } else {
          status = service.getContext().entityContext().getStatus(target);
        }

        LOG.debug("Found link to '{}({})'", target, status);

        final URI editLink = target.getEntity().getEditLink();

        if ((status == AttachedEntityStatus.ATTACHED || status == AttachedEntityStatus.LINKED) && !target.isChanged()) {
          LOG.debug("Add link to '{}'", target);
          entity.addLink(buildNavigationLink(
              property.getKey().name(),
              URIUtils.getURI(service.getClient().getServiceRoot(), editLink.toASCIIString()), type));
        } else {
          if (!items.contains(target)) {
            posNumber = processEntityContext(target, posNumber, items, delayedUpdates, changeset);
            posNumber++;
          }

          final Integer targetPos = items.get(target);
          if (targetPos == null) {
            // schedule update for the current object
            LOG.debug("Schedule '{}' from '{}' to '{}'", type.name(), handler, target);
            toBeLinked.add(target);
          } else if (status == AttachedEntityStatus.CHANGED) {
            LOG.debug("Changed: '{}' from '{}' to (${}) '{}'", type.name(), handler, targetPos, target);
            entity.addLink(buildNavigationLink(
                property.getKey().name(),
                URIUtils.getURI(service.getClient().getServiceRoot(), editLink.toASCIIString()), type));
          } else {
            // create the link for the current object
            LOG.debug("'{}' from '{}' to (${}) '{}'", type.name(), handler, targetPos, target);

            entity.addLink(buildNavigationLink(property.getKey().name(), URI.create("$" + targetPos), type));
          }
        }
      }

      if (!toBeLinked.isEmpty()) {
        delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, toBeLinked, type));
      }

      if (property.getValue() instanceof Proxy) {
        final InvocationHandler target = Proxy.getInvocationHandler(property.getValue());

        if (target instanceof EntityCollectionInvocationHandler) {
          for (String ref : ((EntityCollectionInvocationHandler<?>) target).referenceItems) {
            delayedUpdates.add(new EntityLinkDesc(property.getKey().name(), handler, ref));
          }
        }
      }
    }

    for (Map.Entry<String, AnnotatableInvocationHandler> entry : handler.getNavPropAnnotatableHandlers().entrySet()) {

      CoreUtils.addAnnotations(service.getClient(),
          entry.getValue().getAnnotations(),
          entity.getNavigationLink(entry.getKey()));
    }

    final AttachedEntityStatus processedStatus = queue(handler, entity, changeset);
    if (processedStatus != null) {
      // insert into the process queue
      LOG.debug("{}: Insert '{}' into the process queue", posNumber, handler);
      items.put(handler, posNumber);
    } else {
      posNumber--;
    }

    if (processedStatus != AttachedEntityStatus.DELETED) {
      int startingPos = posNumber;

      if (handler.getEntity().isMediaEntity() && handler.isChanged()) {
        // update media properties
        if (!handler.getPropertyChanges().isEmpty()) {
          final URI targetURI = currentStatus == AttachedEntityStatus.NEW
              ? URI.create("$" + startingPos)
              : URIUtils.getURI(
                  service.getClient().getServiceRoot(), handler.getEntity().getEditLink().toASCIIString());
          queueUpdate(handler, targetURI, entity, changeset);
          posNumber++;
          items.put(handler, posNumber);
          LOG.debug("{}: Update media properties for '{}' into the process queue", posNumber, handler);
        }

        // update media content
        if (handler.getStreamChanges() != null) {
          final URI targetURI = currentStatus == AttachedEntityStatus.NEW
              ? URI.create("$" + startingPos + "/$value")
              : URIUtils.getURI(
                  service.getClient().getServiceRoot(),
                  handler.getEntity().getEditLink().toASCIIString() + "/$value");

          queueUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);

          // update media info (use null key)
          posNumber++;
          items.put(null, posNumber);
          LOG.debug("{}: Update media info for '{}' into the process queue", posNumber, handler);
        }
      }

      for (Map.Entry<String, EdmStreamValue> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
        final URI targetURI = currentStatus == AttachedEntityStatus.NEW
            ? URI.create("$" + startingPos) : URIUtils.getURI(
                service.getClient().getServiceRoot(),
                CoreUtils.getMediaEditLink(streamedChanges.getKey(), entity).toASCIIString());

        queueUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);

        // update media info (use null key)
        posNumber++;
        items.put(handler, posNumber);
        LOG.debug("{}: Update media info (null key) for '{}' into the process queue", posNumber, handler);
      }
    }

    return posNumber;
  }