package org.odata4j.producer.resources;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.logging.Logger;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import org.core4j.Enumerable;
import org.odata4j.core.ODataConstants;
import org.odata4j.core.OEntityId;
import org.odata4j.core.OEntityIds;
import org.odata4j.core.OEntityKey;
import org.odata4j.edm.EdmMultiplicity;
import org.odata4j.exceptions.NotFoundException;
import org.odata4j.format.FormatParser;
import org.odata4j.format.FormatParserFactory;
import org.odata4j.format.FormatWriter;
import org.odata4j.format.FormatWriterFactory;
import org.odata4j.format.SingleLink;
import org.odata4j.format.SingleLinks;
import org.odata4j.producer.EntityIdResponse;
import org.odata4j.producer.ODataContextImpl;
import org.odata4j.producer.ODataProducer;
public class LinksRequestResource extends BaseResource {
private static final Logger log = Logger.getLogger(LinksRequestResource.class.getName());
private final OEntityId sourceEntity;
private final String targetNavProp;
private final OEntityKey targetEntityKey;
public LinksRequestResource(OEntityId sourceEntity, String targetNavProp, OEntityKey targetEntityKey) {
this.sourceEntity = sourceEntity;
this.targetNavProp = targetNavProp;
this.targetEntityKey = targetEntityKey;
}
@POST
public Response createLink(@Context HttpHeaders httpHeaders,
@Context UriInfo uriInfo,
@Context ContextResolver<ODataProducer> producerResolver,
@Context SecurityContext securityContext,
String payload) {
log.info(String.format(
"createLink(%s,%s,%s,%s)",
sourceEntity.getEntitySetName(),
sourceEntity.getEntityKey(),
targetNavProp,
targetEntityKey));
ODataProducer producer = producerResolver.getContext(ODataProducer.class);
OEntityId newTargetEntity = parseRequestUri(httpHeaders, uriInfo, payload);
producer.createLink(ODataContextImpl.builder().aspect(httpHeaders).aspect(securityContext).build(), sourceEntity, targetNavProp, newTargetEntity);
return noContent();
}
@PUT
public Response updateLink(@Context HttpHeaders httpHeaders,
@Context UriInfo uriInfo,
@Context ContextResolver<ODataProducer> producerResolver,
@Context SecurityContext securityContext,
String payload) {
log.info(String.format(
"updateLink(%s,%s,%s,%s)",
sourceEntity.getEntitySetName(),
sourceEntity.getEntityKey(),
targetNavProp,
targetEntityKey));
ODataProducer producer = producerResolver.getContext(ODataProducer.class);
OEntityId newTargetEntity = parseRequestUri(httpHeaders, uriInfo, payload);
producer.updateLink(ODataContextImpl.builder().aspect(httpHeaders).aspect(securityContext).build(), sourceEntity, targetNavProp, targetEntityKey, newTargetEntity);
return noContent();
}
private OEntityId parseRequestUri(HttpHeaders httpHeaders, UriInfo uriInfo, String payload) {
FormatParser<SingleLink> parser = FormatParserFactory.getParser(SingleLink.class, httpHeaders.getMediaType(), null);
SingleLink link = parser.parse(new StringReader(payload));
return OEntityIds.parse(uriInfo.getBaseUri().toString(), link.getUri());
}
private Response noContent() {
return Response.noContent().header(ODataConstants.Headers.DATA_SERVICE_VERSION, ODataConstants.DATA_SERVICE_VERSION_HEADER).build();
}
@DELETE
public Response deleteLink(@Context HttpHeaders httpHeaders,
@Context UriInfo uriInfo,
@Context ContextResolver<ODataProducer> producerResolver,
@Context SecurityContext securityContext) {
log.info(String.format(
"deleteLink(%s,%s,%s,%s)",
sourceEntity.getEntitySetName(),
sourceEntity.getEntityKey(),
targetNavProp,
targetEntityKey));
ODataProducer producer = producerResolver.getContext(ODataProducer.class);
producer.deleteLink(ODataContextImpl.builder().aspect(httpHeaders).aspect(securityContext).build(), sourceEntity, targetNavProp, targetEntityKey);
return noContent();
}
@GET
public Response getLinks(@Context HttpHeaders httpHeaders,
@Context UriInfo uriInfo,
@Context ContextResolver<ODataProducer> producerResolver,
@Context SecurityContext securityContext,
@QueryParam("$format") String format,
@QueryParam("$callback") String callback) {
log.info(String.format(
"getLinks(%s,%s,%s,%s)",
sourceEntity.getEntitySetName(),
sourceEntity.getEntityKey(),
targetNavProp,
targetEntityKey));
ODataProducer producer = producerResolver.getContext(ODataProducer.class);
EntityIdResponse response = producer.getLinks(ODataContextImpl.builder().aspect(httpHeaders).aspect(securityContext).build(), sourceEntity, targetNavProp);
StringWriter sw = new StringWriter();
String serviceRootUri = uriInfo.getBaseUri().toString();
String contentType;
if (response.getMultiplicity() == EdmMultiplicity.MANY) {
SingleLinks links = SingleLinks.create(serviceRootUri, response.getEntities(), sourceEntity, targetNavProp);
FormatWriter<SingleLinks> fw = FormatWriterFactory.getFormatWriter(SingleLinks.class, httpHeaders.getAcceptableMediaTypes(), format, callback);
fw.write(uriInfo, sw, links);
contentType = fw.getContentType();
} else {
OEntityId entityId = Enumerable.create(response.getEntities()).firstOrNull();
if (entityId == null)
throw new NotFoundException();
SingleLink link = SingleLinks.create(serviceRootUri, entityId, sourceEntity, targetNavProp);
FormatWriter<SingleLink> fw = FormatWriterFactory.getFormatWriter(SingleLink.class, httpHeaders.getAcceptableMediaTypes(), format, callback);
fw.write(uriInfo, sw, link);
contentType = fw.getContentType();
}
String entity = sw.toString();
return Response.ok(entity, contentType).header(ODataConstants.Headers.DATA_SERVICE_VERSION, ODataConstants.DATA_SERVICE_VERSION_HEADER).build();
}
}