You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/05/22 13:22:31 UTC
[7/9] Merge from masterĂ¹
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PersistenceManagerImpl.java
----------------------------------------------------------------------
diff --cc ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PersistenceManagerImpl.java
index 9c39c95,0000000..e7ffc57
mode 100644,000000..100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PersistenceManagerImpl.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PersistenceManagerImpl.java
@@@ -1,551 -1,0 +1,568 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.ext.proxy.commons;
+
+import java.io.InputStream;
+import java.lang.reflect.Proxy;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
- import org.apache.olingo.client.api.communication.request.batch.BatchStreamManager;
++import org.apache.olingo.client.api.communication.request.batch.BatchManager;
+import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
+import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
+import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
+import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem;
+import org.apache.olingo.client.core.uri.URIUtils;
+import org.apache.olingo.commons.api.domain.CommonODataEntity;
+import org.apache.olingo.commons.api.domain.ODataLink;
+import org.apache.olingo.commons.api.domain.ODataLinkType;
++import org.apache.olingo.commons.api.domain.v4.ODataEntity;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.format.ODataMediaFormat;
+import org.apache.olingo.ext.proxy.EntityContainerFactory;
+import org.apache.olingo.ext.proxy.api.PersistenceManager;
+import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
+import org.apache.olingo.ext.proxy.context.AttachedEntity;
+import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
+import org.apache.olingo.ext.proxy.context.EntityLinkDesc;
+import org.apache.olingo.ext.proxy.utils.CoreUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class PersistenceManagerImpl implements PersistenceManager {
+
+ private static final long serialVersionUID = -3320312269235907501L;
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(PersistenceManagerImpl.class);
+
+ private final EntityContainerFactory<?> factory;
+
+ PersistenceManagerImpl(final EntityContainerFactory<?> factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * Transactional changes commit.
+ */
+ @Override
+ public void flush() {
+ final CommonODataBatchRequest request =
+ factory.getClient().getBatchRequestFactory().getBatchRequest(factory.getClient().getServiceRoot());
+ ((ODataRequest) request).setAccept(factory.getClient().getConfiguration().getDefaultBatchAcceptFormat());
+
- final BatchStreamManager streamManager = (BatchStreamManager) ((ODataStreamedRequest) request).execute();
++ final BatchManager streamManager = (BatchManager) ((ODataStreamedRequest) request).payloadManager();
+
+ final ODataChangeset changeset = streamManager.addChangeset();
+
+ final TransactionItems items = new TransactionItems();
+ final List<EntityLinkDesc> delayedUpdates = new ArrayList<EntityLinkDesc>();
+
+ int pos = 0;
+
+ for (AttachedEntity attachedEntity : factory.getContext().entityContext()) {
+ final AttachedEntityStatus status = attachedEntity.getStatus();
+ if (((status != AttachedEntityStatus.ATTACHED
+ && status != AttachedEntityStatus.LINKED) || attachedEntity.getEntity().isChanged())
+ && !items.contains(attachedEntity.getEntity())) {
+ pos++;
+ pos = processEntityContext(attachedEntity.getEntity(), pos, items, delayedUpdates, changeset);
+ }
+ }
+
+ processDelayedUpdates(delayedUpdates, pos, items, changeset);
+
+ final ODataBatchResponse response = streamManager.getResponse();
+
- if ((factory.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
- && response.getStatusCode() != 202)
- || (factory.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) > 0
- && response.getStatusCode() != 200)) {
-
++ // This should be 202 for service version <= 3.0 and 200 for service version >= 4.0 but it seems that
++ // many service implementations are not fully compliant with this respect.
++ if (response.getStatusCode() != 202 && response.getStatusCode() != 200) {
+ throw new IllegalStateException("Operation failed");
+ }
+
+ if (!items.isEmpty()) {
+ final Iterator<ODataBatchResponseItem> iter = response.getBody();
+ if (!iter.hasNext()) {
+ throw new IllegalStateException("Unexpected operation result");
+ }
+
+ final ODataBatchResponseItem item = iter.next();
+ if (!(item instanceof ODataChangesetResponseItem)) {
+ throw new IllegalStateException("Unexpected batch response item " + item.getClass().getSimpleName());
+ }
+
+ final ODataChangesetResponseItem chgres = (ODataChangesetResponseItem) item;
+
+ for (Integer changesetItemId : items.sortedValues()) {
+ LOG.debug("Expected changeset item {}", changesetItemId);
+ final ODataResponse res = chgres.next();
+ if (res.getStatusCode() >= 400) {
+ throw new IllegalStateException("Transaction failed: " + res.getStatusMessage());
+ }
+
+ final EntityInvocationHandler handler = items.get(changesetItemId);
+
+ if (handler != null) {
+ if (res instanceof ODataEntityCreateResponse && res.getStatusCode() == 201) {
+ handler.setEntity(((ODataEntityCreateResponse) res).getBody());
+ LOG.debug("Upgrade created object '{}'", handler);
+ } else if (res instanceof ODataEntityUpdateResponse && res.getStatusCode() == 200) {
+ handler.setEntity(((ODataEntityUpdateResponse) res).getBody());
+ LOG.debug("Upgrade updated object '{}'", handler);
+ }
+ }
+ }
+ }
+
+ factory.getContext().detachAll();
+ }
+
- private void batch(
++ private AttachedEntityStatus batch(
+ final EntityInvocationHandler handler,
+ final CommonODataEntity entity,
+ final ODataChangeset changeset) {
+
+ switch (factory.getContext().entityContext().getStatus(handler)) {
+ case NEW:
+ batchCreate(handler, entity, changeset);
- break;
++ return AttachedEntityStatus.NEW;
+
+ case CHANGED:
+ batchUpdate(handler, entity, changeset);
- break;
++ return AttachedEntityStatus.CHANGED;
+
+ case DELETED:
+ batchDelete(handler, entity, changeset);
- break;
++ return AttachedEntityStatus.DELETED;
+
+ default:
+ if (handler.isChanged()) {
+ batchUpdate(handler, entity, changeset);
+ }
++ return AttachedEntityStatus.CHANGED;
+ }
+ }
+
+ private void batchCreate(
+ final EntityInvocationHandler handler,
+ final CommonODataEntity entity,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Create '{}'", handler);
+
- changeset.addRequest(
- factory.getClient().getCUDRequestFactory().getEntityCreateRequest(handler.getEntitySetURI(), entity));
++ changeset.addRequest(factory.getClient().getCUDRequestFactory().
++ getEntityCreateRequest(handler.getEntitySetURI(), entity));
+ }
+
+ private void batchUpdateMediaEntity(
+ final EntityInvocationHandler handler,
+ final URI uri,
+ final InputStream input,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Update media entity '{}'", uri);
+
+ final ODataMediaEntityUpdateRequest<?> req =
- factory.getClient().getStreamedRequestFactory().getMediaEntityUpdateRequest(uri, input);
++ factory.getClient().getCUDRequestFactory().getMediaEntityUpdateRequest(uri, input);
+
+ req.setContentType(StringUtils.isBlank(handler.getEntity().getMediaContentType())
+ ? ODataMediaFormat.WILDCARD.toString()
+ : ODataMediaFormat.fromFormat(handler.getEntity().getMediaContentType()).toString());
+
+ if (StringUtils.isNotBlank(handler.getETag())) {
+ req.setIfMatch(handler.getETag());
+ }
+
+ changeset.addRequest(req);
+ }
+
+ private void batchUpdateMediaResource(
+ final EntityInvocationHandler handler,
+ final URI uri,
+ final InputStream input,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Update media entity '{}'", uri);
+
- final ODataStreamUpdateRequest req = factory.getClient().
- getStreamedRequestFactory().getStreamUpdateRequest(uri, input);
++ final ODataStreamUpdateRequest req = factory.getClient().getCUDRequestFactory().getStreamUpdateRequest(uri, input);
+
+ if (StringUtils.isNotBlank(handler.getETag())) {
+ req.setIfMatch(handler.getETag());
+ }
+
+ changeset.addRequest(req);
+ }
+
+ private void batchUpdate(
+ final EntityInvocationHandler handler,
+ final CommonODataEntity changes,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Update '{}'", handler.getEntityURI());
+
+ final ODataEntityUpdateRequest<CommonODataEntity> req =
+ factory.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
+ ? ((org.apache.olingo.client.api.v3.EdmEnabledODataClient) factory.getClient()).getCUDRequestFactory().
+ getEntityUpdateRequest(handler.getEntityURI(),
+ org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
+ : ((org.apache.olingo.client.api.v4.EdmEnabledODataClient) factory.getClient()).getCUDRequestFactory().
+ getEntityUpdateRequest(handler.getEntityURI(),
+ org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
+
+ req.setPrefer(new ODataPreferences(factory.getClient().getServiceVersion()).returnContent());
+
+ if (StringUtils.isNotBlank(handler.getETag())) {
+ req.setIfMatch(handler.getETag());
+ }
+
+ changeset.addRequest(req);
+ }
+
+ private void batchUpdate(
+ final EntityInvocationHandler handler,
+ final URI uri,
+ final CommonODataEntity changes,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Update '{}'", uri);
+
+ final ODataEntityUpdateRequest<CommonODataEntity> req =
+ factory.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) <= 0
+ ? ((org.apache.olingo.client.api.v3.EdmEnabledODataClient) factory.getClient()).getCUDRequestFactory().
+ getEntityUpdateRequest(uri,
+ org.apache.olingo.client.api.communication.request.cud.v3.UpdateType.PATCH, changes)
+ : ((org.apache.olingo.client.api.v4.EdmEnabledODataClient) factory.getClient()).getCUDRequestFactory().
+ getEntityUpdateRequest(uri,
+ org.apache.olingo.client.api.communication.request.cud.v4.UpdateType.PATCH, changes);
+
+ req.setPrefer(new ODataPreferences(factory.getClient().getServiceVersion()).returnContent());
+
+ if (StringUtils.isNotBlank(handler.getETag())) {
+ req.setIfMatch(handler.getETag());
+ }
+
+ changeset.addRequest(req);
+ }
+
+ private void batchDelete(
+ final EntityInvocationHandler handler,
+ final CommonODataEntity entity,
+ final ODataChangeset changeset) {
+
+ final URI deleteURI = handler.getEntityURI() == null ? entity.getEditLink() : handler.getEntityURI();
+ LOG.debug("Delete '{}'", deleteURI);
+
+ final ODataDeleteRequest req = factory.getClient().getCUDRequestFactory().getDeleteRequest(deleteURI);
+
+ if (StringUtils.isNotBlank(handler.getETag())) {
+ req.setIfMatch(handler.getETag());
+ }
+
+ changeset.addRequest(req);
+ }
+
+ private int processEntityContext(
+ final EntityInvocationHandler handler,
+ int pos,
+ final TransactionItems items,
+ final List<EntityLinkDesc> delayedUpdates,
+ final ODataChangeset changeset) {
+
+ LOG.debug("Process '{}'", handler);
+
+ items.put(handler, null);
+
+ final CommonODataEntity entity = handler.getEntity();
+ entity.getNavigationLinks().clear();
+
+ final AttachedEntityStatus currentStatus = factory.getContext().entityContext().getStatus(handler);
+
+ if (AttachedEntityStatus.DELETED != currentStatus) {
+ entity.getProperties().clear();
+ CoreUtils.addProperties(factory.getClient(), handler.getPropertyChanges(), entity);
++
++ if (entity instanceof ODataEntity) {
++ ((ODataEntity) entity).getAnnotations().clear();
++ CoreUtils.addAnnotations(factory.getClient(), handler.getAnnotations(), (ODataEntity) entity);
++
++ for (Map.Entry<String, AnnotatableInvocationHandler> entry : handler.getPropAnnotatableHandlers().entrySet()) {
++ CoreUtils.addAnnotations(factory.getClient(),
++ entry.getValue().getAnnotations(), ((ODataEntity) entity).getProperty(entry.getKey()));
++ }
++ }
+ }
+
+ for (Map.Entry<NavigationProperty, Object> property : handler.getLinkChanges().entrySet()) {
+ final ODataLinkType type = Collection.class.isAssignableFrom(property.getValue().getClass())
+ ? ODataLinkType.ENTITY_SET_NAVIGATION
+ : ODataLinkType.ENTITY_NAVIGATION;
+
+ final Set<EntityInvocationHandler> toBeLinked = new HashSet<EntityInvocationHandler>();
- final String serviceRoot = factory.getClient().getServiceRoot();
-
+ for (Object proxy : type == ODataLinkType.ENTITY_SET_NAVIGATION
+ ? (Collection) property.getValue() : Collections.singleton(property.getValue())) {
+
+ final EntityInvocationHandler target = (EntityInvocationHandler) Proxy.getInvocationHandler(proxy);
+
+ final AttachedEntityStatus status = factory.getContext().entityContext().getStatus(target);
+
+ final URI editLink = target.getEntity().getEditLink();
+
+ if ((status == AttachedEntityStatus.ATTACHED || status == AttachedEntityStatus.LINKED) && !target.isChanged()) {
+ entity.addLink(buildNavigationLink(
+ property.getKey().name(),
- URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
++ URIUtils.getURI(factory.getClient().getServiceRoot(), editLink.toASCIIString()), type));
+ } else {
+ if (!items.contains(target)) {
+ pos = processEntityContext(target, pos, items, delayedUpdates, changeset);
+ pos++;
+ }
+
+ 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) {
+ entity.addLink(buildNavigationLink(
+ property.getKey().name(),
- URIUtils.getURI(serviceRoot, editLink.toASCIIString()), type));
++ URIUtils.getURI(factory.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 (entity instanceof ODataEntity) {
++ for (Map.Entry<String, AnnotatableInvocationHandler> entry
++ : handler.getNavPropAnnotatableHandlers().entrySet()) {
++
++ CoreUtils.addAnnotations(factory.getClient(),
++ entry.getValue().getAnnotations(),
++ (org.apache.olingo.commons.api.domain.v4.ODataLink) entity.getNavigationLink(entry.getKey()));
++ }
++ }
++
+ // insert into the batch
+ LOG.debug("{}: Insert '{}' into the batch", pos, handler);
- batch(handler, entity, changeset);
++ final AttachedEntityStatus processedStatus = batch(handler, entity, changeset);
+
+ items.put(handler, pos);
+
- int startingPos = pos;
++ if (processedStatus != AttachedEntityStatus.DELETED) {
++ int startingPos = pos;
++
++ if (handler.getEntity().isMediaEntity() && handler.isChanged()) {
++ // update media properties
++ if (!handler.getPropertyChanges().isEmpty()) {
++ final URI targetURI = currentStatus == AttachedEntityStatus.NEW
++ ? URI.create("$" + startingPos)
++ : URIUtils.getURI(
++ factory.getClient().getServiceRoot(), handler.getEntity().getEditLink().toASCIIString());
++ batchUpdate(handler, targetURI, entity, changeset);
++ pos++;
++ items.put(handler, pos);
++ }
++
++ // update media content
++ if (handler.getStreamChanges() != null) {
++ final URI targetURI = currentStatus == AttachedEntityStatus.NEW
++ ? URI.create("$" + startingPos + "/$value")
++ : URIUtils.getURI(
++ factory.getClient().getServiceRoot(),
++ handler.getEntity().getEditLink().toASCIIString() + "/$value");
+
- if (handler.getEntity().isMediaEntity()) {
++ batchUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);
+
- // update media properties
- if (!handler.getPropertyChanges().isEmpty()) {
- final URI targetURI = currentStatus == AttachedEntityStatus.NEW
- ? URI.create("$" + startingPos)
- : URIUtils.getURI(
- factory.getClient().getServiceRoot(),
- handler.getEntity().getEditLink().toASCIIString());
- batchUpdate(handler, targetURI, entity, changeset);
- pos++;
- items.put(handler, pos);
++ // update media info (use null key)
++ pos++;
++ items.put(null, pos);
++ }
+ }
+
- // update media content
- if (handler.getStreamChanges() != null) {
++ for (Map.Entry<String, InputStream> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
+ final URI targetURI = currentStatus == AttachedEntityStatus.NEW
- ? URI.create("$" + startingPos + "/$value")
- : URIUtils.getURI(
++ ? URI.create("$" + startingPos) : URIUtils.getURI(
+ factory.getClient().getServiceRoot(),
- handler.getEntity().getEditLink().toASCIIString() + "/$value");
++ CoreUtils.getMediaEditLink(streamedChanges.getKey(), entity).toASCIIString());
+
- batchUpdateMediaEntity(handler, targetURI, handler.getStreamChanges(), changeset);
++ batchUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);
+
+ // update media info (use null key)
+ pos++;
- items.put(null, pos);
++ items.put(handler, pos);
+ }
+ }
+
- for (Map.Entry<String, InputStream> streamedChanges : handler.getStreamedPropertyChanges().entrySet()) {
- final URI targetURI = currentStatus == AttachedEntityStatus.NEW
- ? URI.create("$" + startingPos) : URIUtils.getURI(
- factory.getClient().getServiceRoot(),
- CoreUtils.getMediaEditLink(streamedChanges.getKey(), entity).toASCIIString());
-
- batchUpdateMediaResource(handler, targetURI, streamedChanges.getValue(), changeset);
-
- // update media info (use null key)
- pos++;
- items.put(handler, pos);
- }
-
+ return pos;
+ }
+
+ private ODataLink buildNavigationLink(final String name, final URI uri, final ODataLinkType type) {
+ ODataLink result;
+
+ switch (type) {
+ case ENTITY_NAVIGATION:
+ result = factory.getClient().getObjectFactory().newEntityNavigationLink(name, uri);
+ break;
+
+ case ENTITY_SET_NAVIGATION:
+ result = factory.getClient().getObjectFactory().newEntitySetNavigationLink(name, uri);
+ break;
+
+ default:
+ throw new IllegalArgumentException("Invalid link type " + type.name());
+ }
+
+ return result;
+ }
+
+ private void processDelayedUpdates(
+ final List<EntityLinkDesc> delayedUpdates,
+ int pos,
+ final TransactionItems items,
+ final ODataChangeset changeset) {
+
+ for (EntityLinkDesc delayedUpdate : delayedUpdates) {
+ pos++;
+ items.put(delayedUpdate.getSource(), pos);
+
+ final CommonODataEntity changes =
+ factory.getClient().getObjectFactory().newEntity(delayedUpdate.getSource().getEntity().getTypeName());
+
+ AttachedEntityStatus status = factory.getContext().entityContext().getStatus(delayedUpdate.getSource());
+
+ final URI sourceURI;
+ if (status == AttachedEntityStatus.CHANGED) {
+ sourceURI = URIUtils.getURI(
+ factory.getClient().getServiceRoot(),
+ delayedUpdate.getSource().getEntity().getEditLink().toASCIIString());
+ } else {
+ int sourcePos = items.get(delayedUpdate.getSource());
+ sourceURI = URI.create("$" + sourcePos);
+ }
+
+ for (EntityInvocationHandler target : delayedUpdate.getTargets()) {
+ status = factory.getContext().entityContext().getStatus(target);
+
+ final URI targetURI;
+ if (status == AttachedEntityStatus.CHANGED) {
+ targetURI = URIUtils.getURI(
+ factory.getClient().getServiceRoot(), target.getEntity().getEditLink().toASCIIString());
+ } else {
+ int targetPos = items.get(target);
+ targetURI = URI.create("$" + targetPos);
+ }
+
+ changes.addLink(delayedUpdate.getType() == ODataLinkType.ENTITY_NAVIGATION
+ ? factory.getClient().getObjectFactory().
+ newEntityNavigationLink(delayedUpdate.getSourceName(), targetURI)
+ : factory.getClient().getObjectFactory().
+ newEntitySetNavigationLink(delayedUpdate.getSourceName(), targetURI));
+
+ LOG.debug("'{}' from {} to {}", delayedUpdate.getType().name(), sourceURI, targetURI);
+ }
+
+ batchUpdate(delayedUpdate.getSource(), sourceURI, changes, changeset);
+ }
+ }
+
+ private class TransactionItems {
+
+ private final List<EntityInvocationHandler> keys = new ArrayList<EntityInvocationHandler>();
+
+ private final List<Integer> values = new ArrayList<Integer>();
+
+ public EntityInvocationHandler get(final Integer value) {
+ if (value != null && values.contains(value)) {
+ return keys.get(values.indexOf(value));
+ } else {
+ return null;
+ }
+ }
+
+ public Integer get(final EntityInvocationHandler key) {
+ if (key != null && keys.contains(key)) {
+ return values.get(keys.indexOf(key));
+ } else {
+ return null;
+ }
+ }
+
+ public void remove(final EntityInvocationHandler key) {
+ if (keys.contains(key)) {
+ values.remove(keys.indexOf(key));
+ keys.remove(key);
+ }
+ }
+
+ public void put(final EntityInvocationHandler key, final Integer value) {
+ // replace just in case of null current value; otherwise add the new entry
+ if (key != null && keys.contains(key) && values.get(keys.indexOf(key)) == null) {
+ remove(key);
+ }
+ keys.add(key);
+ values.add(value);
+ }
+
+ public List<Integer> sortedValues() {
+ final List<Integer> sortedValues = new ArrayList<Integer>(values);
+ Collections.<Integer>sort(sortedValues);
+ return sortedValues;
+ }
+
+ public boolean contains(final EntityInvocationHandler key) {
+ return keys.contains(key);
+ }
+
+ public int size() {
+ return keys.size();
+ }
+
+ public boolean isEmpty() {
+ return keys.isEmpty();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
----------------------------------------------------------------------
diff --cc ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
index 2b42cd1,560b185..ae6937d
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityContext.java
@@@ -101,9 -101,9 +101,7 @@@ public class EntityContext implements I
* @param entity entity to be detached.
*/
public void detach(final EntityInvocationHandler entity) {
-- if (searchableEntities.containsKey(entity.getUUID())) {
-- searchableEntities.remove(entity.getUUID());
-- }
++ searchableEntities.remove(entity.getUUID());
allAttachedEntities.remove(entity);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
----------------------------------------------------------------------
diff --cc ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
index edfc227,edfc227..168696a
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/context/EntityUUID.java
@@@ -92,7 -92,7 +92,9 @@@ public class EntityUUID implements Seri
@Override
public int hashCode() {
-- return HashCodeBuilder.reflectionHashCode(this, "tempKey");
++ return key == null
++ ? HashCodeBuilder.reflectionHashCode(this)
++ : HashCodeBuilder.reflectionHashCode(this, "tempKey");
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --cc ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index 822e8ea,b32e80e..5e44e74
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@@ -43,9 -43,11 +43,10 @@@ import org.apache.olingo.commons.api.do
import org.apache.olingo.commons.api.domain.ODataLink;
import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
import org.apache.olingo.commons.api.domain.ODataValue;
+ import org.apache.olingo.commons.api.domain.v4.ODataAnnotatable;
+ import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
-import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.domain.v4.ODataEnumValue;
import org.apache.olingo.commons.api.domain.v4.ODataObjectFactory;
- import org.apache.olingo.commons.api.domain.v4.ODataProperty;
import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@@ -106,12 -112,12 +111,7 @@@ public final class CoreUtils
}
}
} else if (type.isComplexType()) {
-- Object objHandler;
-- if (obj instanceof Proxy) {
-- objHandler = Proxy.getInvocationHandler(obj);
-- } else {
-- objHandler = obj;
-- }
++ final Object objHandler = Proxy.getInvocationHandler(obj);
if (objHandler instanceof ComplexInvocationHandler) {
value = ((ComplexInvocationHandler) objHandler).getComplex();
@@@ -121,7 -127,7 +121,7 @@@
if (propAnn != null) {
try {
value.asComplex().add(getODataComplexProperty(
-- client, type.getFullQualifiedName(), propAnn.name(), method.invoke(objHandler)));
++ client, type.getFullQualifiedName(), propAnn.name(), method.invoke(obj)));
} catch (Exception ignore) {
// ignore value
LOG.warn("Error attaching complex {} for field '{}.{}'",
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/pom.xml
----------------------------------------------------------------------
diff --cc fit/pom.xml
index 41f990a,41f990a..93f4a45
--- a/fit/pom.xml
+++ b/fit/pom.xml
@@@ -182,6 -182,6 +182,7 @@@
<cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
<cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
++ <!--<cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n-->
<cargo.jvmargs>-noverify -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m</cargo.jvmargs>
</properties>
<files>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/main/java/org/apache/olingo/fit/V3Services.java
----------------------------------------------------------------------
diff --cc fit/src/main/java/org/apache/olingo/fit/V3Services.java
index 410fcad,0a0eb09..a036fd2
--- a/fit/src/main/java/org/apache/olingo/fit/V3Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V3Services.java
@@@ -156,7 -156,7 +156,7 @@@ public class V3Services extends Abstrac
addChangesetItemIntro(chbos, lastContebtID, cboundary);
res = bodyPartRequest(new MimeBodyPart(part.getInputStream()), references);
- if (res.getStatus() >= 400) {
- if (res==null || res.getStatus() >= 400) {
++ if (res == null || res.getStatus() >= 400) {
throw new Exception("Failure processing changeset");
}
@@@ -222,10 -222,10 +222,10 @@@
@QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) String filter,
@QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) String orderby,
@QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) String skiptoken) {
--
++
return super.getEntitySet(uriInfo, accept, "Car", top, skip, format, count, filter, orderby, skiptoken);
-- }
--
++ }
++
@GET
@Path("/Login({entityId})")
public Response getLogin(
@@@ -258,6 -258,6 +258,14 @@@
return super.postNewEntity(uriInfo, accept, contentType, prefer, "Login", entity);
}
++ @DELETE
++ @Path("/Login({entityId})")
++ public Response removeLogin(
++ @PathParam("entityId") String entityId) {
++
++ return super.removeEntity("Login", StringUtils.remove(entityId, "'"));
++ }
++
/**
* Retrieve links sample.
*
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
index 17bb65b,0bf0eb5..f2de82a
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
@@@ -62,8 -63,8 +62,6 @@@ public abstract class AbstractTestITCas
protected static String testLargeModelServiceRootURL;
- protected static String testAuthServiceRootURL;
-
- protected final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
-
protected static EntityContainerFactory<EdmEnabledODataClient> containerFactory;
protected static DefaultContainer container;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
index ccfbd2a,2ae58e8..75e583d
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/EntityCreateTestITCase.java
@@@ -116,7 -116,7 +116,7 @@@ public class EntityCreateTestITCase ext
Customer actual = readCustomer(container, id);
checkSampleCustomerProfile(actual, id, sampleName);
-- assertEquals(Integer.valueOf(16), actual.getInfo().getCustomerInfoId());
++ assertEquals(16, actual.getInfo().getCustomerInfoId(), 0);
container.getCustomer().delete(actual.getCustomerId());
container.flush();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v3/MediaEntityTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v3/MediaEntityTestITCase.java
index 0000000,366b5c3..c20b056
mode 000000,100644..100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/MediaEntityTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/MediaEntityTestITCase.java
@@@ -1,0 -1,108 +1,107 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.olingo.fit.proxy.v3;
+
+ import static org.junit.Assert.assertNull;
+ import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertTrue;
+
+ import java.io.ByteArrayInputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import org.apache.commons.io.IOUtils;
-import org.apache.olingo.ext.proxy.EntityContainerFactory;
+ import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Car;
+ import org.junit.Test;
+
+ /**
+ * This is the unit test class to check media entity retrieve operations.
+ */
+ public class MediaEntityTestITCase extends AbstractTestITCase {
+
+ @Test
+ public void read() throws IOException {
+ final InputStream is = container.getCar().get(12).getStream();
+ assertNotNull(is);
+ IOUtils.closeQuietly(is);
+ }
+
+ @Test
+ public void updateReadStreamedProperty() throws IOException {
+ final String TO_BE_UPDATED = "buffered stream sample (" + System.currentTimeMillis() + ")";
+ final InputStream input = new ByteArrayInputStream(TO_BE_UPDATED.getBytes());
+
+ Car car = container.getCar().get(12);
+ car.setPhoto(input);
+
+ container.flush();
+
+ car = container.getCar().get(12);
+ final InputStream is = car.getPhoto();
+ assertEquals(TO_BE_UPDATED, IOUtils.toString(is));
+ IOUtils.closeQuietly(is);
+ }
+
+ @Test
+ public void update() throws IOException {
+ final Car car = container.getCar().get(14);
+ assertNotNull(car);
+
+ final String TO_BE_UPDATED = "buffered stream sample (" + System.currentTimeMillis() + ")";
+ InputStream input = IOUtils.toInputStream(TO_BE_UPDATED);
+
+ car.setStream(input);
+
+ container.flush();
+
+ input = container.getCar().get(14).getStream();
+ assertEquals(TO_BE_UPDATED, IOUtils.toString(input));
+ IOUtils.closeQuietly(input);
+ }
+
+ @Test
+ public void create() throws IOException {
+ Car car = container.getCar().newCar();
+
+ final String TO_BE_UPDATED = "buffered stream sample (" + System.currentTimeMillis() + ")";
+ InputStream input = IOUtils.toInputStream(TO_BE_UPDATED);
+
+ final String DESC = "DESC - " + System.currentTimeMillis();
+ car.setStream(input);
+ car.setDescription(DESC);
+
+ container.flush();
+
+ int key = car.getVIN();
+ assertTrue(key > 0);
+
- EntityContainerFactory.getContext().detachAll();
++ containerFactory.getContext().detachAll();
+
+ car = container.getCar().get(key);
+ assertEquals(DESC, car.getDescription());
+ input = car.getStream();
+ assertEquals(TO_BE_UPDATED, IOUtils.toString(input));
+ IOUtils.closeQuietly(input);
+
+ container.getCar().delete(key);
+ container.flush();
+
+ assertNull(container.getCar().get(key));
+ }
+ }
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v3/OpenTypeTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v3/OpenTypeTestITCase.java
index 1a0a08c,28b768f..3ee02ba
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/OpenTypeTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/OpenTypeTestITCase.java
@@@ -44,12 -44,12 +44,13 @@@ import org.junit.Test
*/
public class OpenTypeTestITCase extends AbstractTestITCase {
++ private static EntityContainerFactory<EdmEnabledODataClient> otcontainerFactory;
++
private static DefaultContainer otcontainer;
@BeforeClass
public static void initContainer() {
-- final EntityContainerFactory<EdmEnabledODataClient> otcontainerFactory =
-- EntityContainerFactory.getV3(testOpenTypeServiceRootURL);
++ otcontainerFactory = EntityContainerFactory.getV3(testOpenTypeServiceRootURL);
otcontainerFactory.getClient().getConfiguration().
setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
otcontainer = otcontainerFactory.getEntityContainer(DefaultContainer.class);
@@@ -64,7 -64,7 +65,7 @@@
getAnnotation(EntityType.class).openType());
assertTrue(otcontainer.getRow().newIndexedRow().getClass().getInterfaces()[0].
getAnnotation(EntityType.class).openType());
- containerFactory.getContext().detachAll();
- entityContext.detachAll();
++ otcontainerFactory.getContext().detachAll();
}
@Test
@@@ -124,7 -124,7 +125,7 @@@
assertTrue(Calendar.class.isAssignableFrom(rowIndex.getAdditionalProperty("aDate").getClass()));
assertEquals(ContactDetails.class, rowIndex.getAdditionalProperty("aContact").getClass().getInterfaces()[0]);
- containerFactory.getContext().detachAll();
- entityContext.detachAll();
++ otcontainerFactory.getContext().detachAll();
otcontainer.getRowIndex().delete(id);
otcontainer.flush();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AbstractTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/AbstractTestITCase.java
index 40cd2bb,4efc7d0..c46d59d
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AbstractTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AbstractTestITCase.java
@@@ -105,7 -111,7 +108,7 @@@ public abstract class AbstractTestITCas
assertEquals(orderDate.getTimeInMillis(), actual.getOrderDate().getTimeInMillis());
assertEquals(BigDecimal.TEN, actual.getShelfLife());
assertEquals(2, actual.getOrderShelfLifes().size());
--
++
container.getOrders().delete(105);
actual = container.getOrders().get(105);
assertNull(actual);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AuthEntityCreateTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/AuthEntityCreateTestITCase.java
index 0000000,d837075..678e714
mode 000000,100644..100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AuthEntityCreateTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/AuthEntityCreateTestITCase.java
@@@ -1,0 -1,50 +1,52 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.olingo.fit.proxy.v4;
+
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
+ import org.apache.olingo.client.core.http.BasicAuthHttpClientFactory;
+ import org.apache.olingo.commons.api.format.ContentType;
+ import org.apache.olingo.ext.proxy.EntityContainerFactory;
-import static org.apache.olingo.fit.proxy.v4.AbstractTestITCase.containerFactory;
++
++import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
+ import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.InMemoryEntities;
+
+ public class AuthEntityCreateTestITCase extends EntityCreateTestITCase {
+
- @BeforeClass
- public static void setupContaner() {
- containerFactory = EntityContainerFactory.getV4(testAuthServiceRootURL);
- containerFactory.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
- containerFactory.getClient().getConfiguration().
- setHttpClientFactory(new BasicAuthHttpClientFactory("odatajclient", "odatajclient"));
- container = containerFactory.getEntityContainer(InMemoryEntities.class);
- assertNotNull(container);
++ private EntityContainerFactory<EdmEnabledODataClient> ecf;
++
++ private InMemoryEntities ime;
++
++ @Override
++ public EntityContainerFactory<EdmEnabledODataClient> getContainerFactory() {
++ if (ecf == null) {
++ ecf = EntityContainerFactory.getV4(testAuthServiceRootURL);
++ ecf.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
++ ecf.getClient().getConfiguration().
++ setHttpClientFactory(new BasicAuthHttpClientFactory("odatajclient", "odatajclient"));
++ }
++ return ecf;
+ }
+
- @AfterClass
- public static void disableBasicAuth() {
- containerFactory = EntityContainerFactory.getV4(testStaticServiceRootURL);
- container = containerFactory.getEntityContainer(InMemoryEntities.class);
- assertNotNull(container);
++ @Override
++ protected InMemoryEntities getContainer() {
++ if (ime == null) {
++ ime = getContainerFactory().getEntityContainer(InMemoryEntities.class);
++ }
++ return ime;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java
index 5eaae9a,88c4743..faea864
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/EntityCreateTestITCase.java
@@@ -29,6 -29,8 +29,9 @@@ import java.util.Calendar
import java.util.Collections;
import java.util.TimeZone;
import org.apache.commons.lang3.RandomUtils;
-import static org.apache.olingo.fit.proxy.v4.AbstractTestITCase.container;
-
++import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
++import org.apache.olingo.ext.proxy.EntityContainerFactory;
++import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.InMemoryEntities;
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.AccessLevel;
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Address;
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Color;
@@@ -53,16 -55,16 +56,24 @@@ import org.junit.Test
*/
public class EntityCreateTestITCase extends AbstractTestITCase {
++ public EntityContainerFactory<EdmEnabledODataClient> getContainerFactory() {
++ return containerFactory;
++ }
++
++ protected InMemoryEntities getContainer() {
++ return container;
++ }
++
@Test
public void createAndDelete() {
-- createAndDeleteOrder(container);
++ createAndDeleteOrder(getContainer());
}
@Test
public void createEmployee() {
final Integer id = 101;
-- final Employee employee = container.getPeople().newEmployee();
++ final Employee employee = getContainer().getPeople().newEmployee();
employee.setPersonID(id);
employee.setFirstName("Fabio");
employee.setLastName("Martelli");
@@@ -78,27 -80,27 +89,27 @@@
employee.setHomeAddress(homeAddress);
employee.setNumbers(Arrays.asList(new String[] {"3204725072", "08569930"}));
-- container.flush();
++ getContainer().flush();
-- Employee actual = container.getPeople().get(id, Employee.class);
++ Employee actual = getContainer().getPeople().get(id, Employee.class);
assertNotNull(actual);
assertEquals(id, actual.getPersonID());
assertEquals(homeAddress.getCity(), actual.getHomeAddress().getCity());
- containerFactory.getContext().detachAll();
- actual = container.getPeople().get(id, Employee.class);
- entityContext.detachAll();
- actual = container.getPeople().get(id, Employee.class);
++ getContainerFactory().getContext().detachAll();
++ actual = getContainer().getPeople().get(id, Employee.class);
assertNotNull(actual);
assertEquals(id, actual.getPersonID());
assertEquals(homeAddress.getCity(), actual.getHomeAddress().getCity());
-- container.getPeople().delete(actual.getPersonID());
-- container.flush();
++ getContainer().getPeople().delete(actual.getPersonID());
++ getContainer().flush();
- actual = container.getPeople().get(id, Employee.class);;
- actual = container.getPeople().get(id, Employee.class);
++ actual = getContainer().getPeople().get(id, Employee.class);
assertNull(actual);
- containerFactory.getContext().detachAll();
- actual = container.getPeople().get(id, Employee.class);
- entityContext.detachAll();
- actual = container.getPeople().get(id, Employee.class);
++ getContainerFactory().getContext().detachAll();
++ actual = getContainer().getPeople().get(id, Employee.class);
assertNull(actual);
}
@@@ -106,7 -108,7 +117,7 @@@
public void createWithNavigation() {
final Integer id = 101;
-- final Customer customer = container.getCustomers().newCustomer();
++ final Customer customer = getContainer().getCustomers().newCustomer();
customer.setPersonID(id);
customer.setPersonID(id);
customer.setFirstName("Fabio");
@@@ -120,21 -122,21 +131,21 @@@
customer.setHomeAddress(homeAddress);
customer.setNumbers(Arrays.asList(new String[] {"3204725072", "08569930"}));
-- final OrderCollection orders = container.getOrders().newOrderCollection();
-- orders.add(container.getOrders().get(8));
++ final OrderCollection orders = getContainer().getOrders().newOrderCollection();
++ orders.add(getContainer().getOrders().get(8));
customer.setOrders(orders);
-- container.flush();
++ getContainer().flush();
Customer actual = readCustomer(container, id);
assertEquals(homeAddress.getCity(), actual.getHomeAddress().getCity());
assertEquals(1, actual.getOrders().size());
assertEquals(8, actual.getOrders().iterator().next().getOrderID(), 0);
-
- container.getCustomers().delete(actual.getPersonID());
- container.flush();
- container.getCustomers().delete(actual.getPersonID());
- container.flush();
- actual = container.getCustomers().get(id);
++ getContainer().getCustomers().delete(actual.getPersonID());
++ getContainer().flush();
+
- actual = container.getCustomers().get(id);
++ actual = getContainer().getCustomers().get(id);
assertNull(actual);
}
@@@ -145,7 -147,7 +156,7 @@@
// -------------------------------
// Create a new order
// -------------------------------
-- Order order = container.getOrders().newOrder();
++ Order order = getContainer().getOrders().newOrder();
order.setOrderID(id);
final Calendar orderDate = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
@@@ -160,7 -162,7 +171,7 @@@
// -------------------------------
// Create a new customer
// -------------------------------
-- final Customer customer = container.getCustomers().newCustomer();
++ final Customer customer = getContainer().getCustomers().newCustomer();
customer.setPersonID(id);
customer.setPersonID(id);
customer.setFirstName("Fabio");
@@@ -174,7 -176,7 +185,7 @@@
customer.setHomeAddress(homeAddress);
customer.setNumbers(Arrays.asList(new String[] {"3204725072", "08569930"}));
-- final OrderCollection orders = container.getOrders().newOrderCollection();
++ final OrderCollection orders = getContainer().getOrders().newOrderCollection();
orders.add(order);
customer.setOrders(orders);
// -------------------------------
@@@ -185,7 -187,7 +196,7 @@@
order.setCustomerForOrder(customer);
// -------------------------------
-- container.flush();
++ getContainer().flush();
assertEquals(id, order.getOrderID());
assertEquals(id, customer.getPersonID());
@@@ -195,56 -197,56 +206,56 @@@
assertEquals(1, actual.getOrders().size());
assertEquals(id, actual.getOrders().iterator().next().getOrderID());
-- order = container.getOrders().get(id);
++ order = getContainer().getOrders().get(id);
assertNotNull(order);
assertEquals(id, order.getCustomerForOrder().getPersonID());
-- container.getOrders().delete(actual.getOrders());
-- container.flush();
++ getContainer().getOrders().delete(actual.getOrders());
++ getContainer().flush();
-- order = container.getOrders().get(id);
++ order = getContainer().getOrders().get(id);
assertNull(order);
actual = readCustomer(container, id);
assertTrue(actual.getOrders().isEmpty());
-- container.getCustomers().delete(actual.getPersonID());
-- container.flush();
++ getContainer().getCustomers().delete(actual.getPersonID());
++ getContainer().flush();
-- actual = container.getCustomers().get(id);
++ actual = getContainer().getCustomers().get(id);
assertNull(actual);
}
@Test
public void multiKey() {
-- OrderDetail details = container.getOrderDetails().newOrderDetail();
++ OrderDetail details = getContainer().getOrderDetails().newOrderDetail();
details.setOrderID(8);
details.setProductID(1);
details.setQuantity(100);
details.setUnitPrice(5f);
-- container.flush();
++ getContainer().flush();
OrderDetailKey key = new OrderDetailKey();
key.setOrderID(8);
key.setProductID(1);
-- details = container.getOrderDetails().get(key);
++ details = getContainer().getOrderDetails().get(key);
assertNotNull(details);
assertEquals(Integer.valueOf(100), details.getQuantity());
assertEquals(8, details.getOrderID(), 0);
assertEquals(1, details.getProductID(), 0);
assertEquals(5f, details.getUnitPrice(), 0);
-- container.getOrderDetails().delete(key);
-- container.flush();
++ getContainer().getOrderDetails().delete(key);
++ getContainer().flush();
-- assertNull(container.getOrderDetails().get(key));
++ assertNull(getContainer().getOrderDetails().get(key));
}
@Test
public void deepInsert() {
-- Product product = container.getProducts().newProduct();
++ Product product = getContainer().getProducts().newProduct();
product.setProductID(12);
product.setName("Latte");
product.setQuantityPerUnit("100g Bag");
@@@ -255,30 -257,30 +266,30 @@@
product.setSkinColor(Color.Blue);
product.setCoverColors(Arrays.asList(new Color[] {Color.Red, Color.Green}));
-- final ProductDetail detail = container.getProductDetails().newProductDetail();
++ final ProductDetail detail = getContainer().getProductDetails().newProductDetail();
detail.setProductID(product.getProductID());
detail.setProductDetailID(12);
detail.setProductName("LatteHQ");
detail.setDescription("High-Quality Milk");
-- final ProductDetailCollection detailCollection = container.getProductDetails().newProductDetailCollection();
++ final ProductDetailCollection detailCollection = getContainer().getProductDetails().newProductDetailCollection();
detailCollection.add(detail);
product.setDetails(detailCollection);
-- container.flush();
++ getContainer().flush();
-- product = container.getProducts().get(12);
++ product = getContainer().getProducts().get(12);
assertEquals("Latte", product.getName());
assertEquals(12, product.getDetails().iterator().next().getProductDetailID(), 0);
}
@Test
public void contained() {
-- PaymentInstrumentCollection instruments = container.getAccounts().get(101).getMyPaymentInstruments().getAll();
++ PaymentInstrumentCollection instruments = getContainer().getAccounts().get(101).getMyPaymentInstruments().getAll();
final int sizeBefore = instruments.size();
-- final PaymentInstrument instrument = container.getAccounts().get(101).
++ final PaymentInstrument instrument = getContainer().getAccounts().get(101).
getMyPaymentInstruments().newPaymentInstrument();
final int id = RandomUtils.nextInt(101999, 105000);
@@@ -286,17 -288,17 +297,17 @@@
instrument.setFriendlyName("New one");
instrument.setCreatedDate(Calendar.getInstance());
-- container.flush();
++ getContainer().flush();
-- instruments = container.getAccounts().get(101).getMyPaymentInstruments().getAll();
++ instruments = getContainer().getAccounts().get(101).getMyPaymentInstruments().getAll();
final int sizeAfter = instruments.size();
assertEquals(sizeBefore + 1, sizeAfter);
-- container.getAccounts().get(101).getMyPaymentInstruments().delete(id);
++ getContainer().getAccounts().get(101).getMyPaymentInstruments().delete(id);
-- container.flush();
++ getContainer().flush();
-- instruments = container.getAccounts().get(101).getMyPaymentInstruments().getAll();
++ instruments = getContainer().getAccounts().get(101).getMyPaymentInstruments().getAll();
final int sizeEnd = instruments.size();
assertEquals(sizeBefore, sizeEnd);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/MediaEntityTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/MediaEntityTestITCase.java
index 0000000,ad78bdd..60074b0
mode 000000,100644..100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/MediaEntityTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/MediaEntityTestITCase.java
@@@ -1,0 -1,106 +1,106 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.olingo.fit.proxy.v4;
+
+ import static org.junit.Assert.assertNull;
+ import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertTrue;
+
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.util.Calendar;
+ import java.util.UUID;
+ import org.apache.commons.io.IOUtils;
+ import org.apache.commons.lang3.RandomStringUtils;
+ import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
+ import org.apache.olingo.commons.api.format.ContentType;
+ import org.apache.olingo.ext.proxy.EntityContainerFactory;
+ import org.apache.olingo.fit.proxy.v4.demo.odatademo.DemoService;
+ import org.apache.olingo.fit.proxy.v4.demo.odatademo.types.Advertisement;
+ import org.junit.BeforeClass;
+ import org.junit.Test;
+
+ /**
+ * This is the unit test class to check media entity retrieve operations.
+ */
+ public class MediaEntityTestITCase extends AbstractTestITCase {
+
+ private static DemoService dcontainer;
+
+ @BeforeClass
+ public static void initContainer() {
+ final EntityContainerFactory<EdmEnabledODataClient> otcontainerFactory =
+ EntityContainerFactory.getV4(testDemoServiceRootURL);
+ otcontainerFactory.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
+ dcontainer = otcontainerFactory.getEntityContainer(DemoService.class);
+ assertNotNull(dcontainer);
+ }
+
+ @Test
+ public void read() throws IOException {
+ final UUID uuid = UUID.fromString("f89dee73-af9f-4cd4-b330-db93c25ff3c7");
+
+ final Advertisement adv = dcontainer.getAdvertisements().get(uuid);
+ assertTrue(adv.getAirDate() instanceof Calendar);
+
+ final InputStream is = adv.getStream();
+ assertNotNull(is);
+ IOUtils.closeQuietly(is);
+ }
+
+ @Test
+ public void update() throws IOException {
+ final UUID uuid = UUID.fromString("f89dee73-af9f-4cd4-b330-db93c25ff3c7");
+
+ final Advertisement adv = dcontainer.getAdvertisements().get(uuid);
+ assertNotNull(adv);
+
+ final String random = RandomStringUtils.random(124, "abcdefghijklmnopqrstuvwxyz");
+
+ adv.setStream(IOUtils.toInputStream(random));
+
+ dcontainer.flush();
+
+ assertEquals(random, IOUtils.toString(dcontainer.getAdvertisements().get(uuid).getStream()));
+ }
+
+ @Test
+ public void create() throws IOException {
+ final String random = RandomStringUtils.random(124, "abcdefghijklmnopqrstuvwxyz");
+
+ final Advertisement adv = dcontainer.getAdvertisements().newAdvertisement();
+ adv.setStream(IOUtils.toInputStream(random));
+ adv.setAirDate(Calendar.getInstance());
+
+ dcontainer.flush();
+
+ final UUID uuid = adv.getID();
- entityContext.detachAll();
++ containerFactory.getContext().detachAll();
+
+ assertEquals(random, IOUtils.toString(dcontainer.getAdvertisements().get(uuid).getStream()));
+
- entityContext.detachAll();
++ containerFactory.getContext().detachAll();
+
+ dcontainer.getAdvertisements().delete(uuid);
+ dcontainer.flush();
+
+ assertNull(dcontainer.getAdvertisements().get(uuid));
+ }
+ }
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/OpenTypeTestITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/OpenTypeTestITCase.java
index 9b63483,e337521..035b7a3
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/OpenTypeTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/OpenTypeTestITCase.java
@@@ -45,12 -46,12 +46,13 @@@ import org.junit.Test
*/
public class OpenTypeTestITCase extends AbstractTestITCase {
++ private static EntityContainerFactory<EdmEnabledODataClient> otcontainerFactory;
++
private static DefaultContainer otcontainer;
@BeforeClass
public static void initContainer() {
-- final EntityContainerFactory<EdmEnabledODataClient> otcontainerFactory =
-- EntityContainerFactory.getV4(testOpenTypeServiceRootURL);
++ otcontainerFactory = EntityContainerFactory.getV4(testOpenTypeServiceRootURL);
otcontainerFactory.getClient().getConfiguration().
setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
otcontainer = otcontainerFactory.getEntityContainer(DefaultContainer.class);
@@@ -65,7 -66,7 +67,7 @@@
getAnnotation(EntityType.class).openType());
assertTrue(otcontainer.getRow().newIndexedRow().getClass().getInterfaces()[0].
getAnnotation(EntityType.class).openType());
- containerFactory.getContext().detachAll();
- entityContext.detachAll();
++ otcontainerFactory.getContext().detachAll();
}
@Test
@@@ -127,8 -134,12 +135,12 @@@
assertEquals(ContactDetails.class, rowIndex.getAdditionalProperty("aContact").getClass().getInterfaces()[0]);
assertEquals(Color.class, rowIndex.getAdditionalProperty("aColor").getClass());
assertEquals(Color.Green, rowIndex.getAdditionalProperty("aColor"));
+ assertEquals("Fabio", AccountInfo.class.cast(rowIndex.getAdditionalProperty("info")).getFirstName());
+ assertEquals("Martelli", AccountInfo.class.cast(rowIndex.getAdditionalProperty("info")).getLastName());
+ assertEquals("fabio.martelli@tirasa.net", AccountInfo.class.cast(rowIndex.getAdditionalProperty("info")).
+ getAdditionalProperty("email"));
- containerFactory.getContext().detachAll();
- entityContext.detachAll();
++ otcontainerFactory.getContext().detachAll();
otcontainer.getRowIndex().delete(id);
otcontainer.flush();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/demo/odatademo/DemoService.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/demo/odatademo/DemoService.java
index 0000000,88c555d..627a08f
mode 000000,100644..100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/demo/odatademo/DemoService.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/demo/odatademo/DemoService.java
@@@ -1,0 -1,85 +1,85 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.olingo.fit.proxy.v4.demo.odatademo;
+
+ import org.apache.olingo.client.api.http.HttpMethod;
+ import org.apache.olingo.ext.proxy.api.annotations.Namespace;
+ import org.apache.olingo.ext.proxy.api.annotations.EntityContainer;
+ import org.apache.olingo.ext.proxy.api.annotations.Operation;
+ import org.apache.olingo.ext.proxy.api.annotations.Parameter;
+ import org.apache.olingo.ext.proxy.api.annotations.Property;
-import org.apache.olingo.ext.proxy.api.Container;
++import org.apache.olingo.ext.proxy.api.PersistenceManager;
+ import org.apache.olingo.ext.proxy.api.OperationType;
+ import org.apache.olingo.fit.proxy.v4.demo.odatademo.*;
+ import org.apache.olingo.fit.proxy.v4.demo.odatademo.types.*;
+
+ import org.apache.olingo.commons.api.edm.geo.Geospatial;
+ import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
+ import org.apache.olingo.commons.api.edm.geo.LineString;
+ import org.apache.olingo.commons.api.edm.geo.MultiLineString;
+ import org.apache.olingo.commons.api.edm.geo.MultiPoint;
+ import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
+ import org.apache.olingo.commons.api.edm.geo.Point;
+ import org.apache.olingo.commons.api.edm.geo.Polygon;
+ import java.math.BigDecimal;
+ import java.net.URI;
+ import java.util.UUID;
+ import java.io.Serializable;
+ import java.util.Collection;
+ import java.util.Calendar;
+ import javax.xml.datatype.Duration;
+
+ @Namespace("ODataDemo")
+ @EntityContainer(name = "DemoService",
+ namespace = "ODataDemo",
+ isDefaultEntityContainer = true)
-public interface DemoService extends Container {
++public interface DemoService extends PersistenceManager {
+
+ Products getProducts();
+ Advertisements getAdvertisements();
+ Persons getPersons();
+ Categories getCategories();
+ PersonDetails getPersonDetails();
+ Suppliers getSuppliers();
+ ProductDetails getProductDetails();
+
+
+
+ Operations operations();
+
+ public interface Operations {
+
+ @Operation(name = "IncreaseSalaries",
+ type = OperationType.ACTION)
+ void increaseSalaries(
+ @Parameter(name = "percentage", type = "Edm.Int32", nullable = false) Integer percentage
+ );
+
+ }
+
+ ComplexFactory complexFactory();
+
+ interface ComplexFactory {
+ @Property(name = "Address",
+ type = "ODataDemo.Address")
+ org.apache.olingo.fit.proxy.v4.demo.odatademo.types.Address newAddress();
+
+ }
+ }
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7a09dd24/fit/src/test/java/org/apache/olingo/fit/proxy/v4/opentype/microsoft/test/odata/services/opentypesservicev4/DefaultContainer.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/proxy/v4/opentype/microsoft/test/odata/services/opentypesservicev4/DefaultContainer.java
index 11d485e,f146c6b..574d5b4
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/opentype/microsoft/test/odata/services/opentypesservicev4/DefaultContainer.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/opentype/microsoft/test/odata/services/opentypesservicev4/DefaultContainer.java
@@@ -50,10 -50,9 +50,9 @@@ import javax.xml.datatype.Duration
@EntityContainer(name = "DefaultContainer",
namespace = "Microsoft.Test.OData.Services.OpenTypesServiceV4",
isDefaultEntityContainer = true)
-public interface DefaultContainer extends Container {
+public interface DefaultContainer extends PersistenceManager {
Row getRow();
-
RowIndex getRowIndex();