package org.odata4j.producer;
import java.util.ArrayList;
import java.util.List;
import org.odata4j.core.OCollection;
import org.odata4j.core.OCollections;
import org.odata4j.core.OEntities;
import org.odata4j.core.OEntity;
import org.odata4j.core.OEntityKey;
import org.odata4j.core.OEntityKey.KeyType;
import org.odata4j.core.OFunctionParameter;
import org.odata4j.core.OFunctionParameters;
import org.odata4j.core.OLink;
import org.odata4j.core.OProperties;
import org.odata4j.core.OProperty;
import org.odata4j.edm.EdmCollectionType;
import org.odata4j.edm.EdmEntitySet;
import org.odata4j.edm.EdmEntityType;
import org.odata4j.edm.EdmFunctionImport;
import org.odata4j.edm.EdmFunctionParameter;
import org.odata4j.expression.EntitySimpleProperty;
import org.odata4j.expression.Expression;
public class OBindingResolverExtensions {
public static OBindingResolverExtension getPartialBindingResolver(){
return new KeyOnlyBindingResolverExtension();
}
public static OBindingResolverExtension getFullBindingResolver(){
return new PreloadBindingResolverExtension();
}
/**
* An OBindingResolverExtension that will only resolve entity keys.
*
*/
static class KeyOnlyBindingResolverExtension implements OBindingResolverExtension {
@Override
public OFunctionParameter resolveBindingParameter(
ODataContext context,
EdmFunctionImport function,
String entitySetName,
OEntityKey entityKey,
QueryInfo queryInfo) {
EdmFunctionParameter parameter = function.getBoundParameter();
ODataProducer producer = context.getContextAspect(ODataProducer.class);
if (parameter.getType() instanceof EdmCollectionType){
// Collection binding
EdmEntitySet entitySet = producer.getMetadata().findEdmEntitySet(entitySetName);
EdmEntityType itemType = entitySet.getType();
// We try to select only key attributes
List<String> keyNames = itemType.getKeys();
List<EntitySimpleProperty> selectedKeys = new ArrayList<EntitySimpleProperty>();
for (String keyName: keyNames){
selectedKeys.add(Expression.simpleProperty(keyName));
}
QueryInfo qi = new QueryInfo(
queryInfo.inlineCount,
queryInfo.top,
queryInfo.skip,
queryInfo.filter,
queryInfo.orderBy,
queryInfo.skipToken,
queryInfo.customOptions,
queryInfo.expand,
selectedKeys);
EntitiesResponse response = producer.getEntities(context, entitySetName, qi);
List<OEntity> entities = response.getEntities();
OCollection.Builder<OEntity> builder = OCollections.newBuilder(itemType);
for (OEntity entity : entities){
builder = builder.add(entity);
}
OCollection<?> collection = builder.build();
return OFunctionParameters.create(parameter.getName(), collection);
} else {
// Entity binding
EdmEntitySet entitySet = producer.getMetadata().findEdmEntitySet(entitySetName);
EdmEntityType entityType = entitySet.getType();
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
if (entityKey.getKeyType() == KeyType.SINGLE){
OProperty<?> key = OProperties.simple(entityType.getKeys().get(0), entityKey.asSingleValue());
properties.add(key);
} else {
properties.addAll(entityKey.asComplexProperties());
}
OEntity oEntity = OEntities.create(
entitySet,
entityType,
entityKey,
properties,
new ArrayList<OLink>());
return OFunctionParameters.create(parameter.getName(), oEntity);
}
}
}
/**
* An OBindingResolverExtension that will resolve the full entity by loading
* them from the producer.
*
*/
static class PreloadBindingResolverExtension implements OBindingResolverExtension {
@Override
public OFunctionParameter resolveBindingParameter(ODataContext context, EdmFunctionImport function, String entitySetName, OEntityKey entityKey, QueryInfo queryInfo) {
EdmFunctionParameter parameter = function.getBoundParameter();
ODataProducer producer = context.getContextAspect(ODataProducer.class);
if (parameter.getType() instanceof EdmCollectionType){
// Collection binding
EdmEntitySet entitySet = producer.getMetadata().findEdmEntitySet(entitySetName);
EdmEntityType itemType = entitySet.getType();
// We use the queryInfo use to prefilter arguments
// No way to filter the function result ?!
EntitiesResponse response = producer.getEntities(context, entitySetName, queryInfo);
List<OEntity> entities = response.getEntities();
OCollection.Builder<OEntity> builder = OCollections.newBuilder(itemType);
for (OEntity entity : entities){
builder = builder.add(entity);
}
OCollection<?> collection = builder.build();
return OFunctionParameters.create(parameter.getName(), collection);
} else {
// Entity binding
// queryInfo passed is null as we use it to filter resulting data
EntityResponse response = producer.getEntity(context, entitySetName, entityKey, null);
OEntity entity = response.getEntity();
return OFunctionParameters.create(parameter.getName(), entity);
}
}
}
}