package org.odata4j.core;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.core4j.Enumerable;
import org.odata4j.edm.EdmEntitySet;
import org.odata4j.edm.EdmEntityType;
import org.odata4j.edm.EdmType;
/**
* A static factory to create immutable {@link OEntity} instances.
*/
public class OEntities {
private OEntities() {}
/**
* Creates a new entity.
*
* @param entitySet the entity-set
* @param entityKey the entity-key
* @param properties the entity properties, if any
* @param links the entity links, if any
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, OEntityKey entityKey, List<OProperty<?>> properties, List<OLink> links) {
return new OEntityImpl(entitySet, null, entityKey, true, null, properties, links);
}
/**
* Creates a new entity.
*
* @param entitySet the entity-set
* @param entityKey the entity-key
* @param properties the entity properties, if any
* @param links the entity links, if any
* @param extensions entity extensions, if any
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, OEntityKey entityKey, List<OProperty<?>> properties, List<OLink> links, Object... extensions) {
return new OEntityImpl(entitySet, null, entityKey, true, null, properties, links, extensions);
}
/**
* Creates a new entity.
*
* @param entitySet the entity-set
* @param entityKey the entity-key
* @param properties the entity properties, if any
* @param links the entity links, if any
* @param extensions entity extensions, if any
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, EdmEntityType entityType, OEntityKey entityKey, List<OProperty<?>> properties, List<OLink> links, Object... extensions) {
return new OEntityImpl(entitySet, entityType, entityKey, true, null, properties, links, extensions);
}
/**
* Creates a new entity.
*
* @param entitySet the entity-set
* @param entityType the entity type
* @param entityKey the entity-key
* @param properties the entity properties, if any
* @param links the entity links, if any
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, EdmEntityType entityType, OEntityKey entityKey, List<OProperty<?>> properties, List<OLink> links) {
return new OEntityImpl(entitySet, entityType, entityKey, true, null, properties, links);
}
/**
* Creates a new entity.
*
* @param entitySet the entity-set
* @param entityType the entity type
* @param entityKey the entity-key
* @param entityTag the entity-tag
* @param properties the entity properties, if any
* @param links the entity links, if any
* @param extensions extensions to the entity
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, EdmEntityType entityType, OEntityKey entityKey, String entityTag, List<OProperty<?>> properties, List<OLink> links, Object... extensions) {
return new OEntityImpl(entitySet, entityType, entityKey, true, entityTag, properties, links, extensions);
}
/**
* Creates a new request-entity.
* <p>A request-entity is a new entity that has not yet been created in an OData service, and therefore allowed to not have an entity-key.</p>
*
* @param entitySet the entity-set
* @param properties the entity properties, if any
* @param links the entity links, if any
* @return the new entity
*/
public static OEntity createRequest(EdmEntitySet entitySet, List<OProperty<?>> properties, List<OLink> links) {
return new OEntityImpl(entitySet, null, null, false, null, properties, links);
}
/**
* Creates a new entity with additional Atom information.
*
* @param entitySet the entity-set
* @param entityType the entity type
* @param entityKey the entity-key
* @param entityTag the entity-tag, if applicable
* @param properties the entity properties, if any
* @param links the entity links, if any
* @param title the Atom title
* @param categoryTerm the Atom category term
* @param extensions extensions to the entity
* @return the new entity
*/
public static OEntity create(EdmEntitySet entitySet, EdmEntityType entityType, OEntityKey entityKey, String entityTag, List<OProperty<?>> properties, List<OLink> links, String title, String categoryTerm, Object... extensions) {
return new OEntityAtomImpl(entitySet, entityType, entityKey, true, entityTag, properties, links, title, categoryTerm, extensions);
}
/**
* Creates a new request-entity with additional Atom information.
* <p>A request-entity is a new entity that has not yet been created in an OData service, and therefore allowed to not have an entity-key.</p>
*
* @param entitySet the entity-set
* @param properties the entity properties, if any
* @param links the entity links, if any
* @param title the Atom title
* @param categoryTerm the Atom category term
* @return the new entity
*/
public static OEntity createRequest(EdmEntitySet entitySet, List<OProperty<?>> properties, List<OLink> links, String title, String categoryTerm) {
return new OEntityAtomImpl(entitySet, null, null, false, null, properties, links, title, categoryTerm);
}
private static class OEntityAtomImpl extends OEntityImpl implements AtomInfo {
private final String title;
private final String categoryTerm;
public OEntityAtomImpl(EdmEntitySet entitySet, EdmEntityType entityType, OEntityKey entityKey, boolean entityKeyRequired, String entityTag,
List<OProperty<?>> properties, List<OLink> links, String title, String categoryTerm, Object... extensions) {
super(entitySet, entityType, entityKey, entityKeyRequired, entityTag, properties, links, extensions);
this.title = title;
this.categoryTerm = categoryTerm;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getCategoryTerm() {
return categoryTerm;
}
}
private static class OEntityImpl implements OEntity {
private final EdmEntitySet entitySet;
private final EdmEntityType entityType;
private final OEntityKey entityKey;
private final List<OProperty<?>> properties;
private final List<OLink> links;
private final String entityTag;
private final Collection<Object> extensions;
private InputStream mediaInputStream;
private String mediaStreamContentType;
OEntityImpl(EdmEntitySet entitySet, EdmEntityType entityType,
OEntityKey entityKey, boolean entityKeyRequired,
String entityTag,
List<OProperty<?>> properties, List<OLink> links,
Object... extensions) {
if (entitySet == null)
throw new IllegalArgumentException("entitySet cannot be null");
if (entityKeyRequired && entityKey == null)
throw new IllegalArgumentException("entityKey cannot be null");
this.entitySet = entitySet;
this.entityType = entityType;
this.entityKey = entityKey;
this.entityTag = entityTag;
this.properties = Collections.unmodifiableList(properties);
this.links = links == null ? Collections.<OLink> emptyList() : Collections.unmodifiableList(links);
this.extensions = Arrays.asList(extensions);
}
@Override
public String toString() {
return "OEntity[" + Enumerable.create(getProperties()).join(",") + "]";
}
@Override
public EdmEntitySet getEntitySet() {
return entitySet;
}
@Override
public EdmEntityType getEntityType() {
return entityType != null ? entityType : entitySet != null ? entitySet.getType() : null;
}
@Override
public String getEntitySetName() {
return entitySet.getName();
}
@Override
public OEntityKey getEntityKey() {
return entityKey;
}
@Override
public List<OProperty<?>> getProperties() {
return properties;
}
@Override
public OProperty<?> getProperty(String propName) {
return Enumerable.create(properties).first(OPredicates.propertyNameEquals(propName));
}
@SuppressWarnings("unchecked")
@Override
public <T> OProperty<T> getProperty(String propName, Class<T> propClass) {
return (OProperty<T>) getProperty(propName);
}
@Override
public List<OLink> getLinks() {
return links;
}
@SuppressWarnings("unchecked")
@Override
public <T extends OLink> T getLink(String title, Class<T> linkClass) {
for (OLink link : getLinks())
if (link.getTitle().equals(title))
return (T) link;
throw new IllegalArgumentException("No link with title: " + title);
}
@Override
public String getEntityTag() {
return entityTag;
}
@Override
public EdmType getType() {
return this.entitySet.getType();
}
@Override
public <TExtension extends OExtension<OEntity>> TExtension findExtension(Class<TExtension> clazz) {
for (Object extension : extensions) {
if (clazz.isInstance(extension)) {
return clazz.cast(extension);
}
}
return null;
}
@Override
public String getMediaTypeForStream() {
return this.mediaStreamContentType;
}
@Override
public InputStream getMediaLinkStream() {
return this.mediaInputStream;
}
@Override
public void setMediaLinkStream(InputStream inStream) {
this.mediaInputStream = inStream;
}
@Override
public void setMediaTypeForStream(String mediaTypeForStream) {
this.mediaStreamContentType = mediaTypeForStream;
}
}
}