package ru.semiot.platform.apigateway.rest; import static ru.semiot.commons.restapi.AsyncResponseHelper.resume; import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.utils.JsonUtils; import org.apache.jena.datatypes.xsd.XSDDatatype; import org.apache.jena.rdf.model.Literal; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ResIterator; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.vocabulary.DCTerms; import org.apache.jena.vocabulary.RDF; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.semiot.commons.namespaces.Proto; import ru.semiot.commons.namespaces.SSN; import ru.semiot.commons.rdf.ModelJsonLdUtils; import ru.semiot.commons.restapi.MediaType; import ru.semiot.platform.apigateway.beans.impl.ContextProvider; import ru.semiot.platform.apigateway.beans.impl.SPARQLQueryService; import ru.semiot.platform.apigateway.utils.URIUtils; import rx.exceptions.Exceptions; import java.io.IOException; import java.net.URI; import java.util.Map; import javax.ejb.Stateless; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; @Path("/systems/{system_id}/subsystems") @Stateless public class SubSystemResource extends AbstractSystemResource { private static final Logger logger = LoggerFactory.getLogger(SubSystemResource.class); private static final String QUERY_DESCRIBE_SUBSYSTEM = "CONSTRUCT {" + " ?subsystem ?p ?o ." + " ?o ?o_p ?o_o ." + "} WHERE {" + " ?subsystem ?p ?o ;" + " dcterms:identifier \"${SUBSYSTEM_ID}\" ." + " OPTIONAL {" + " ?o ?o_p ?o_o ." + " FILTER isBlank(?o)" + " }" + "}"; public SubSystemResource() { super(); } @Inject private ContextProvider contextProvider; @Inject private SPARQLQueryService sparqlQuery; @Context private UriInfo uriInfo; @GET @Path("/{subsystem_id}") @Produces({MediaType.APPLICATION_LD_JSON, MediaType.APPLICATION_JSON}) public void getSubsystem(@Suspended final AsyncResponse response, @PathParam("system_id") String systemId, @PathParam("subsystem_id") String subsystemId) throws IOException { URI root = uriInfo.getRequestUri(); String rootUrl = URIUtils.extractRootURL(root); Model model = contextProvider.getRDFModel( ContextProvider.SUBSYSTEM_SINGLE, root); Map<String, Object> frame = contextProvider.getFrame( ContextProvider.SUBSYSTEM_SINGLE, root); sparqlQuery.describe(QUERY_DESCRIBE_SUBSYSTEM.replace("${SUBSYSTEM_ID}", subsystemId)) .map((Model result) -> { model.add(result); try { Literal identifier = ResourceFactory.createTypedLiteral( subsystemId, XSDDatatype.XSDstring); Resource subsystem = model.listResourcesWithProperty( DCTerms.identifier, identifier).next(); Resource prototype = model.listObjectsOfProperty( subsystem, Proto.hasPrototype).next().asResource(); Resource prototypeResource = ResourceUtils .createResourceFromClass(root, prototype.getLocalName()); model.add(subsystem, RDF.type, prototypeResource); ResIterator sdIterator = model.listSubjectsWithProperty( RDF.type, SSN.SensingDevice); if (sdIterator.hasNext()) { //The subsystem is a sensing device Resource sensingDevice = sdIterator.next(); model.add(sensingDevice, ResourceFactory.createProperty(rootUrl + "/doc#observations"), ResourceFactory.createResource(UriBuilder.fromUri(root) .replacePath("/systems/{system_id}/observations") .queryParam("sensor_id", subsystemId) .build(systemId).toASCIIString())); } return JsonUtils.toPrettyString(ModelJsonLdUtils.toJsonLdCompact(model, frame)); } catch (JsonLdError | IOException ex) { throw Exceptions.propagate(ex); } }).subscribe(resume(response)); } }