/*
* Data Hub Service (DHuS) - For Space data distribution.
* Copyright (C) 2013,2014,2015,2016 GAEL Systems
*
* This file is part of DHuS software sources.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.gael.dhus.olingo.v1.entityset;
import fr.gael.dhus.database.object.User;
import fr.gael.dhus.olingo.v1.ExpectedException;
import fr.gael.dhus.olingo.v1.Navigator;
import fr.gael.dhus.olingo.v1.Model;
import fr.gael.dhus.olingo.v1.entity.AbstractEntity;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.edm.FullQualifiedName;
import org.apache.olingo.odata2.api.edm.provider.Association;
import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
import org.apache.olingo.odata2.api.edm.provider.EntitySet;
import org.apache.olingo.odata2.api.edm.provider.EntityType;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
import org.apache.olingo.odata2.api.uri.KeyPredicate;
import org.apache.olingo.odata2.api.uri.info.GetComplexPropertyUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
/**
* Base class to implement new Entity Sets.
*
* @param <T> the Entity Type contained in this ES.
*/
public abstract class AbstractEntitySet<T extends AbstractEntity>
{
/**
* @return the name of the Entity Type contained in this ES.
*/
public abstract String getEntityName();
/**
* @return the Entity Type contained in this ES.
*/
public abstract EntityType getEntityType();
/**
* Returns the name of this ES, defaults to {@code "`name of the ET` + (e)s"}.
*
* @return name of this ES.
*/
public String getName()
{
return generateEntitySetName(getEntityName());
}
/**
* @return the full qualified name of the Entity Type contained in this ES.
*/
public FullQualifiedName getFullQualifiedName()
{
return new FullQualifiedName(Model.NAMESPACE, getEntityName());
}
/**
* @return Olingo ES object for this ES.
*/
public EntitySet getEntitySet()
{
EntitySet res = new EntitySet().setName(getName());
res.setEntityType(getFullQualifiedName());
return res;
}
/**
* @return a list of association sets (defaults to empty list).
*/
public List<AssociationSet> getAssociationSets()
{
return Collections.EMPTY_LIST;
}
/**
* @return a list of associations (defaults to empty list).
*/
public List<Association> getAssociations()
{
return Collections.EMPTY_LIST;
}
/**
* Does the navigation and calls {@link AbstractEntity#getProperty(String)}.
* @param uri_info contains the navigation segments and the name of the property to get.
* @return the value of requested property (may be null).
* @throws ODataException
*/
public Object readPropertyValue(GetSimplePropertyUriInfo uri_info)
throws ODataException
{
KeyPredicate startKP = uri_info.getKeyPredicates().get(0);
EdmProperty target
= uri_info.getPropertyPath()
.get(uri_info.getPropertyPath().size() - 1);
T t = Navigator.<T>navigate(uri_info.getStartEntitySet(), startKP,
uri_info.getNavigationSegments(), null);
// Case of complex property
String propName = target.getName();
if (uri_info.getPropertyPath().size() > 1)
{
return t.getComplexProperty(
uri_info.getPropertyPath().get(0).getName()).get(propName);
}
return t.getProperty(propName);
}
public Map<String, Object> getComplexProperty(
GetComplexPropertyUriInfo uri_info) throws ODataException
{
KeyPredicate startKP = uri_info.getKeyPredicates().get(0);
EdmProperty target
= uri_info.getPropertyPath()
.get(uri_info.getPropertyPath().size() - 1);
T t = Navigator.<T>navigate(uri_info.getStartEntitySet(), startKP,
uri_info.getNavigationSegments(), null);
return t.getComplexProperty(target.getName());
}
public ODataResponse getEntityMedia(GetMediaResourceUriInfo uri_info,
ODataSingleProcessor processor) throws ODataException
{
KeyPredicate startKP = uri_info.getKeyPredicates().get(0);
T t = Navigator.<T>navigate(uri_info.getStartEntitySet(), startKP,
uri_info.getNavigationSegments(), null);
ODataResponse resp = t.getEntityMedia(processor);
if (resp == null)
{
throw new ExpectedException("No stream for entity " + getEntityName());
}
return resp;
}
public int count()
{
return 0;
}
public boolean isAuthorized(User user)
{
return true;
}
/**
* Is an abstract ES? defaults to {@code false}.
* @return true if this ES is abstract.
*/
public boolean isAbstract()
{
return false;
}
/**
* Return true if this ES is a top level ES (displayed in the service document and accessible
* at the root of the service).
*
* @return true if is a top level ES.
*/
public boolean isTopLevel()
{
return true;
}
/**
* Return {@code true} to enable pagination.
*
* @return true if this ES typically has many entries
*/
public boolean hasManyEntries()
{
return true;
}
/**
* Returns the entities as a Map.<p>
* Only top-level entity sets (accessible at the root of the OData service)
* should implement this method.
* The returned map may implement SubMap, to create a filtered map.
*
* @return an instance of Map, never null.
*/
public Map<?, AbstractEntity> getEntities()
{
return Collections.EMPTY_MAP;
}
/**
* Returns an Entity identified by the given KeyPredicate.<p>
* Only top-level entity sets (accessible at the root of the OData service)
* should implement this method.
*
* @param kp KeyPredicate.
* @return an Entity or null if `kp` does not identify an Entity.
*/
public AbstractEntity getEntity(KeyPredicate kp)
{
return null;
}
/**
* Get the list of navigation links that are acceptable values for the $expand query parameter.
*
* @return a non null list that may be empty.
*/
public List<String> getExpandableNavLinkNames()
{
return Collections.emptyList();
}
/**
* Expand the given navigation link.
*
* @see fr.gael.dhus.olingo.v1.Expander#expandFeedSingletonKey(String, String, Map, Map, String)
*
* @param navlink_name navlink_name name of the navigation link to expand.
* @param self_url the absolute url to address this entitySet.
* @param entities that are part of the response and will hold the inlined entities returned by
* this method.
* @param key that identifies the Entity from the feed being served to the client.
*
* @return a non null list that may be empty.
*/
public List<Map<String, Object>> expand(String navlink_name, String self_url,
Map<?, AbstractEntity> entities, Map<String, Object> key)
{
throw new IllegalStateException("NavLink " + navlink_name + " cannot be expanded");
}
public static String generateEntitySetName(String entityName)
{
String suffix = "s";
if (entityName.endsWith("s"))
{
suffix = "es";
}
return entityName + suffix;
}
}