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