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