| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.stanbol.ontologymanager.web.resources; |
| |
| import static javax.ws.rs.core.MediaType.APPLICATION_JSON; |
| import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA; |
| import static javax.ws.rs.core.MediaType.TEXT_HTML; |
| import static javax.ws.rs.core.MediaType.TEXT_PLAIN; |
| import static javax.ws.rs.core.Response.Status.BAD_REQUEST; |
| import static javax.ws.rs.core.Response.Status.CONFLICT; |
| import static javax.ws.rs.core.Response.Status.FORBIDDEN; |
| import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; |
| import static javax.ws.rs.core.Response.Status.NOT_FOUND; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.FUNCTIONAL_OWL; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.MANCHESTER_OWL; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.N3; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.N_TRIPLE; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.OWL_XML; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.RDF_JSON; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.RDF_XML; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.TURTLE; |
| import static org.apache.stanbol.commons.web.base.format.KRFormat.X_TURTLE; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| |
| import javax.servlet.ServletContext; |
| import javax.ws.rs.Consumes; |
| import javax.ws.rs.DELETE; |
| import javax.ws.rs.DefaultValue; |
| import javax.ws.rs.GET; |
| import javax.ws.rs.OPTIONS; |
| import javax.ws.rs.POST; |
| import javax.ws.rs.PUT; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.PathParam; |
| import javax.ws.rs.Produces; |
| import javax.ws.rs.QueryParam; |
| import javax.ws.rs.WebApplicationException; |
| import javax.ws.rs.core.Context; |
| import javax.ws.rs.core.HttpHeaders; |
| import javax.ws.rs.core.MediaType; |
| import javax.ws.rs.core.Response; |
| import javax.ws.rs.core.Response.ResponseBuilder; |
| import javax.ws.rs.core.Response.Status; |
| import javax.ws.rs.core.UriInfo; |
| |
| import org.apache.clerezza.jaxrs.utils.form.FormFile; |
| import org.apache.clerezza.jaxrs.utils.form.MultiPartBody; |
| import org.apache.clerezza.commons.rdf.ImmutableGraph; |
| import org.apache.clerezza.commons.rdf.Graph; |
| import org.apache.clerezza.rdf.core.access.TcProvider; |
| import org.apache.clerezza.rdf.core.serializedform.Parser; |
| import org.apache.clerezza.rdf.core.serializedform.UnsupportedFormatException; |
| import org.apache.felix.scr.annotations.Component; |
| import org.apache.felix.scr.annotations.Property; |
| import org.apache.felix.scr.annotations.Reference; |
| import org.apache.felix.scr.annotations.Service; |
| import org.apache.stanbol.commons.owl.util.OWLUtils; |
| import org.apache.stanbol.commons.owl.util.URIUtils; |
| import org.apache.stanbol.commons.web.viewable.Viewable; |
| import org.apache.stanbol.ontologymanager.registry.api.RegistryManager; |
| import org.apache.stanbol.ontologymanager.registry.api.model.Library; |
| import org.apache.stanbol.ontologymanager.registry.io.LibrarySource; |
| import org.apache.stanbol.ontologymanager.servicesapi.collector.DuplicateIDException; |
| import org.apache.stanbol.ontologymanager.servicesapi.collector.IrremovableOntologyException; |
| import org.apache.stanbol.ontologymanager.servicesapi.collector.OntologyCollectorModificationException; |
| import org.apache.stanbol.ontologymanager.servicesapi.collector.UnmodifiableOntologyCollectorException; |
| import org.apache.stanbol.ontologymanager.servicesapi.io.OntologyInputSource; |
| import org.apache.stanbol.ontologymanager.servicesapi.io.SetInputSource; |
| import org.apache.stanbol.ontologymanager.servicesapi.io.StoredOntologySource; |
| import org.apache.stanbol.ontologymanager.servicesapi.ontology.OntologyLoadingException; |
| import org.apache.stanbol.ontologymanager.servicesapi.ontology.OntologyProvider; |
| import org.apache.stanbol.ontologymanager.servicesapi.scope.OntologySpace; |
| import org.apache.stanbol.ontologymanager.servicesapi.scope.Scope; |
| import org.apache.stanbol.ontologymanager.servicesapi.scope.ScopeManager; |
| import org.apache.stanbol.ontologymanager.servicesapi.util.OntologyUtils; |
| import org.apache.stanbol.ontologymanager.sources.clerezza.GraphContentInputSource; |
| import org.apache.stanbol.ontologymanager.sources.clerezza.GraphSource; |
| import org.apache.stanbol.ontologymanager.sources.owlapi.RootOntologySource; |
| import org.apache.stanbol.ontologymanager.web.util.OntologyPrettyPrintResource; |
| import org.coode.owlapi.manchesterowlsyntax.ManchesterOWLSyntaxOntologyFormat; |
| import org.semanticweb.owlapi.model.IRI; |
| import org.semanticweb.owlapi.model.OWLOntology; |
| import org.semanticweb.owlapi.model.OWLOntologyCreationException; |
| import org.semanticweb.owlapi.model.OWLOntologyID; |
| import org.semanticweb.owlapi.model.OWLOntologyStorageException; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * The REST resource of an OntoNet {@link OntologyScope} whose identifier is known. |
| * |
| * @author alexdma |
| * |
| */ |
| @Component |
| @Service(Object.class) |
| @Property(name = "javax.ws.rs", boolValue = true) |
| @Path("/ontonet/ontology/{scopeid}") |
| public class ScopeResource extends AbstractOntologyAccessResource { |
| |
| private Logger log = LoggerFactory.getLogger(getClass()); |
| |
| /* |
| * Placeholder for the ONManager to be fetched from the servlet context. |
| */ |
| @Reference |
| protected ScopeManager onm; |
| @Reference |
| protected OntologyProvider<TcProvider> ontologyProvider; |
| |
| /* |
| * Placeholder for the RegistryManager to be fetched from the servlet context. |
| */ |
| @Reference |
| protected RegistryManager regMgr; |
| |
| protected Scope scope; |
| |
| public ScopeResource() { |
| super(); |
| // log.info("<init> with scope {}", scopeId); |
| // |
| // this.servletContext = servletContext; |
| // this.onm = (ScopeManager) ContextHelper.getServiceFromContext(ScopeManager.class, servletContext); |
| // this.regMgr = (RegistryManager) ContextHelper.getServiceFromContext(RegistryManager.class, |
| // servletContext); |
| // this.ontologyProvider = (OntologyProvider<TcProvider>) ContextHelper.getServiceFromContext( |
| // OntologyProvider.class, servletContext); |
| |
| // if (scopeId == null || scopeId.isEmpty()) { |
| // log.error("Missing path parameter scopeid={}", scopeId); |
| // throw new WebApplicationException(NOT_FOUND); |
| // } |
| // scope = onm.getScope(scopeId); |
| |
| // // Skip null checks: the scope might be created with a PUT |
| // if (scope == null) { |
| // log.error("Scope {} not found", scopeId); |
| // throw new WebApplicationException(NOT_FOUND); |
| // } |
| } |
| |
| @GET |
| @Produces(value = {APPLICATION_JSON, N3, N_TRIPLE, RDF_JSON}) |
| public Response asOntologyGraph(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context HttpHeaders headers) { |
| |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) return Response.status(NOT_FOUND).build(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| // Export to Clerezza ImmutableGraph, which can be rendered as JSON-LD. |
| ResponseBuilder rb = Response.ok(scope.export(ImmutableGraph.class, merge, prefix)); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Produces(value = {RDF_XML, TURTLE, X_TURTLE}) |
| public Response asOntologyMixed(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) return Response.status(NOT_FOUND).build(); |
| // Export smaller graphs to OWLOntology due to the more human-readable rendering. |
| ResponseBuilder rb; |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| if (merge) rb = Response.ok(scope.export(ImmutableGraph.class, merge, prefix)); |
| else rb = Response.ok(scope.export(OWLOntology.class, merge, prefix)); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Produces(value = {MANCHESTER_OWL, FUNCTIONAL_OWL, OWL_XML, TEXT_PLAIN}) |
| public Response asOntologyOWL(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) return Response.status(NOT_FOUND).build(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| // Export to OWLOntology due to the more human-readable rendering. |
| ResponseBuilder rb = Response.ok(scope.export(OWLOntology.class, merge, prefix)); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @DELETE |
| public Response deregisterScope(@PathParam("scopeid") String scopeid, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers, |
| @Context ServletContext servletContext) { |
| scope = onm.getScope(scopeid); |
| |
| onm.deregisterScope(scope); |
| scope = null; |
| ResponseBuilder rb = Response.ok(); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| public SortedSet<String> getCoreOntologies() { |
| SortedSet<String> result = new TreeSet<String>(); |
| for (OWLOntologyID id : scope.getCoreSpace().listManagedOntologies()) |
| result.add(OntologyUtils.encode(id)); |
| return result; |
| } |
| |
| @GET |
| @Path("/core") |
| @Produces(value = {APPLICATION_JSON, N3, N_TRIPLE, RDF_JSON}) |
| public Response getCoreSpaceGraph(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| OntologySpace space = scope.getCoreSpace(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| ImmutableGraph o = space.export(ImmutableGraph.class, merge, prefix); |
| ResponseBuilder rb = Response.ok(o); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Path("/core") |
| @Produces(value = {RDF_XML, TURTLE, X_TURTLE, MANCHESTER_OWL, FUNCTIONAL_OWL, OWL_XML, TEXT_PLAIN}) |
| public Response getCoreSpaceOWL(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| OntologySpace space = scope.getCoreSpace(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| OWLOntology o = space.export(OWLOntology.class, merge, prefix); |
| ResponseBuilder rb = Response.ok(o); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| private URI getCreatedResource(String ontologyIRI) { |
| return URI.create("/" + ontologyIRI); |
| } |
| |
| public SortedSet<String> getCustomOntologies() { |
| SortedSet<String> result = new TreeSet<String>(); |
| for (OWLOntologyID id : scope.getCustomSpace().listManagedOntologies()) |
| result.add(OntologyUtils.encode(id)); |
| return result; |
| } |
| |
| @GET |
| @Path("/custom") |
| @Produces(value = {APPLICATION_JSON, N3, N_TRIPLE, RDF_JSON}) |
| public Response getCustomSpaceGraph(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| OntologySpace space = scope.getCustomSpace(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| ImmutableGraph o = space.export(ImmutableGraph.class, merge, prefix); |
| ResponseBuilder rb = Response.ok(o); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Path("/custom") |
| @Produces(value = {RDF_XML, TURTLE, X_TURTLE, MANCHESTER_OWL, FUNCTIONAL_OWL, OWL_XML, TEXT_PLAIN}) |
| public Response getCustomSpaceOWL(@PathParam("scopeid") String scopeid, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| scope = onm.getScope(scopeid); |
| |
| OntologySpace space = scope.getCustomSpace(); |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| OWLOntology o = space.export(OWLOntology.class, merge, prefix); |
| ResponseBuilder rb = Response.ok(o); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Produces(TEXT_HTML) |
| public Response getHtmlInfo(@PathParam("scopeid") String scopeid, @Context HttpHeaders headers) { |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) rb = Response.status(NOT_FOUND); |
| else rb = Response.ok(new Viewable("index", this)); // TODO move to a dedicated class |
| rb.header(HttpHeaders.CONTENT_TYPE, TEXT_HTML + "; charset=utf-8"); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| public Set<Library> getLibraries() { |
| return regMgr.getLibraries(); |
| } |
| |
| public SortedSet<String> getManageableOntologies() { |
| SortedSet<String> result = new TreeSet<String>(); |
| // for (String s : ontologyProvider.getPublicKeys()) { |
| // // String s1 = s.split("::")[1]; |
| // if (s != null && !s.isEmpty()) result.add(s); |
| // } |
| for (OWLOntologyID id : ontologyProvider.listPrimaryKeys()) |
| result.add(OntologyUtils.encode(id)); |
| for (OWLOntologyID id : scope.getCoreSpace().listManagedOntologies()) |
| result.remove(OntologyUtils.encode(id)); |
| for (OWLOntologyID id : scope.getCustomSpace().listManagedOntologies()) |
| result.remove(OntologyUtils.encode(id)); |
| return result; |
| } |
| |
| /* |
| * Needed for freemarker |
| */ |
| public Scope getScope() { |
| return scope; |
| } |
| |
| @OPTIONS |
| public Response handleCorsPreflight(@Context HttpHeaders headers) { |
| ResponseBuilder rb = Response.ok(); |
| // enableCORS(servletContext, rb, headers, GET, POST, PUT, DELETE, OPTIONS); |
| return rb.build(); |
| } |
| |
| @OPTIONS |
| @Path("/core") |
| public Response handleCorsPreflightCore(@Context HttpHeaders headers) { |
| ResponseBuilder rb = Response.ok(); |
| // enableCORS(servletContext, rb, headers, GET, OPTIONS); |
| return rb.build(); |
| } |
| |
| @OPTIONS |
| @Path("/custom") |
| public Response handleCorsPreflightCustom(@Context HttpHeaders headers) { |
| ResponseBuilder rb = Response.ok(); |
| // enableCORS(servletContext, rb, headers, GET, OPTIONS); |
| return rb.build(); |
| } |
| |
| @OPTIONS |
| @Path("/{ontologyId:.+}") |
| public Response handleCorsPreflightOntology(@Context HttpHeaders headers) { |
| ResponseBuilder rb = Response.ok(); |
| // enableCORS(servletContext, rb, headers, GET, DELETE, OPTIONS); |
| return rb.build(); |
| } |
| |
| /** |
| * Gets the ontology with the given identifier in its version managed by the session. |
| * |
| * @param sessionId |
| * the session identifier. |
| * @param ontologyId |
| * the ontology identifier. |
| * @param uriInfo |
| * @param headers |
| * @return the requested managed ontology, or {@link Status#NOT_FOUND} if either the sessionn does not |
| * exist, or the if the ontology either does not exist or is not managed. |
| */ |
| @GET |
| @Path("/{ontologyId:.+}") |
| @Produces(value = {APPLICATION_JSON, N3, N_TRIPLE, RDF_JSON}) |
| public Response managedOntologyGetGraph(@PathParam("scopeid") String scopeid, |
| @PathParam("ontologyId") String ontologyId, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| log.debug("Absolute URL Path {}", uriInfo.getRequestUri()); |
| log.debug("Ontology ID {}", ontologyId); |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) rb = Response.status(NOT_FOUND); |
| else { |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| ImmutableGraph o = null; |
| OWLOntologyID id = OntologyUtils.decode(ontologyId); |
| OntologySpace spc = scope.getCustomSpace(); |
| if (spc != null && spc.hasOntology(id)) { |
| o = spc.getOntology(id, ImmutableGraph.class, merge, prefix); |
| } else { |
| spc = scope.getCoreSpace(); |
| if (spc != null && spc.hasOntology(id)) o = spc.getOntology(id, ImmutableGraph.class, merge, prefix); |
| } |
| if (o == null) rb = Response.status(NOT_FOUND); |
| else rb = Response.ok(o); |
| } |
| |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| /** |
| * Gets the ontology with the given identifier in its version managed by the session. |
| * |
| * @param sessionId |
| * the session identifier. |
| * @param ontologyId |
| * the ontology identifier. |
| * @param uriInfo |
| * @param headers |
| * @return the requested managed ontology, or {@link Status#NOT_FOUND} if either the sessionn does not |
| * exist, or the if the ontology either does not exist or is not managed. |
| */ |
| @GET |
| @Path("/{ontologyId:.+}") |
| @Produces(value = {RDF_XML, TURTLE, X_TURTLE, MANCHESTER_OWL, FUNCTIONAL_OWL, OWL_XML, TEXT_PLAIN}) |
| public Response managedOntologyGetOWL(@PathParam("scopeid") String scopeid, |
| @PathParam("ontologyId") String ontologyId, |
| @DefaultValue("false") @QueryParam("merge") boolean merge, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| log.debug("Absolute URL Path {}", uriInfo.getRequestUri()); |
| log.debug("Ontology ID {}", ontologyId); |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| |
| if (scope == null) rb = Response.status(NOT_FOUND); |
| else { |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| OWLOntology o = null; |
| OWLOntologyID id = OntologyUtils.decode(ontologyId); |
| OntologySpace spc = scope.getCustomSpace(); |
| if (spc != null && spc.hasOntology(id)) { |
| o = spc.getOntology(id, OWLOntology.class, merge, prefix); |
| } else { |
| spc = scope.getCoreSpace(); |
| if (spc != null && spc.hasOntology(id)) o = spc.getOntology(id, OWLOntology.class, merge, |
| prefix); |
| } |
| if (o == null) rb = Response.status(NOT_FOUND); |
| else rb = Response.ok(o); |
| } |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @GET |
| @Path("/{ontologyId:.+}") |
| @Produces(TEXT_HTML) |
| public Response managedOntologyShow(@PathParam("scopeid") String scopeid, |
| @PathParam("ontologyId") String ontologyId, |
| @Context HttpHeaders headers) { |
| ResponseBuilder rb; |
| |
| scope = onm.getScope(scopeid); |
| if (scope == null) rb = Response.status(NOT_FOUND); |
| else if (ontologyId == null || ontologyId.isEmpty()) rb = Response.status(BAD_REQUEST); |
| else if (!ontologyProvider.hasOntology(OntologyUtils.decode(ontologyId))) rb = Response |
| .status(NOT_FOUND); |
| else { |
| IRI prefix = IRI.create(getPublicBaseUri() + "ontonet/ontology/"); |
| OWLOntology o = scope.getCustomSpace().getOntology(OntologyUtils.decode(ontologyId), |
| OWLOntology.class, false, prefix); |
| if (o == null) o = scope.getCoreSpace().getOntology(OntologyUtils.decode(ontologyId), |
| OWLOntology.class, false, prefix); |
| if (o == null) rb = Response.status(NOT_FOUND); |
| else try { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| o.getOWLOntologyManager().saveOntology(o, new ManchesterOWLSyntaxOntologyFormat(), out); |
| rb = Response.ok(new Viewable("ontology", |
| new OntologyPrettyPrintResource(uriInfo, out, scope))); |
| } catch (OWLOntologyStorageException e) { |
| throw new WebApplicationException(e, INTERNAL_SERVER_ERROR); |
| } |
| } |
| rb.header(HttpHeaders.CONTENT_TYPE, TEXT_HTML + "; charset=utf-8"); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| /** |
| * Unloads an ontology from an ontology scope. |
| * |
| * @param scopeId |
| * @param ontologyid |
| * @param uriInfo |
| * @param headers |
| */ |
| @DELETE |
| @Path("/{ontologyId:.+}") |
| public Response managedOntologyUnload(@PathParam("scopeid") String scopeid, |
| @PathParam("ontologyId") String ontologyId, |
| @PathParam("scopeid") String scopeId, |
| @Context UriInfo uriInfo, |
| @Context HttpHeaders headers) { |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| if (ontologyId != null && !ontologyId.trim().isEmpty()) { |
| OWLOntologyID id = OntologyUtils.decode(ontologyId); |
| OntologySpace cs = scope.getCustomSpace(); |
| if (!cs.hasOntology(id)) rb = Response.notModified(); // ontology not managed |
| else try { |
| onm.setScopeActive(scopeId, false); |
| cs.removeOntology(id); |
| rb = Response.ok(); |
| } catch (IrremovableOntologyException e) { |
| throw new WebApplicationException(e, FORBIDDEN); |
| } catch (UnmodifiableOntologyCollectorException e) { |
| throw new WebApplicationException(e, FORBIDDEN); |
| } catch (OntologyCollectorModificationException e) { |
| throw new WebApplicationException(e, INTERNAL_SERVER_ERROR); |
| } finally { |
| onm.setScopeActive(scopeId, true); |
| } |
| } else rb = Response.status(BAD_REQUEST); // null/blank ontology ID |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| /** |
| * Tells the scope that it should manage the ontology obtained by parsing the supplied content.<br> |
| * <br> |
| * Note that the PUT method cannot be used, as it is not possible to predict what ID the ontology will |
| * have until it is parsed. |
| * |
| * @param content |
| * the ontology content |
| * @return {@link Status#OK} if the addition was successful, {@link Status#NOT_FOUND} if there is no such |
| * session at all, {@link Status#FORBIDDEN} if the session is locked or cannot modified for some |
| * other reason, {@link Status#INTERNAL_SERVER_ERROR} if some other error occurs. |
| */ |
| @POST |
| @Consumes(value = {RDF_XML, OWL_XML, N_TRIPLE, N3, TURTLE, X_TURTLE, FUNCTIONAL_OWL, MANCHESTER_OWL, |
| RDF_JSON}) |
| public Response manageOntology(InputStream content, |
| @PathParam("scopeid") String scopeid, |
| @Context HttpHeaders headers) { |
| long before = System.currentTimeMillis(); |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| if (scope == null) rb = Response.status(NOT_FOUND); // Always check session first |
| else try { |
| MediaType mt = headers.getMediaType(); |
| log.debug("POST content claimed to be of type {}.", mt); |
| OWLOntologyID key = scope.getCustomSpace().addOntology( |
| /* |
| * For the time being, REST services operate in-memory (i.e. no TcProvider is supplied to the |
| * input source). This means that only the final processed graph is stored. |
| * |
| * TODO : we might find a reason to change that in the future. |
| */ |
| new GraphContentInputSource(content, mt.toString(), ontologyProvider.getStore())); |
| if (key == null || key.isAnonymous()) { |
| log.error("FAILED parse with media type {}.", mt); |
| throw new WebApplicationException(INTERNAL_SERVER_ERROR); |
| } |
| // FIXME ugly but will have to do for the time being |
| log.debug("SUCCESS parse with media type {}.", mt); |
| String uri = // key.split("::")[1]; |
| OntologyUtils.encode(key); |
| // uri = uri.substring((ontologyProvider.getGraphPrefix() + "::").length()); |
| URI created = null; |
| if (uri != null && !uri.isEmpty()) { |
| created = getCreatedResource(uri); |
| rb = Response.created(created); |
| } else rb = Response.ok(); |
| log.info("POST request for ontology addition completed in {} ms.", |
| (System.currentTimeMillis() - before)); |
| log.info("New resource URL is {}", created); |
| } catch (UnmodifiableOntologyCollectorException e) { |
| throw new WebApplicationException(e, FORBIDDEN); |
| } |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| /** |
| * Tells the session that it should manage the ontology obtained by dereferencing the supplied IRI.<br> |
| * <br> |
| * Note that the PUT method cannot be used, as it is not possible to predict what ID the ontology will |
| * have until it is parsed. |
| * |
| * @param content |
| * the ontology physical IRI |
| * @return {@link Status#OK} if the addition was successful, {@link Status#NOT_FOUND} if there is no such |
| * session at all, {@link Status#FORBIDDEN} if the session is locked or cannot modified for some |
| * other reason, {@link Status#INTERNAL_SERVER_ERROR} if some other error occurs. |
| */ |
| @POST |
| @Consumes(value = MediaType.TEXT_PLAIN) |
| public Response manageOntology(String iri, |
| @PathParam("scopeid") String scopeid, |
| @Context HttpHeaders headers) { |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| if (scope == null) rb = Response.status(NOT_FOUND); |
| else try { |
| OWLOntologyID key = scope.getCustomSpace().addOntology(new RootOntologySource(IRI.create(iri))); |
| URI created = getCreatedResource(OntologyUtils.encode(key)); |
| rb = Response.created(created); |
| } catch (UnmodifiableOntologyCollectorException e) { |
| throw new WebApplicationException(e, FORBIDDEN); |
| } catch (OWLOntologyCreationException e) { |
| throw new WebApplicationException(e, INTERNAL_SERVER_ERROR); |
| } |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| @POST |
| @Consumes({MULTIPART_FORM_DATA}) |
| @Produces({TEXT_HTML, TEXT_PLAIN, RDF_XML, TURTLE, X_TURTLE, N3}) |
| public Response postOntology(MultiPartBody data, |
| @PathParam("scopeid") String scopeid, |
| @Context HttpHeaders headers) { |
| log.info(" post(MultiPartBody data) scope: {}", scopeid); |
| ResponseBuilder rb; |
| scope = onm.getScope(scopeid); |
| |
| // TODO remove and make sure it is set across the method |
| rb = Response.status(BAD_REQUEST); |
| |
| IRI location = null, library = null; |
| FormFile file = null; // If found, it takes precedence over location. |
| String format = null; |
| Set<String> keys = new HashSet<String>(); |
| |
| // for (BodyPart bpart : data.getBodyParts()) { |
| // log.debug("is a {}", bpart.getClass()); |
| // if (bpart instanceof FormDataBodyPart) { |
| // FormDataBodyPart dbp = (FormDataBodyPart) bpart; |
| // String name = dbp.getName(); |
| // if (name.equals("file")) file = bpart.getEntityAs(File.class); |
| // else { |
| // String value = dbp.getValue(); |
| // if (name.equals("format") && !value.equals("auto")) format = value; |
| // else if (name.equals("url")) try { |
| // URI.create(value); // To throw 400 if malformed. |
| // location = IRI.create(value); |
| // } catch (Exception ex) { |
| // log.error("Malformed IRI for " + value, ex); |
| // throw new WebApplicationException(ex, BAD_REQUEST); |
| // } |
| // else if (name.equals("library") && !"null".equals(value)) try { |
| // URI.create(value); // To throw 400 if malformed. |
| // library = IRI.create(value); |
| // } catch (Exception ex) { |
| // log.error("Malformed IRI for " + value, ex); |
| // throw new WebApplicationException(ex, BAD_REQUEST); |
| // } |
| // else if (name.equals("stored") && !"null".equals(value)) { |
| // log.info("Request to manage ontology with key {}", value); |
| // keys.add(value); |
| // } |
| // } |
| // |
| // } |
| // } |
| |
| if (data.getFormFileParameterValues("file").length > 0) { |
| file = data.getFormFileParameterValues("file")[0]; |
| } |
| // else { |
| if (data.getTextParameterValues("format").length > 0) { |
| String value = data.getTextParameterValues("format")[0]; |
| if (!value.equals("auto")) { |
| format = value; |
| } |
| } |
| if (data.getTextParameterValues("url").length > 0) { |
| String value = data.getTextParameterValues("url")[0]; |
| try { |
| URI.create(value); // To throw 400 if malformed. |
| location = IRI.create(value); |
| } catch (Exception ex) { |
| log.error("Malformed IRI for param url " + value, ex); |
| throw new WebApplicationException(ex, BAD_REQUEST); |
| } |
| } |
| if (data.getTextParameterValues("library").length > 0) { |
| String value = data.getTextParameterValues("library")[0]; |
| try { |
| URI.create(value); // To throw 400 if malformed. |
| library = IRI.create(value); |
| } catch (Exception ex) { |
| log.error("Malformed IRI for param library " + value, ex); |
| throw new WebApplicationException(ex, BAD_REQUEST); |
| } |
| } |
| if (data.getTextParameterValues("stored").length > 0) { |
| String value = data.getTextParameterValues("stored")[0]; |
| keys.add(value); |
| } |
| |
| log.debug("Parameters:"); |
| log.debug("file: {}", file); |
| log.debug("url: {}", location); |
| log.debug("format: {}", format); |
| log.debug("keys: {}", keys); |
| |
| boolean fileOk = file != null; |
| // if(fileOk && !(file.canRead() && file.exists())){ |
| // log.error("File is not accessible: {}", file); |
| // throw new WebApplicationException(INTERNAL_SERVER_ERROR); |
| // } |
| if (fileOk || location != null || library != null) { // File and location take precedence |
| |
| // src = new GraphContentInputSource(content, format, ontologyProvider.getStore()); |
| |
| // Then add the file |
| OntologyInputSource<?> src = null; |
| if (fileOk) { |
| |
| /* |
| * Because the ontology provider's load method could fail after only one attempt without |
| * resetting the stream, we might have to do that ourselves. |
| */ |
| List<String> formats; |
| if (format != null && !format.trim().isEmpty()) formats = Collections.singletonList(format); |
| else // The RESTful API has its own list of preferred formats |
| formats = Arrays.asList(RDF_XML, TURTLE, X_TURTLE, N3, N_TRIPLE, OWL_XML, |
| FUNCTIONAL_OWL, MANCHESTER_OWL, RDF_JSON); |
| int unsupported = 0, failed = 0; |
| Iterator<String> itf = formats.iterator(); |
| if (!itf.hasNext()) throw new OntologyLoadingException("No suitable format found or defined."); |
| do { |
| String f = itf.next(); |
| try { |
| // Re-instantiate the stream on every attempt |
| InputStream content = new ByteArrayInputStream(file.getContent()); |
| // ClerezzaOWLUtils.guessOntologyID(new FileInputStream(file), Parser.getInstance(), |
| // f); |
| OWLOntologyID guessed = OWLUtils.guessOntologyID(content, Parser.getInstance(), f); |
| log.debug("guessed ontology id: {}", guessed); |
| if (guessed != null && !guessed.isAnonymous() |
| && ontologyProvider.hasOntology(guessed)) { |
| // rb = Response.status(Status.CONFLICT); |
| this.submitted = guessed; |
| if (headers.getAcceptableMediaTypes().contains(MediaType.TEXT_HTML_TYPE)) { |
| rb.entity(new Viewable("conflict.ftl", new ScopeResultData())); |
| rb.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML + "; charset=utf-8"); |
| } |
| break; |
| } else { |
| content = new ByteArrayInputStream(file.getContent()); |
| log.debug("Recreated input stream for format {}", f); |
| src = new GraphContentInputSource(content, f, ontologyProvider.getStore()); |
| } |
| } catch (UnsupportedFormatException e) { |
| log.warn( |
| "POST method failed for media type {}. This should not happen (should fail earlier)", |
| headers.getMediaType()); |
| // rb = Response.status(UNSUPPORTED_MEDIA_TYPE); |
| unsupported++; |
| } catch (IOException e) { |
| log.debug(">>> FAILURE format {} (I/O error)", f); |
| failed++; |
| } catch (Exception e) { // SAXParseException and others |
| log.debug(">>> FAILURE format {} (parse error)", f); |
| failed++; |
| } |
| } while (src == null && itf.hasNext()); |
| } |
| |
| if (src != null) { |
| OWLOntologyID key = scope.getCustomSpace().addOntology(src); |
| if (key == null || key.isAnonymous()) throw new WebApplicationException(INTERNAL_SERVER_ERROR); |
| // FIXME ugly but will have to do for the time being |
| String uri = // key.split("::")[1]; |
| OntologyUtils.encode(key); |
| // uri = uri.substring((ontologyProvider.getGraphPrefix() + "::").length()); |
| if (uri != null && !uri.isEmpty()) { |
| rb = Response.seeOther(URI.create("/ontonet/ontology/" + scope.getID() + "/" + uri)); |
| } else rb = Response.ok(); |
| } else if (rb == null) rb = Response.status(INTERNAL_SERVER_ERROR); |
| } |
| |
| if (!keys.isEmpty()) { |
| for (String key : keys) |
| scope.getCustomSpace().addOntology(new StoredOntologySource(OntologyUtils.decode(key))); |
| rb = Response.seeOther(URI.create("/ontonet/ontology/" + scope.getID())); |
| } |
| // else throw new WebApplicationException(BAD_REQUEST); |
| // rb.header(HttpHeaders.CONTENT_TYPE, TEXT_HTML + "; charset=utf-8"); |
| // FIXME return an appropriate response e.g. 201 |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| /** |
| * At least one between corereg and coreont must be present. Registry iris supersede ontology iris. |
| * |
| * @param scopeid |
| * @param coreRegistry |
| * a. If it is a well-formed IRI it supersedes <code>coreOntology</code>. |
| * @param coreOntologies |
| * @param customRegistry |
| * a. If it is a well-formed IRI it supersedes <code>customOntology</code>. |
| * @param customOntologies |
| * @param activate |
| * if true, the new scope will be activated upon creation. |
| * @param uriInfo |
| * @param headers |
| * @return |
| */ |
| @PUT |
| @Consumes(MediaType.WILDCARD) |
| public Response registerScope(@PathParam("scopeid") String scopeid, |
| @QueryParam("corereg") final List<String> coreRegistries, |
| @QueryParam("coreont") final List<String> coreOntologies, |
| @DefaultValue("false") @QueryParam("activate") boolean activate, |
| @Context HttpHeaders headers) { |
| log.debug("Request URI {}", uriInfo.getRequestUri()); |
| |
| scope = onm.getScope(scopeid); |
| List<OntologyInputSource<?>> srcs = new ArrayList<OntologyInputSource<?>>(coreOntologies.size() |
| + coreRegistries.size()); |
| // First thing, check registry sources. |
| if (coreRegistries != null) for (String reg : coreRegistries) |
| if (reg != null && !reg.isEmpty()) try { |
| // Library IDs are sanitized differently |
| srcs.add(new LibrarySource(URIUtils.desanitize(IRI.create(reg)), regMgr)); |
| } catch (Exception e1) { |
| throw new WebApplicationException(e1, BAD_REQUEST); |
| // Bad or not supplied core registry, try the ontology. |
| } |
| |
| // Then ontology sources |
| if (coreOntologies != null) for (String ont : coreOntologies) |
| if (ont != null && !ont.isEmpty()) try { |
| srcs.add(new RootOntologySource(IRI.create(ont))); |
| } catch (OWLOntologyCreationException e2) { |
| // If this fails too, throw a bad request. |
| throw new WebApplicationException(e2, BAD_REQUEST); |
| } |
| |
| // Now the creation. |
| try { |
| // Expand core sources |
| List<OntologyInputSource<?>> expanded = new ArrayList<OntologyInputSource<?>>(); |
| for (OntologyInputSource<?> coreSrc : srcs) |
| if (coreSrc != null) { |
| if (coreSrc instanceof SetInputSource) { |
| for (Object o : ((SetInputSource<?>) coreSrc).getOntologies()) { |
| OntologyInputSource<?> src = null; |
| if (o instanceof OWLOntology) src = new RootOntologySource((OWLOntology) o); |
| else if (o instanceof Graph) src = new GraphSource( |
| (Graph) o); |
| if (src != null) expanded.add(src); |
| } |
| } else expanded.add(coreSrc); // Must be denoting a single ontology |
| } |
| scope = onm.createOntologyScope(scopeid, expanded.toArray(new OntologyInputSource[0])); |
| // Setup and register the scope. If no custom space was set, it will |
| // still be open for modification. |
| scope.setUp(); |
| onm.setScopeActive(scopeid, activate); |
| } catch (DuplicateIDException e) { |
| throw new WebApplicationException(e, CONFLICT); |
| } catch (Exception ex) { |
| throw new WebApplicationException(ex, INTERNAL_SERVER_ERROR); |
| } |
| |
| ResponseBuilder rb = Response.created(uriInfo.getAbsolutePath()); |
| // addCORSOrigin(servletContext, rb, headers); |
| return rb.build(); |
| } |
| |
| public class ScopeResultData extends ResultData { |
| |
| public OWLOntologyID getRepresentedOntologyKey() { |
| log.info("getRepresentedOntologyKey {}",ScopeResource.this.getRepresentedOntologyKey()); |
| return ScopeResource.this.getRepresentedOntologyKey(); |
| } |
| |
| public String stringForm(OWLOntologyID ontologyID) { |
| return OntologyUtils.encode(ontologyID); |
| } |
| } |
| |
| } |