/** * PODD is an OWL ontology database used for scientific project management * * Copyright (C) 2009-2013 The University Of Queensland * * 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 com.github.podd.resources; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Set; import org.openrdf.OpenRDFException; import org.openrdf.model.Model; import org.openrdf.model.URI; import org.openrdf.rio.RDFFormat; import org.openrdf.rio.Rio; import org.openrdf.rio.UnsupportedRDFormatException; import org.restlet.data.MediaType; import org.restlet.data.Status; import org.restlet.representation.ByteArrayRepresentation; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.Get; import org.restlet.resource.Post; import org.restlet.resource.ResourceException; import org.restlet.security.User; import org.semanticweb.owlapi.model.IRI; import com.github.podd.exception.RepositoryNotFoundException; import com.github.podd.exception.SchemaManifestException; import com.github.podd.exception.UnmanagedArtifactIRIException; import com.github.podd.exception.UnmanagedArtifactVersionException; import com.github.podd.exception.UnmanagedSchemaIRIException; import com.github.podd.restlet.PoddAction; import com.github.podd.utils.InferredOWLOntologyID; import com.github.podd.utils.PODD; import com.github.podd.utils.PoddWebConstants; /** * Search ontology service to search for matching results from an Ontology. * * @author kutila * */ public class SearchOntologyResourceImpl extends AbstractPoddResourceImpl { @Get("rdf|rj|json|ttl") public Representation getRdf(final Variant variant) throws ResourceException { this.log.debug("searchRdf"); final ByteArrayOutputStream output = new ByteArrayOutputStream(8096); // search term - mandatory parameter final String searchTerm = this.getQuery().getFirstValue(PoddWebConstants.KEY_SEARCHTERM, true); if(searchTerm == null) { throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Search term not submitted"); } // artifact ID - optional parameter final String artifactUri = this.getQuery().getFirstValue(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, true); InferredOWLOntologyID ontologyID = null; if(artifactUri != null) { try { ontologyID = this.getPoddArtifactManager().getArtifact(IRI.create(artifactUri)); } catch(final UnmanagedArtifactIRIException | UnmanagedSchemaIRIException e) { throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Could not find the given artifact", e); } } // search Types - optional parameter final String[] searchTypes = this.getQuery().getValuesArray(PoddWebConstants.KEY_SEARCH_TYPES); final Set<URI> set = new HashSet<URI>(); if(searchTypes != null && searchTypes.length > 0) { for(final String searchType : searchTypes) { set.add(PODD.VF.createURI(searchType)); } } this.log.debug("requesting search ({}): {}, {}, {}", variant.getMediaType().getName(), searchTerm, artifactUri, searchTypes); if(ontologyID == null) { // only when a Project Admin is creating a new artifact this.checkAuthentication(PoddAction.ARTIFACT_CREATE); } else { this.checkAuthentication(PoddAction.UNPUBLISHED_ARTIFACT_READ, ontologyID.getOntologyIRI().toOpenRDFURI()); } final User user = this.getRequest().getClientInfo().getUser(); this.log.debug("authenticated user: {}", user); Model results = null; try { results = this.getPoddArtifactManager().searchForOntologyLabels(ontologyID, searchTerm, set.toArray(new URI[0])); } catch(final OpenRDFException | UnmanagedSchemaIRIException | SchemaManifestException | UnsupportedRDFormatException | IOException | UnmanagedArtifactIRIException | UnmanagedArtifactVersionException | RepositoryNotFoundException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Failed searching for Ontology Labels", e); } this.log.debug("Found {} matches for this search term", results.size()); final RDFFormat resultFormat = Rio.getWriterFormatForMIMEType(variant.getMediaType().getName(), RDFFormat.RDFXML); // - prepare response try { Rio.write(results, output, resultFormat); } catch(final OpenRDFException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Error while preparing response", e); } return new ByteArrayRepresentation(output.toByteArray(), MediaType.valueOf(resultFormat.getDefaultMIMEType())); } /** * Handle an HTTP POST requesting information about the content passed in. */ @Post("rdf|rj|json|ttl") public Representation postRdf(final Representation entity, final Variant variant) throws ResourceException { // artifact ID - optional parameter final String artifactUri = this.getQuery().getFirstValue(PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, true); InferredOWLOntologyID ontologyID = null; if(artifactUri != null) { try { ontologyID = this.getPoddArtifactManager().getArtifact(IRI.create(artifactUri)); } catch(final UnmanagedArtifactIRIException | UnmanagedSchemaIRIException e) { throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Could not find the given artifact", e); } } if(ontologyID == null) { // only when a Project Admin is creating a new artifact this.checkAuthentication(PoddAction.ARTIFACT_CREATE); } else { this.checkAuthentication(PoddAction.UNPUBLISHED_ARTIFACT_READ, ontologyID.getOntologyIRI().toOpenRDFURI()); } // - get input stream with incoming content InputStream inputStream = null; try { inputStream = entity.getStream(); } catch(final IOException e) { throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "There was a problem with the input", e); } final RDFFormat inputFormat = Rio.getParserFormatForMIMEType(entity.getMediaType().getName(), RDFFormat.RDFXML); final RDFFormat outputFormat = Rio.getWriterFormatForMIMEType(variant.getMediaType().getName(), RDFFormat.RDFXML); // - prepare response final ByteArrayOutputStream output = new ByteArrayOutputStream(8096); try { // read input content into a Model final Model inputModel = Rio.parse(inputStream, "", inputFormat); final Model resultModel = this.getPoddArtifactManager().fillMissingData(ontologyID, inputModel); // - write the result Model into response Rio.write(resultModel, output, outputFormat); } catch(final OpenRDFException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not create response", e); } catch(final UnsupportedRDFormatException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not parse input format", e); } catch(final IOException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not parse input", e); } catch(final UnmanagedSchemaIRIException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find necessary schema ontology", e); } catch(final SchemaManifestException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find necessary schema ontology", e); } catch(final UnmanagedArtifactIRIException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find artifact IRI", e); } catch(final UnmanagedArtifactVersionException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find artifact version", e); } catch(final RepositoryNotFoundException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find repository", e); } return new ByteArrayRepresentation(output.toByteArray(), MediaType.valueOf(outputFormat.getDefaultMIMEType())); } }