Search in sources :

Example 1 with DatasetDescriptionRegistry

use of org.apache.jena.fuseki.build.DatasetDescriptionRegistry in project jena by apache.

the class ActionDatasets method execPostContainer.

// ---- POST 
@Override
protected JsonValue execPostContainer(HttpAction action) {
    JenaUUID uuid = JenaUUID.generate();
    DatasetDescriptionRegistry registry = FusekiServer.registryForBuild();
    ContentType ct = FusekiLib.getContentType(action);
    boolean committed = false;
    // Also acts as a concurrency lock
    system.begin(ReadWrite.WRITE);
    String systemFileCopy = null;
    String configFile = null;
    try {
        // Where to build the templated service/database. 
        Model model = ModelFactory.createDefaultModel();
        StreamRDF dest = StreamRDFLib.graph(model.getGraph());
        if (WebContent.isHtmlForm(ct))
            assemblerFromForm(action, dest);
        else if (WebContent.isMultiPartForm(ct))
            assemblerFromUpload(action, dest);
        else
            assemblerFromBody(action, dest);
        // ----
        // Keep a persistent copy immediately.  This is not used for
        // anything other than being "for the record".
        systemFileCopy = FusekiServer.dirFileArea.resolve(uuid.asString()).toString();
        try (OutputStream outCopy = IO.openOutputFile(systemFileCopy)) {
            RDFDataMgr.write(outCopy, model, Lang.TURTLE);
        }
        // ----
        // Process configuration.
        Statement stmt = getOne(model, null, pServiceName, null);
        if (stmt == null) {
            StmtIterator sIter = model.listStatements(null, pServiceName, (RDFNode) null);
            if (!sIter.hasNext())
                ServletOps.errorBadRequest("No name given in description of Fuseki service");
            sIter.next();
            if (sIter.hasNext())
                ServletOps.errorBadRequest("Multiple names given in description of Fuseki service");
            throw new InternalErrorException("Inconsistent: getOne didn't fail the second time");
        }
        if (!stmt.getObject().isLiteral())
            ServletOps.errorBadRequest("Found " + FmtUtils.stringForRDFNode(stmt.getObject()) + " : Service names are strings, then used to build the external URI");
        Resource subject = stmt.getSubject();
        Literal object = stmt.getObject().asLiteral();
        if (object.getDatatype() != null && !object.getDatatype().equals(XSDDatatype.XSDstring))
            action.log.warn(format("[%d] Service name '%s' is not a string", action.id, FmtUtils.stringForRDFNode(object)));
        String datasetPath;
        {
            // Check the name provided.
            String datasetName = object.getLexicalForm();
            // ---- Check and canonicalize name.
            if (datasetName.isEmpty())
                ServletOps.error(HttpSC.BAD_REQUEST_400, "Empty dataset name");
            if (StringUtils.isBlank(datasetName))
                ServletOps.error(HttpSC.BAD_REQUEST_400, format("Whitespace dataset name: '%s'", datasetName));
            if (datasetName.contains(" "))
                ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name (contains spaces) '%s'", datasetName));
            if (datasetName.equals("/"))
                ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name '%s'", datasetName));
            datasetPath = DataAccessPoint.canonical(datasetName);
        }
        action.log.info(format("[%d] Create database : name = %s", action.id, datasetPath));
        // ---- Check whether it already exists 
        if (action.getDataAccessPointRegistry().isRegistered(datasetPath))
            // And abort.
            ServletOps.error(HttpSC.CONFLICT_409, "Name already registered " + datasetPath);
        configFile = FusekiEnv.generateConfigurationFilename(datasetPath);
        List<String> existing = FusekiEnv.existingConfigurationFile(datasetPath);
        if (!existing.isEmpty())
            ServletOps.error(HttpSC.CONFLICT_409, "Configuration file for '" + datasetPath + "' already exists");
        // Write to configuration directory.
        try (OutputStream outCopy = IO.openOutputFile(configFile)) {
            RDFDataMgr.write(outCopy, model, Lang.TURTLE);
        }
        // Currently do nothing with the system database.
        // In the future ... maybe ...
        //            Model modelSys = system.getNamedModel(gn.getURI()) ;
        //            modelSys.removeAll(null, pStatus, null) ;
        //            modelSys.add(subject, pStatus, FusekiVocab.stateActive) ;
        // Need to be in Resource space at this point.
        DataAccessPoint ref = FusekiBuilder.buildDataAccessPoint(subject, registry);
        action.getDataAccessPointRegistry().register(datasetPath, ref);
        action.getResponse().setContentType(WebContent.contentTypeTextPlain);
        ServletOps.success(action);
        system.commit();
        committed = true;
    } catch (IOException ex) {
        IO.exception(ex);
    } finally {
        if (!committed) {
            if (systemFileCopy != null)
                FileOps.deleteSilent(systemFileCopy);
            if (configFile != null)
                FileOps.deleteSilent(configFile);
            system.abort();
        }
        system.end();
    }
    return null;
}
Also used : ContentType(org.apache.jena.atlas.web.ContentType) OutputStream(java.io.OutputStream) JenaUUID(org.apache.jena.shared.uuid.JenaUUID) InternalErrorException(org.apache.jena.atlas.lib.InternalErrorException) IOException(java.io.IOException) DatasetDescriptionRegistry(org.apache.jena.fuseki.build.DatasetDescriptionRegistry) StreamRDF(org.apache.jena.riot.system.StreamRDF)

Aggregations

IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 InternalErrorException (org.apache.jena.atlas.lib.InternalErrorException)1 ContentType (org.apache.jena.atlas.web.ContentType)1 DatasetDescriptionRegistry (org.apache.jena.fuseki.build.DatasetDescriptionRegistry)1 StreamRDF (org.apache.jena.riot.system.StreamRDF)1 JenaUUID (org.apache.jena.shared.uuid.JenaUUID)1