/**
* 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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.openrdf.OpenRDFException;
import org.openrdf.model.Model;
import org.openrdf.model.impl.LinkedHashModel;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
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.ResourceException;
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.ontologies.PODDSCIENCE;
import com.github.podd.restlet.PoddAction;
import com.github.podd.restlet.RestletUtils;
import com.github.podd.utils.InferredOWLOntologyID;
import com.github.podd.utils.OntologyUtils;
import com.github.podd.utils.PODD;
import com.github.podd.utils.PoddObjectLabel;
import com.github.podd.utils.PoddWebConstants;
/**
* Resource which lists the existing artifacts in PODD.
* <p>
* TODO: list based on authorization, group projects. list project title, description, PI and lead
* institution
*
* @author kutila
* @author Peter Ansell p_ansell@yahoo.com
*
*/
public class ListArtifactsResourceImpl extends AbstractPoddResourceImpl
{
public static final String LIST_PAGE_TITLE_TEXT = "PODD Artifact Listing";
private Map<String, List<InferredOWLOntologyID>> getArtifactsInternal() throws ResourceException
{
final Map<String, List<InferredOWLOntologyID>> results = new HashMap<String, List<InferredOWLOntologyID>>();
final String publishedString = this.getQuery().getFirstValue(PoddWebConstants.KEY_PUBLISHED, true);
final String unpublishedString = this.getQuery().getFirstValue(PoddWebConstants.KEY_UNPUBLISHED, true);
// default to both published and unpublished to start with
boolean published = true;
boolean unpublished = false;
if(publishedString != null)
{
published = Boolean.parseBoolean(publishedString);
}
// If the user is authenticated, set unpublished to true before checking
// the query
// parameters
// if(this.getClientInfo().isAuthenticated())
// {
// this.log.info("User was logged in");
// unpublished = true;
// }
if(unpublishedString != null)
{
unpublished = Boolean.parseBoolean(unpublishedString);
}
else
{
// Default to showing unpublished artifacts to authenticated users
// if they did not
// specify anything in their query parameters
unpublished = this.getRequest().getClientInfo().isAuthenticated();
}
if(published)
{
this.log.debug("Including published artifacts");
}
if(unpublished)
{
this.log.debug("Including unpublished artifacts");
}
if(!published && !unpublished)
{
this.log.error("Both published and unpublished artifacts were disabled in query");
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
"Both published and unpublished artifacts were disabled in query");
}
try
{
if(published)
{
final List<InferredOWLOntologyID> publishedResults = new ArrayList<InferredOWLOntologyID>();
final List<InferredOWLOntologyID> publishedArtifacts =
this.getPoddArtifactManager().listPublishedArtifacts();
for(final InferredOWLOntologyID nextPublishedArtifact : publishedArtifacts)
{
if(this.checkAuthentication(PoddAction.PUBLISHED_ARTIFACT_READ, nextPublishedArtifact
.getOntologyIRI().toOpenRDFURI(), false))
{
// If the authentication succeeded add the artifact
publishedResults.add(nextPublishedArtifact);
}
}
results.put(PoddWebConstants.KEY_PUBLISHED, publishedArtifacts);
}
if(unpublished && this.checkAuthentication(PoddAction.UNPUBLISHED_ARTIFACT_LIST, null, false))
{
this.log.debug("About to check for authentication to look at unpublished artifacts");
this.log.debug("Is authenticated: {}", this.getRequest().getClientInfo().isAuthenticated());
this.log.debug("Current user: {}", this.getRequest().getClientInfo().getUser());
final List<InferredOWLOntologyID> unpublishedResults = new ArrayList<InferredOWLOntologyID>();
final List<InferredOWLOntologyID> unpublishedArtifacts =
this.getPoddArtifactManager().listUnpublishedArtifacts();
for(final InferredOWLOntologyID nextUnpublishedArtifact : unpublishedArtifacts)
{
try
{
if(this.checkAuthentication(PoddAction.UNPUBLISHED_ARTIFACT_READ, nextUnpublishedArtifact
.getOntologyIRI().toOpenRDFURI(), false))
{
// If the authentication succeeded add the artifact
unpublishedResults.add(nextUnpublishedArtifact);
}
}
catch(final ResourceException e)
{
// Ignore this as it should not happen with the
// throwExceptionOnFailure
// parameter set to false.
}
}
results.put(PoddWebConstants.KEY_UNPUBLISHED, unpublishedResults);
}
}
catch(final OpenRDFException e)
{
throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Database exception", e);
}
return results;
}
/**
* Handle http GET request to serve the list artifacts page.
*
* @throws UnmanagedSchemaIRIException
*/
@Get(":html")
public Representation getListArtifactsPage(final Representation entity) throws ResourceException,
UnmanagedSchemaIRIException
{
this.log.debug("@Get listArtifacts Page");
final Map<String, List<InferredOWLOntologyID>> artifactsInternal = this.getArtifactsInternal();
final Map<String, Object> dataModel = RestletUtils.getBaseDataModel(this.getRequest());
dataModel.put("contentTemplate", "projects.html.ftl");
dataModel.put("pageTitle", ListArtifactsResourceImpl.LIST_PAGE_TITLE_TEXT);
// Disable currently unimplemented features
dataModel.put("canFilter", Boolean.FALSE);
dataModel.put("hasFilter", Boolean.FALSE);
if(this.checkAuthentication(PoddAction.ARTIFACT_CREATE, null, false))
{
dataModel.put("userCanCreate", Boolean.TRUE);
}
else
{
dataModel.put("userCanCreate", Boolean.FALSE);
}
this.log.trace("artifacts: {}", artifactsInternal);
for(final Entry<String, List<InferredOWLOntologyID>> nextEntry : artifactsInternal.entrySet())
{
final String nextKey = nextEntry.getKey();
try
{
final List<PoddObjectLabel> results =
this.getPoddArtifactManager().getTopObjectLabels(nextEntry.getValue());
dataModel.put(nextKey + "ArtifactsList", results);
}
catch(final OpenRDFException | SchemaManifestException | UnsupportedRDFormatException | IOException
| UnmanagedArtifactIRIException | UnmanagedArtifactVersionException | RepositoryNotFoundException e)
{
throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not find labels for " + nextKey
+ " artifacts", e);
}
}
// Output the base template, with contentTemplate from the dataModel
// defining the
// template to use for the content in the body of the page
return RestletUtils.getHtmlRepresentation(
this.getPoddApplication().getPropertyUtil()
.get(PoddWebConstants.PROPERTY_TEMPLATE_BASE, PoddWebConstants.DEFAULT_TEMPLATE_BASE),
dataModel, MediaType.TEXT_HTML, this.getPoddApplication().getTemplateConfiguration());
}
@Get(":rdf|rj|json|ttl")
public Representation getListArtifactsRdf(final Representation entity, final Variant variant)
throws ResourceException
{
final Map<String, List<InferredOWLOntologyID>> artifactsInternal = this.getArtifactsInternal();
final RDFFormat resultFormat = Rio.getWriterFormatForMIMEType(variant.getMediaType().getName());
if(resultFormat == null)
{
this.log.error("Could not find an RDF serialiser matching the requested mime-type: "
+ variant.getMediaType().getName());
throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE,
"Could not find an RDF serialiser matching the requested mime-type: "
+ variant.getMediaType().getName());
}
final MediaType resultMediaType = MediaType.valueOf(resultFormat.getDefaultMIMEType());
final ByteArrayOutputStream out = new ByteArrayOutputStream(8096);
final Model model = new LinkedHashModel();
try
{
for(final List<InferredOWLOntologyID> nextArtifacts : artifactsInternal.values())
{
OntologyUtils.ontologyIDsToModel(nextArtifacts, model);
final List<PoddObjectLabel> results = this.getPoddArtifactManager().getTopObjectLabels(nextArtifacts);
for(final PoddObjectLabel nextResult : results)
{
model.add(nextResult.getOntologyID().getOntologyIRI().toOpenRDFURI(),
PODD.PODD_BASE_HAS_TOP_OBJECT, nextResult.getObjectURI());
model.add(nextResult.getObjectURI(), RDFS.LABEL, nextResult.getLabelLiteral());
if(nextResult.getBarcode() != null)
{
model.add(nextResult.getObjectURI(), PODDSCIENCE.HAS_BARCODE, nextResult.getBarcodeLiteral());
}
final List<PoddObjectLabel> typesList =
this.getPoddArtifactManager().getObjectTypes(nextResult.getOntologyID(),
nextResult.getObjectURI());
for(final PoddObjectLabel objectType : typesList)
{
model.add(nextResult.getObjectURI(), RDF.TYPE, objectType.getObjectURI());
model.add(objectType.getObjectURI(), RDFS.LABEL, objectType.getLabelLiteral());
}
}
}
Rio.write(model, out, resultFormat);
}
catch(final OpenRDFException | UnmanagedSchemaIRIException | SchemaManifestException
| UnsupportedRDFormatException | IOException | UnmanagedArtifactIRIException
| UnmanagedArtifactVersionException | RepositoryNotFoundException e)
{
throw new ResourceException(Status.SERVER_ERROR_INTERNAL,
"Could not generate RDF output due to an exception", e);
}
// this.log.info(new String(out.toByteArray(), StandardCharsets.UTF_8));
final ByteArrayRepresentation result = new ByteArrayRepresentation(out.toByteArray(), resultMediaType);
return result;
}
}