You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/11/17 17:20:43 UTC

[17/34] jena git commit: Rename FusekiSystem as FusekiWebapp.

Rename FusekiSystem as FusekiWebapp.

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/6e8e0743
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/6e8e0743
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/6e8e0743

Branch: refs/heads/master
Commit: 6e8e07431bffc7e72a1720ac976047a41fc7312f
Parents: f25e410
Author: Andy Seaborne <an...@apache.org>
Authored: Fri Nov 2 18:18:18 2018 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Nov 13 15:39:14 2018 +0000

----------------------------------------------------------------------
 .../org/apache/jena/fuseki/cmd/FusekiCmd.java   |   4 +-
 .../jena/fuseki/mgt/ActionBackupList.java       |   8 +-
 .../apache/jena/fuseki/mgt/ActionDatasets.java  |  14 +-
 .../java/org/apache/jena/fuseki/mgt/Backup.java |   4 +-
 .../apache/jena/fuseki/webapp/FusekiEnv.java    |   2 +-
 .../fuseki/webapp/FusekiServerListener.java     |  10 +-
 .../apache/jena/fuseki/webapp/FusekiSystem.java | 472 -------------------
 .../apache/jena/fuseki/webapp/FusekiWebapp.java | 472 +++++++++++++++++++
 .../fuseki/webapp/ShiroEnvironmentLoader.java   |   2 +-
 .../apache/jena/fuseki/webapp/SystemState.java  |   2 +-
 .../java/org/apache/jena/fuseki/ServerCtl.java  |  14 +-
 .../org/apache/jena/fuseki/TestAdminAPI.java    |   4 +-
 12 files changed, 504 insertions(+), 504 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/cmd/FusekiCmd.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/cmd/FusekiCmd.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/cmd/FusekiCmd.java
index 249e050..a6ee545 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/cmd/FusekiCmd.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/cmd/FusekiCmd.java
@@ -35,7 +35,7 @@ import org.apache.jena.fuseki.server.FusekiInitialConfig ;
 import org.apache.jena.fuseki.system.FusekiLogging;
 import org.apache.jena.fuseki.webapp.FusekiEnv;
 import org.apache.jena.fuseki.webapp.FusekiServerListener;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 import org.apache.jena.query.ARQ ;
 import org.apache.jena.query.Dataset ;
 import org.apache.jena.riot.Lang ;
@@ -224,7 +224,7 @@ public class FusekiCmd {
             if ( ! cmdlineConfigPresent && cmdLineConfig.fusekiCmdLineConfigFile == null ) {
                 // Turn command line argument into an absolute file name.
                 FusekiEnv.setEnvironment();
-                Path cfg = FusekiEnv.FUSEKI_BASE.resolve(FusekiSystem.DFT_CONFIG).toAbsolutePath() ;
+                Path cfg = FusekiEnv.FUSEKI_BASE.resolve(FusekiWebapp.DFT_CONFIG).toAbsolutePath() ;
                 if ( Files.exists(cfg) )
                     cmdLineConfig.fusekiServerConfigFile = cfg.toString() ;
             }

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionBackupList.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionBackupList.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionBackupList.java
index 0dc540d..4f52ccf 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionBackupList.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionBackupList.java
@@ -37,7 +37,7 @@ import org.apache.jena.atlas.json.JsonValue ;
 import org.apache.jena.fuseki.ctl.ActionCtl;
 import org.apache.jena.fuseki.servlets.HttpAction ;
 import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 
 /**
  * A JSON API to list all the backups in the backup directory
@@ -67,11 +67,11 @@ public class ActionBackupList extends ActionCtl {
     } ;
 
     private JsonValue description(HttpAction action) {
-        if ( ! Files.isDirectory(FusekiSystem.dirBackups) )
-            ServletOps.errorOccurred(format("[%d] Backup area '%s' is not a directory", action.id, FusekiSystem.dirBackups)) ;
+        if ( ! Files.isDirectory(FusekiWebapp.dirBackups) )
+            ServletOps.errorOccurred(format("[%d] Backup area '%s' is not a directory", action.id, FusekiWebapp.dirBackups)) ;
         
         List<Path> paths = new ArrayList<>() ;
-        try (DirectoryStream<Path> stream = Files.newDirectoryStream(FusekiSystem.dirBackups, filterVisibleFiles)) {
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(FusekiWebapp.dirBackups, filterVisibleFiles)) {
             stream.forEach(paths::add) ;
         } catch (IOException ex) {
             action.log.error(format("[%d] Backup file list :: IOException :: %s", action.id, ex.getMessage())) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
index dcc7435..1f6e0d2 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
@@ -59,7 +59,7 @@ import org.apache.jena.fuseki.servlets.HttpAction;
 import org.apache.jena.fuseki.servlets.ServletOps;
 import org.apache.jena.fuseki.system.FusekiNetLib;
 import org.apache.jena.fuseki.system.Upload;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 import org.apache.jena.fuseki.webapp.SystemState;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
@@ -160,7 +160,7 @@ public class ActionDatasets extends ActionContainerItem {
             // ----
             // Keep a persistent copy immediately.  This is not used for
             // anything other than being "for the record".
-            systemFileCopy = FusekiSystem.dirFileArea.resolve(uuid.asString()).toString() ;
+            systemFileCopy = FusekiWebapp.dirFileArea.resolve(uuid.asString()).toString() ;
             try ( OutputStream outCopy = IO.openOutputFile(systemFileCopy) ) {
                 RDFDataMgr.write(outCopy, model, Lang.TURTLE) ;
             }
@@ -210,8 +210,8 @@ public class ActionDatasets extends ActionContainerItem {
             
             action.log.info(format("[%d] Create database : name = %s", action.id, datasetPath)) ;
 
-            configFile = FusekiSystem.generateConfigurationFilename(datasetPath) ;
-            List<String> existing = FusekiSystem.existingConfigurationFile(datasetPath) ;
+            configFile = FusekiWebapp.generateConfigurationFilename(datasetPath) ;
+            List<String> existing = FusekiWebapp.existingConfigurationFile(datasetPath) ;
             if ( ! existing.isEmpty() )
                 ServletOps.error(HttpSC.CONFLICT_409, "Configuration file for '"+datasetPath+"' already exists") ;
 
@@ -325,7 +325,7 @@ public class ActionDatasets extends ActionContainerItem {
                 ServletOps.errorNotFound("No such dataset registered: "+name);
             
             String filename = name.startsWith("/") ? name.substring(1) : name;
-            List<String> configurationFiles = FusekiSystem.existingConfigurationFile(filename);
+            List<String> configurationFiles = FusekiWebapp.existingConfigurationFile(filename);
             if  ( configurationFiles.size() != 1 ) {
                 // This should not happen.
                 action.log.warn(format("[%d] There are %d configuration files, not one.", action.id, configurationFiles.size()));
@@ -363,7 +363,7 @@ public class ActionDatasets extends ActionContainerItem {
                 // Delete databases created by the UI, or the admin operation, which are
                 // in predictable, unshared location on disk.
                 // There may not be any database files, the in-memory case.
-                Path pDatabase = FusekiSystem.dirDatabases.resolve(filename);
+                Path pDatabase = FusekiWebapp.dirDatabases.resolve(filename);
                 if ( Files.exists(pDatabase)) {
                     try {
                         if ( Files.isSymbolicLink(pDatabase)) {
@@ -423,7 +423,7 @@ public class ActionDatasets extends ActionContainerItem {
             params.put(Template.NAME, dbName.substring(1)) ;
         else
             params.put(Template.NAME, dbName) ;
-        FusekiSystem.addGlobals(params); 
+        FusekiWebapp.addGlobals(params); 
         
         //action.log.info(format("[%d] Create database : name = %s, type = %s", action.id, dbName, dbType )) ;
         

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/Backup.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/Backup.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/Backup.java
index 4be3604..0e4590a 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/Backup.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/Backup.java
@@ -29,7 +29,7 @@ import org.apache.jena.atlas.lib.DateTimeUtils ;
 import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.fuseki.Fuseki ;
 import org.apache.jena.fuseki.FusekiException ;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 import org.apache.jena.query.ReadWrite ;
 import org.apache.jena.riot.Lang ;
 import org.apache.jena.riot.RDFDataMgr ;
@@ -53,7 +53,7 @@ public class Backup
 
         String timestamp = DateTimeUtils.nowAsString("yyyy-MM-dd_HH-mm-ss") ;
         String filename = ds + "_" + timestamp ;
-        filename = FusekiSystem.dirBackups.resolve(filename).toString() ;
+        filename = FusekiWebapp.dirBackups.resolve(filename).toString() ;
         return filename ;
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiEnv.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiEnv.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiEnv.java
index e725db1..956c4c1 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiEnv.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiEnv.java
@@ -26,7 +26,7 @@ import java.nio.file.Paths ;
  * FusekiLogging can use these values.
  * This code must not touch Jena.  
  * 
- * @see FusekiSystem 
+ * @see FusekiWebapp 
  */ 
 public class FusekiEnv {
     // Initialization logging happens via stdout/stderr directly.

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiServerListener.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiServerListener.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiServerListener.java
index 8c1b5fe..2e1171f 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiServerListener.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiServerListener.java
@@ -76,8 +76,8 @@ public class FusekiServerListener implements ServletContextListener {
         DataAccessPointRegistry.set(servletContext, dataAccessPointRegistry);
         
         try {
-            FusekiSystem.formatBaseArea() ; 
-            if ( ! FusekiSystem.serverInitialized ) {
+            FusekiWebapp.formatBaseArea() ; 
+            if ( ! FusekiWebapp.serverInitialized ) {
                 Fuseki.serverLog.error("Failed to initialize : Server not running") ;
                 return ;
             }
@@ -86,7 +86,7 @@ public class FusekiServerListener implements ServletContextListener {
             // In a non-commandline startup, initialSetup is null. 
             if ( initialSetup == null ) {
                 initialSetup = new FusekiInitialConfig() ;
-                String cfg = FusekiEnv.FUSEKI_BASE.resolve(FusekiSystem.DFT_CONFIG).toAbsolutePath().toString() ;
+                String cfg = FusekiEnv.FUSEKI_BASE.resolve(FusekiWebapp.DFT_CONFIG).toAbsolutePath().toString() ;
                 initialSetup.fusekiServerConfigFile = cfg ;
             }
 
@@ -95,8 +95,8 @@ public class FusekiServerListener implements ServletContextListener {
                 throw new FusekiException("No configuration") ;
             }                
             Fuseki.setVerbose(servletContext, initialSetup.verbose);
-            FusekiSystem.initializeDataAccessPoints(dataAccessPointRegistry,
-                                                    initialSetup, FusekiSystem.dirConfiguration.toString()) ;
+            FusekiWebapp.initializeDataAccessPoints(dataAccessPointRegistry,
+                                                    initialSetup, FusekiWebapp.dirConfiguration.toString()) ;
         } catch (Throwable th) { 
             Fuseki.serverLog.error("Exception in initialization: {}", th.getMessage()) ;
             throw th ;

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiSystem.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiSystem.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiSystem.java
deleted file mode 100644
index e5c4c1f..0000000
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiSystem.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/**
- * 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.jena.fuseki.webapp;
-
-import static java.lang.String.format ;
-
-import java.io.File ;
-import java.io.IOException ;
-import java.io.InputStream ;
-import java.io.StringReader ;
-import java.net.URL ;
-import java.nio.file.DirectoryStream ;
-import java.nio.file.Files ;
-import java.nio.file.Path ;
-import java.nio.file.StandardCopyOption ;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import jena.cmd.CmdException ;
-import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.atlas.lib.FileOps ;
-import org.apache.jena.atlas.lib.InternalErrorException ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiConfigException;
-import org.apache.jena.fuseki.build.DatasetDescriptionRegistry;
-import org.apache.jena.fuseki.build.FusekiBuilder;
-import org.apache.jena.fuseki.build.FusekiConfig;
-import org.apache.jena.fuseki.mgt.Template;
-import org.apache.jena.fuseki.mgt.TemplateFunctions;
-import org.apache.jena.fuseki.server.DataAccessPoint;
-import org.apache.jena.fuseki.server.DataAccessPointRegistry;
-import org.apache.jena.fuseki.server.DataService;
-import org.apache.jena.fuseki.server.FusekiInitialConfig;
-import org.apache.jena.fuseki.server.FusekiVocab;
-import org.apache.jena.fuseki.servlets.HttpAction ;
-import org.apache.jena.fuseki.servlets.ServletOps ;
-import org.apache.jena.rdf.model.* ;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFDataMgr ;
-import org.apache.jena.riot.RDFLanguages ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.assembler.AssemblerUtils;
-import org.apache.jena.tdb.sys.Names ;
-
-public class FusekiSystem
-{
-    // Initialization of FUSEKI_HOME and FUSEKI_BASE is done in FusekiEnv.setEnvironment()
-    // so that the code is independent of any logging.  FusekiLogging can use
-    // initialized values of FUSEKI_BASE while looking forlog4j configuration.
-    
-    /* * Root of the Fuseki installation for fixed files. 
-     * This may be null (e.g. running inside a web application container) */ 
-    //public static Path FUSEKI_HOME = null ;
-    
-    /* * Root of the varying files in this deployment. Often $FUSEKI_HOME/run.
-     * This is not null - it may be /etc/fuseki, which must be writable.
-     */ 
-    //public static Path FUSEKI_BASE = null ;
-    
-    // Relative names of directories in the FUSEKI_BASE area.
-    public static final String     runArea                  = FusekiEnv.ENV_runArea ;
-    public static final String     databasesLocationBase    = "databases" ;
-    // Place to put Lucene text and spatial indexes.
-    //private static final String        databaseIndexesDir       = "indexes" ;
-      
-    public static final String     backupDirNameBase        = "backups" ;
-    public static final String     configDirNameBase        = "configuration" ;
-    public static final String     logsNameBase             = "logs" ;
-    public static final String     systemDatabaseNameBase   = "system" ;
-    public static final String     systemFileAreaBase       = "system_files" ;
-    public static final String     templatesNameBase        = "templates" ;
-    // This name is in web.xml as well.
-    public static final String     DFT_SHIRO_INI            = "shiro.ini" ; 
-    // In FUSEKI_BASE
-    public static final String     DFT_CONFIG               = "config.ttl" ;
-    
-    /** Directory for TDB databases - this is known to the assembler templates */
-    public static Path        dirDatabases       = null ;
-    
-    /** Directory for writing backups */
-    public static Path        dirBackups         = null ;
-
-    /** Directory for assembler files */
-    public static Path        dirConfiguration   = null ;
-    
-    /** Directory for assembler files */
-    public static Path        dirLogs            = null ;
-
-    /** Directory for system database */
-    public static Path        dirSystemDatabase  = null ;
-
-    /** Directory for files uploaded (e.g upload assembler descriptions); not data uploads. */
-    public static Path        dirFileArea        = null ;
-    
-    /** Directory for assembler files */
-    public static Path        dirTemplates       = null ;
-
-    private static boolean    initialized        = false ;
-    // Marks the end of successful initialization.
-    /*package*/static boolean serverInitialized  = false ;
-
-    /*package*/ synchronized static void formatBaseArea() {
-        if ( initialized )
-            return ;
-        initialized = true ;
-        try {
-            FusekiEnv.setEnvironment() ;
-            Path FUSEKI_HOME = FusekiEnv.FUSEKI_HOME ;
-            Path FUSEKI_BASE = FusekiEnv.FUSEKI_BASE ;
-            
-            Fuseki.init() ;
-            Fuseki.configLog.info("FUSEKI_HOME="+ ((FUSEKI_HOME==null) ? "unset" : FUSEKI_HOME.toString())) ;
-            Fuseki.configLog.info("FUSEKI_BASE="+FUSEKI_BASE.toString());
-
-            // ----  Check FUSEKI_HOME and FUSEKI_BASE
-            // If FUSEKI_HOME exists, it may be FUSEKI_BASE.
-
-            if ( FUSEKI_HOME != null ) {
-                if ( ! Files.isDirectory(FUSEKI_HOME) )
-                    throw new FusekiConfigException("FUSEKI_HOME is not a directory: "+FUSEKI_HOME) ;
-                if ( ! Files.isReadable(FUSEKI_HOME) )
-                    throw new FusekiConfigException("FUSEKI_HOME is not readable: "+FUSEKI_HOME) ;
-            }
-
-            if ( Files.exists(FUSEKI_BASE) ) {
-                if ( ! Files.isDirectory(FUSEKI_BASE) )
-                    throw new FusekiConfigException("FUSEKI_BASE is not a directory: "+FUSEKI_BASE) ;
-                if ( ! Files.isWritable(FUSEKI_BASE) )
-                    throw new FusekiConfigException("FUSEKI_BASE is not writable: "+FUSEKI_BASE) ;
-            } else {
-                ensureDir(FUSEKI_BASE);
-            }
-
-            // Ensure FUSEKI_BASE has the assumed directories.
-            dirTemplates        = writeableDirectory(FUSEKI_BASE, templatesNameBase) ;
-            dirDatabases        = writeableDirectory(FUSEKI_BASE, databasesLocationBase) ;
-            dirBackups          = writeableDirectory(FUSEKI_BASE, backupDirNameBase) ;
-            dirConfiguration    = writeableDirectory(FUSEKI_BASE, configDirNameBase) ;
-            dirLogs             = writeableDirectory(FUSEKI_BASE, logsNameBase) ;
-            dirSystemDatabase   = writeableDirectory(FUSEKI_BASE, systemDatabaseNameBase) ;
-            dirFileArea         = writeableDirectory(FUSEKI_BASE, systemFileAreaBase) ;
-            //Possible intercept point
-
-            // ---- Initialize with files.
-
-            if ( Files.isRegularFile(FUSEKI_BASE) ) 
-                throw new FusekiConfigException("FUSEKI_BASE exists but is a file") ;
-
-            // Copy missing files into FUSEKI_BASE
-            copyFileIfMissing(null, DFT_SHIRO_INI, FUSEKI_BASE) ;
-            copyFileIfMissing(null, DFT_CONFIG, FUSEKI_BASE) ;
-            for ( String n : Template.templateNames ) {
-                copyFileIfMissing(null, n, FUSEKI_BASE) ;
-            }
-
-            serverInitialized = true ;
-        } catch (RuntimeException ex) {
-            Fuseki.serverLog.error("Exception in server initialization", ex) ;
-            throw ex ;
-        }
-    }
-    
-    /** Copy a file from src to dst under name fn.
-     * If src is null, try as a classpath resource
-     * @param src   Source directory, or null meaning use java resource. 
-     * @param fn    File name, a relative path.
-     * @param dst   Destination directory.
-     * 
-     */
-    private static void copyFileIfMissing(Path src, String fn, Path dst) {
-        
-        Path dstFile = dst.resolve(fn) ;
-        if ( Files.exists(dstFile) )
-            return ;
-        
-        // fn may be a path.
-        if ( src != null ) {
-            try {
-                Files.copy(src.resolve(fn), dstFile, StandardCopyOption.COPY_ATTRIBUTES) ;
-            } catch (IOException e) {
-                IO.exception("Failed to copy file "+src.resolve(fn), e);
-                e.printStackTrace();
-            }
-        } else {
-            copyFileFromResource(fn, dstFile);
-        }
-    }
-    
-    public static void copyFileFromResource(String fn, Path dstFile) {
-        try {
-            // Get from the file from area "org/apache/jena/fuseki/server"  (our package)
-            URL url = FusekiSystem.class.getResource(fn) ;
-            if ( url == null )
-                throw new FusekiConfigException("Failed to find resource '"+fn+"'") ; 
-            InputStream in = url.openStream() ;
-            Files.copy(in, dstFile) ;
-        }
-        catch (IOException e) {
-            IO.exception("Failed to copy file from resource: "+fn, e);
-            e.printStackTrace();
-        }
-    }
-
-    public static void initializeDataAccessPoints(DataAccessPointRegistry registry, FusekiInitialConfig initialSetup, String configDir) {
-        List<DataAccessPoint> configFileDBs = initServerConfiguration(initialSetup) ;
-        List<DataAccessPoint> directoryDBs =  FusekiConfig.readConfigurationDirectory(configDir) ;
-        List<DataAccessPoint> systemDBs =     FusekiConfig.readSystemDatabase(SystemState.getDataset()) ;
-        
-        List<DataAccessPoint> datapoints = new ArrayList<>() ;
-        datapoints.addAll(configFileDBs) ;
-        datapoints.addAll(directoryDBs) ;
-        datapoints.addAll(systemDBs) ;
-        
-        // Having found them, set them all running.
-        enable(registry, datapoints);
-    }
-
-    private static void enable(DataAccessPointRegistry registry, List<DataAccessPoint> datapoints) {
-        for ( DataAccessPoint dap : datapoints ) {
-            Fuseki.configLog.info("Register: "+dap.getName()) ;
-            dap.getDataService().goActive();
-            registry.register(dap);
-        }
-    }
-
-    private static List<DataAccessPoint> initServerConfiguration(FusekiInitialConfig params) { 
-        // Has a side effect of global context setting
-        // when processing a config file.
-        // Compatibility.
-        
-        List<DataAccessPoint> datasets = new ArrayList<>();
-        if ( params == null )
-            return datasets ;
-
-        if ( params.fusekiCmdLineConfigFile != null ) {
-            List<DataAccessPoint> confDatasets = processServerConfigFile(params.fusekiCmdLineConfigFile) ;
-            datasets.addAll(confDatasets) ;
-        }
-        else if ( params.fusekiServerConfigFile != null ) {
-            List<DataAccessPoint> confDatasets = processServerConfigFile(params.fusekiServerConfigFile) ;
-            datasets.addAll(confDatasets) ;
-        }
-        else if ( params.dsg != null ) {
-            DataAccessPoint dap = datasetDefaultConfiguration(params.datasetPath, params.dsg, params.allowUpdate) ;
-            datasets.add(dap) ;
-        } else if ( params.argTemplateFile != null ) {
-            DataAccessPoint dap = configFromTemplate(params.argTemplateFile, params.datasetPath, params.allowUpdate, params.params) ;
-            datasets.add(dap) ;
-        }
-        // No datasets is valid.
-        return datasets ;
-    }
-    
-    private static List<DataAccessPoint> processServerConfigFile(String configFilename) {
-        if ( ! FileOps.exists(configFilename) ) {
-            Fuseki.configLog.warn("Configuration file '" + configFilename+"' does not exist") ;
-            return Collections.emptyList(); 
-        }
-        Fuseki.configLog.info("Configuration file: " + configFilename) ;
-        //return FusekiConfig.readServerConfigFile(configFilename);
-        Model model = AssemblerUtils.readAssemblerFile(configFilename) ;
-        if ( model.size() == 0 )
-            return Collections.emptyList() ;
-        FusekiConfig.processServerConfig(model);
-        return FusekiConfig.servicesAndDatasets(model) ;
-    }
-    
-    private static DataAccessPoint configFromTemplate(String templateFile, String datasetPath, 
-                                                      boolean allowUpdate, Map<String, String> params) {
-        DatasetDescriptionRegistry registry = new DatasetDescriptionRegistry() ; 
-        // ---- Setup
-        if ( params == null ) {
-            params = new HashMap<>() ;
-            params.put(Template.NAME, datasetPath) ;
-        } else {
-            if ( ! params.containsKey(Template.NAME) ) {
-                Fuseki.configLog.warn("No NAME found in template parameters (added)") ;
-                params.put(Template.NAME, datasetPath) ;   
-            }
-        }
-        //-- Logging
-        Fuseki.configLog.info("Template file: " + templateFile) ;
-        String dir = params.get(Template.DIR) ;
-        if ( dir != null ) {
-            if ( Objects.equals(dir, Names.memName) ) {
-                Fuseki.configLog.info("TDB dataset: in-memory") ;
-            } else {
-                if ( !FileOps.exists(dir) )
-                    throw new CmdException("Directory not found: " + dir) ;
-                Fuseki.configLog.info("TDB dataset: directory=" + dir) ;
-            }
-        }
-        //-- Logging
-        
-        datasetPath = DataAccessPoint.canonical(datasetPath) ;
-        
-        // DRY -- ActionDatasets (and others?)
-        addGlobals(params); 
-
-        String str = TemplateFunctions.templateFile(templateFile, params, Lang.TTL) ;
-        Lang lang = RDFLanguages.filenameToLang(str, Lang.TTL) ;
-        StringReader sr =  new StringReader(str) ;
-        Model model = ModelFactory.createDefaultModel() ;
-        RDFDataMgr.read(model, sr, datasetPath, lang);
-        
-        // ---- DataAccessPoint
-        Statement stmt = getOne(model, null, FusekiVocab.pServiceName, null) ;
-        if ( stmt == null ) {
-            StmtIterator sIter = model.listStatements(null, FusekiVocab.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") ;
-        }
-        Resource subject = stmt.getSubject() ;
-        if ( ! allowUpdate ) {
-            // Opportunity for more sophisticated "read-only" mode.
-            //  1 - clean model, remove "fu:serviceUpdate", "fu:serviceUpload", "fu:serviceReadGraphStore", "fu:serviceReadWriteGraphStore"
-            //  2 - set a flag on DataAccessPoint
-        }
-        DataAccessPoint dap = FusekiConfig.buildDataAccessPoint(subject, registry) ;
-        return dap ;
-    }
-    
-    public static void addGlobals(Map<String, String> params) {
-        if ( params == null ) {
-            Fuseki.configLog.warn("FusekiServer.addGlobals : params is null", new Throwable()) ;
-            return ;
-        }
-        
-        if ( ! params.containsKey("FUSEKI_BASE") )
-            params.put("FUSEKI_BASE", pathStringOrElse(FusekiEnv.FUSEKI_BASE, "unset")) ;
-        if ( ! params.containsKey("FUSEKI_HOME") )
-            params.put("FUSEKI_HOME", pathStringOrElse(FusekiEnv.FUSEKI_HOME, "unset")) ;
-    }
-
-    private static String pathStringOrElse(Path path, String dft) {
-        if ( path == null )
-            return dft ;
-        return path.toString() ;
-    }
-    
-    // DRY -- ActionDatasets (and others?)
-    private static Statement getOne(Model m, Resource s, Property p, RDFNode o) {
-        StmtIterator iter = m.listStatements(s, p, o) ;
-        if ( ! iter.hasNext() )
-            return null ;
-        Statement stmt = iter.next() ;
-        if ( iter.hasNext() )
-            return null ;
-        return stmt ;
-    }
-    
-    private static DataAccessPoint datasetDefaultConfiguration( String name, DatasetGraph dsg, boolean allowUpdate) {
-        name = DataAccessPoint.canonical(name) ;
-        DataService ds = FusekiBuilder.buildDataServiceStd(dsg, allowUpdate) ;
-        DataAccessPoint dap = new DataAccessPoint(name, ds) ;
-        return dap ;
-    }
-    
-    // ---- Helpers
-
-    /** Ensure a directory exists, creating it if necessary.
-     */
-    private static void ensureDir(Path directory) {
-        File dir = directory.toFile() ;
-        if ( ! dir.exists() ) {
-            boolean b = dir.mkdirs() ;
-            if ( ! b )
-                throw new FusekiConfigException("Failed to create directory: "+directory) ;
-        }
-        else if ( ! dir.isDirectory())
-            throw new FusekiConfigException("Not a directory: "+directory) ;
-    }
-
-    private static void mustExist(Path directory) {
-        File dir = directory.toFile() ;
-        if ( ! dir.exists() )
-            throw new FusekiConfigException("Does not exist: "+directory) ; 
-        if ( ! dir.isDirectory())
-            throw new FusekiConfigException("Not a directory: "+directory) ;
-    }
-    
-    private static boolean emptyDir(Path dir) {
-        return dir.toFile().list().length <= 2 ;
-    }
-    
-    private static boolean exists(Path directory) {
-        File dir = directory.toFile() ;
-        return dir.exists() ;
-    }
-
-    private static Path writeableDirectory(Path root , String relName ) {
-        Path p = makePath(root, relName) ;
-        ensureDir(p);
-        if ( ! Files.isWritable(p) )
-            throw new FusekiConfigException("Not writable: "+p) ;
-        return p ;
-    }
-    
-    private static Path makePath(Path root , String relName ) {
-        Path path = root.resolve(relName) ;
-        // Must exist
-//        try { path = path.toRealPath() ; }
-//        catch (IOException e) { IO.exception(e) ; }
-        return path ;
-    }
-
-    /**
-     * Dataset set name to configuration file name. Return a configuration file name -
-     * existing one or ".ttl" form if new
-     */
-    public static String datasetNameToConfigurationFile(HttpAction action, String dsName) {
-        List<String> existing = existingConfigurationFile(dsName) ;
-        if ( ! existing.isEmpty() ) {
-            if ( existing.size() > 1 ) {
-                action.log.warn(format("[%d] Multiple existing configuration files for %s : %s",
-                                       action.id, dsName, existing));
-                ServletOps.errorBadRequest("Multiple existing configuration files for "+dsName);
-                return null ;
-            }
-            return existing.get(0).toString() ;
-        }
-        
-        return generateConfigurationFilename(dsName) ;
-    }
-
-    /** New configuration file name - absiolute filename */
-    public static String generateConfigurationFilename(String dsName) {
-        String filename = dsName ;
-        // Without "/"
-        if ( filename.startsWith("/"))
-            filename = filename.substring(1) ;
-        Path p = FusekiSystem.dirConfiguration.resolve(filename+".ttl") ;
-        return p.toString();
-    }
-
-    /** Return the filenames of all matching files in the configuration directory (absolute paths returned ). */  
-    public static List<String> existingConfigurationFile(String baseFilename) {
-        try { 
-            List<String> paths = new ArrayList<>() ;
-            try (DirectoryStream<Path> stream = Files.newDirectoryStream(FusekiSystem.dirConfiguration, baseFilename+".*") ) {
-                stream.forEach((p)-> paths.add(FusekiSystem.dirConfiguration.resolve(p).toString() ));
-            }
-            return paths ;
-        } catch (IOException ex) {
-            throw new InternalErrorException("Failed to read configuration directory "+FusekiSystem.dirConfiguration) ;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
new file mode 100644
index 0000000..b85f679
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
@@ -0,0 +1,472 @@
+/**
+ * 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.jena.fuseki.webapp;
+
+import static java.lang.String.format ;
+
+import java.io.File ;
+import java.io.IOException ;
+import java.io.InputStream ;
+import java.io.StringReader ;
+import java.net.URL ;
+import java.nio.file.DirectoryStream ;
+import java.nio.file.Files ;
+import java.nio.file.Path ;
+import java.nio.file.StandardCopyOption ;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import jena.cmd.CmdException ;
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.lib.FileOps ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.fuseki.Fuseki ;
+import org.apache.jena.fuseki.FusekiConfigException;
+import org.apache.jena.fuseki.build.DatasetDescriptionRegistry;
+import org.apache.jena.fuseki.build.FusekiBuilder;
+import org.apache.jena.fuseki.build.FusekiConfig;
+import org.apache.jena.fuseki.mgt.Template;
+import org.apache.jena.fuseki.mgt.TemplateFunctions;
+import org.apache.jena.fuseki.server.DataAccessPoint;
+import org.apache.jena.fuseki.server.DataAccessPointRegistry;
+import org.apache.jena.fuseki.server.DataService;
+import org.apache.jena.fuseki.server.FusekiInitialConfig;
+import org.apache.jena.fuseki.server.FusekiVocab;
+import org.apache.jena.fuseki.servlets.HttpAction ;
+import org.apache.jena.fuseki.servlets.ServletOps ;
+import org.apache.jena.rdf.model.* ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.RDFLanguages ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.assembler.AssemblerUtils;
+import org.apache.jena.tdb.sys.Names ;
+
+public class FusekiWebapp
+{
+    // Initialization of FUSEKI_HOME and FUSEKI_BASE is done in FusekiEnv.setEnvironment()
+    // so that the code is independent of any logging.  FusekiLogging can use
+    // initialized values of FUSEKI_BASE while looking forlog4j configuration.
+    
+    /* * Root of the Fuseki installation for fixed files. 
+     * This may be null (e.g. running inside a web application container) */ 
+    //public static Path FUSEKI_HOME = null ;
+    
+    /* * Root of the varying files in this deployment. Often $FUSEKI_HOME/run.
+     * This is not null - it may be /etc/fuseki, which must be writable.
+     */ 
+    //public static Path FUSEKI_BASE = null ;
+    
+    // Relative names of directories in the FUSEKI_BASE area.
+    public static final String     runArea                  = FusekiEnv.ENV_runArea ;
+    public static final String     databasesLocationBase    = "databases" ;
+    // Place to put Lucene text and spatial indexes.
+    //private static final String        databaseIndexesDir       = "indexes" ;
+      
+    public static final String     backupDirNameBase        = "backups" ;
+    public static final String     configDirNameBase        = "configuration" ;
+    public static final String     logsNameBase             = "logs" ;
+    public static final String     systemDatabaseNameBase   = "system" ;
+    public static final String     systemFileAreaBase       = "system_files" ;
+    public static final String     templatesNameBase        = "templates" ;
+    // This name is in web.xml as well.
+    public static final String     DFT_SHIRO_INI            = "shiro.ini" ; 
+    // In FUSEKI_BASE
+    public static final String     DFT_CONFIG               = "config.ttl" ;
+    
+    /** Directory for TDB databases - this is known to the assembler templates */
+    public static Path        dirDatabases       = null ;
+    
+    /** Directory for writing backups */
+    public static Path        dirBackups         = null ;
+
+    /** Directory for assembler files */
+    public static Path        dirConfiguration   = null ;
+    
+    /** Directory for assembler files */
+    public static Path        dirLogs            = null ;
+
+    /** Directory for system database */
+    public static Path        dirSystemDatabase  = null ;
+
+    /** Directory for files uploaded (e.g upload assembler descriptions); not data uploads. */
+    public static Path        dirFileArea        = null ;
+    
+    /** Directory for assembler files */
+    public static Path        dirTemplates       = null ;
+
+    private static boolean    initialized        = false ;
+    // Marks the end of successful initialization.
+    /*package*/static boolean serverInitialized  = false ;
+
+    /*package*/ synchronized static void formatBaseArea() {
+        if ( initialized )
+            return ;
+        initialized = true ;
+        try {
+            FusekiEnv.setEnvironment() ;
+            Path FUSEKI_HOME = FusekiEnv.FUSEKI_HOME ;
+            Path FUSEKI_BASE = FusekiEnv.FUSEKI_BASE ;
+            
+            Fuseki.init() ;
+            Fuseki.configLog.info("FUSEKI_HOME="+ ((FUSEKI_HOME==null) ? "unset" : FUSEKI_HOME.toString())) ;
+            Fuseki.configLog.info("FUSEKI_BASE="+FUSEKI_BASE.toString());
+
+            // ----  Check FUSEKI_HOME and FUSEKI_BASE
+            // If FUSEKI_HOME exists, it may be FUSEKI_BASE.
+
+            if ( FUSEKI_HOME != null ) {
+                if ( ! Files.isDirectory(FUSEKI_HOME) )
+                    throw new FusekiConfigException("FUSEKI_HOME is not a directory: "+FUSEKI_HOME) ;
+                if ( ! Files.isReadable(FUSEKI_HOME) )
+                    throw new FusekiConfigException("FUSEKI_HOME is not readable: "+FUSEKI_HOME) ;
+            }
+
+            if ( Files.exists(FUSEKI_BASE) ) {
+                if ( ! Files.isDirectory(FUSEKI_BASE) )
+                    throw new FusekiConfigException("FUSEKI_BASE is not a directory: "+FUSEKI_BASE) ;
+                if ( ! Files.isWritable(FUSEKI_BASE) )
+                    throw new FusekiConfigException("FUSEKI_BASE is not writable: "+FUSEKI_BASE) ;
+            } else {
+                ensureDir(FUSEKI_BASE);
+            }
+
+            // Ensure FUSEKI_BASE has the assumed directories.
+            dirTemplates        = writeableDirectory(FUSEKI_BASE, templatesNameBase) ;
+            dirDatabases        = writeableDirectory(FUSEKI_BASE, databasesLocationBase) ;
+            dirBackups          = writeableDirectory(FUSEKI_BASE, backupDirNameBase) ;
+            dirConfiguration    = writeableDirectory(FUSEKI_BASE, configDirNameBase) ;
+            dirLogs             = writeableDirectory(FUSEKI_BASE, logsNameBase) ;
+            dirSystemDatabase   = writeableDirectory(FUSEKI_BASE, systemDatabaseNameBase) ;
+            dirFileArea         = writeableDirectory(FUSEKI_BASE, systemFileAreaBase) ;
+            //Possible intercept point
+
+            // ---- Initialize with files.
+
+            if ( Files.isRegularFile(FUSEKI_BASE) ) 
+                throw new FusekiConfigException("FUSEKI_BASE exists but is a file") ;
+
+            // Copy missing files into FUSEKI_BASE
+            copyFileIfMissing(null, DFT_SHIRO_INI, FUSEKI_BASE) ;
+            copyFileIfMissing(null, DFT_CONFIG, FUSEKI_BASE) ;
+            for ( String n : Template.templateNames ) {
+                copyFileIfMissing(null, n, FUSEKI_BASE) ;
+            }
+
+            serverInitialized = true ;
+        } catch (RuntimeException ex) {
+            Fuseki.serverLog.error("Exception in server initialization", ex) ;
+            throw ex ;
+        }
+    }
+    
+    /** Copy a file from src to dst under name fn.
+     * If src is null, try as a classpath resource
+     * @param src   Source directory, or null meaning use java resource. 
+     * @param fn    File name, a relative path.
+     * @param dst   Destination directory.
+     * 
+     */
+    private static void copyFileIfMissing(Path src, String fn, Path dst) {
+        
+        Path dstFile = dst.resolve(fn) ;
+        if ( Files.exists(dstFile) )
+            return ;
+        
+        // fn may be a path.
+        if ( src != null ) {
+            try {
+                Files.copy(src.resolve(fn), dstFile, StandardCopyOption.COPY_ATTRIBUTES) ;
+            } catch (IOException e) {
+                IO.exception("Failed to copy file "+src.resolve(fn), e);
+                e.printStackTrace();
+            }
+        } else {
+            copyFileFromResource(fn, dstFile);
+        }
+    }
+    
+    public static void copyFileFromResource(String fn, Path dstFile) {
+        try {
+            // Get from the file from area "org/apache/jena/fuseki/server"  (our package)
+            URL url = FusekiWebapp.class.getResource(fn) ;
+            if ( url == null )
+                throw new FusekiConfigException("Failed to find resource '"+fn+"'") ; 
+            InputStream in = url.openStream() ;
+            Files.copy(in, dstFile) ;
+        }
+        catch (IOException e) {
+            IO.exception("Failed to copy file from resource: "+fn, e);
+            e.printStackTrace();
+        }
+    }
+
+    public static void initializeDataAccessPoints(DataAccessPointRegistry registry, FusekiInitialConfig initialSetup, String configDir) {
+        List<DataAccessPoint> configFileDBs = initServerConfiguration(initialSetup) ;
+        List<DataAccessPoint> directoryDBs =  FusekiConfig.readConfigurationDirectory(configDir) ;
+        List<DataAccessPoint> systemDBs =     FusekiConfig.readSystemDatabase(SystemState.getDataset()) ;
+        
+        List<DataAccessPoint> datapoints = new ArrayList<>() ;
+        datapoints.addAll(configFileDBs) ;
+        datapoints.addAll(directoryDBs) ;
+        datapoints.addAll(systemDBs) ;
+        
+        // Having found them, set them all running.
+        enable(registry, datapoints);
+    }
+
+    private static void enable(DataAccessPointRegistry registry, List<DataAccessPoint> datapoints) {
+        for ( DataAccessPoint dap : datapoints ) {
+            Fuseki.configLog.info("Register: "+dap.getName()) ;
+            dap.getDataService().goActive();
+            registry.register(dap);
+        }
+    }
+
+    private static List<DataAccessPoint> initServerConfiguration(FusekiInitialConfig params) { 
+        // Has a side effect of global context setting
+        // when processing a config file.
+        // Compatibility.
+        
+        List<DataAccessPoint> datasets = new ArrayList<>();
+        if ( params == null )
+            return datasets ;
+
+        if ( params.fusekiCmdLineConfigFile != null ) {
+            List<DataAccessPoint> confDatasets = processServerConfigFile(params.fusekiCmdLineConfigFile) ;
+            datasets.addAll(confDatasets) ;
+        }
+        else if ( params.fusekiServerConfigFile != null ) {
+            List<DataAccessPoint> confDatasets = processServerConfigFile(params.fusekiServerConfigFile) ;
+            datasets.addAll(confDatasets) ;
+        }
+        else if ( params.dsg != null ) {
+            DataAccessPoint dap = datasetDefaultConfiguration(params.datasetPath, params.dsg, params.allowUpdate) ;
+            datasets.add(dap) ;
+        } else if ( params.argTemplateFile != null ) {
+            DataAccessPoint dap = configFromTemplate(params.argTemplateFile, params.datasetPath, params.allowUpdate, params.params) ;
+            datasets.add(dap) ;
+        }
+        // No datasets is valid.
+        return datasets ;
+    }
+    
+    private static List<DataAccessPoint> processServerConfigFile(String configFilename) {
+        if ( ! FileOps.exists(configFilename) ) {
+            Fuseki.configLog.warn("Configuration file '" + configFilename+"' does not exist") ;
+            return Collections.emptyList(); 
+        }
+        Fuseki.configLog.info("Configuration file: " + configFilename) ;
+        //return FusekiConfig.readServerConfigFile(configFilename);
+        Model model = AssemblerUtils.readAssemblerFile(configFilename) ;
+        if ( model.size() == 0 )
+            return Collections.emptyList() ;
+        List<DataAccessPoint> x = FusekiConfig.processServerConfiguration(model, Fuseki.getContext());
+        return x;
+    }
+    
+    private static DataAccessPoint configFromTemplate(String templateFile, String datasetPath, 
+                                                      boolean allowUpdate, Map<String, String> params) {
+        DatasetDescriptionRegistry registry = new DatasetDescriptionRegistry() ; 
+        // ---- Setup
+        if ( params == null ) {
+            params = new HashMap<>() ;
+            params.put(Template.NAME, datasetPath) ;
+        } else {
+            if ( ! params.containsKey(Template.NAME) ) {
+                Fuseki.configLog.warn("No NAME found in template parameters (added)") ;
+                params.put(Template.NAME, datasetPath) ;   
+            }
+        }
+        //-- Logging
+        Fuseki.configLog.info("Template file: " + templateFile) ;
+        String dir = params.get(Template.DIR) ;
+        if ( dir != null ) {
+            if ( Objects.equals(dir, Names.memName) ) {
+                Fuseki.configLog.info("TDB dataset: in-memory") ;
+            } else {
+                if ( !FileOps.exists(dir) )
+                    throw new CmdException("Directory not found: " + dir) ;
+                Fuseki.configLog.info("TDB dataset: directory=" + dir) ;
+            }
+        }
+        //-- Logging
+        
+        datasetPath = DataAccessPoint.canonical(datasetPath) ;
+        
+        // DRY -- ActionDatasets (and others?)
+        addGlobals(params); 
+
+        String str = TemplateFunctions.templateFile(templateFile, params, Lang.TTL) ;
+        Lang lang = RDFLanguages.filenameToLang(str, Lang.TTL) ;
+        StringReader sr =  new StringReader(str) ;
+        Model model = ModelFactory.createDefaultModel() ;
+        RDFDataMgr.read(model, sr, datasetPath, lang);
+        
+        // ---- DataAccessPoint
+        Statement stmt = getOne(model, null, FusekiVocab.pServiceName, null) ;
+        if ( stmt == null ) {
+            StmtIterator sIter = model.listStatements(null, FusekiVocab.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") ;
+        }
+        Resource subject = stmt.getSubject() ;
+        if ( ! allowUpdate ) {
+            // Opportunity for more sophisticated "read-only" mode.
+            //  1 - clean model, remove "fu:serviceUpdate", "fu:serviceUpload", "fu:serviceReadGraphStore", "fu:serviceReadWriteGraphStore"
+            //  2 - set a flag on DataAccessPoint
+        }
+        DataAccessPoint dap = FusekiConfig.buildDataAccessPoint(subject, registry) ;
+        return dap ;
+    }
+    
+    public static void addGlobals(Map<String, String> params) {
+        if ( params == null ) {
+            Fuseki.configLog.warn("FusekiServer.addGlobals : params is null", new Throwable()) ;
+            return ;
+        }
+        
+        if ( ! params.containsKey("FUSEKI_BASE") )
+            params.put("FUSEKI_BASE", pathStringOrElse(FusekiEnv.FUSEKI_BASE, "unset")) ;
+        if ( ! params.containsKey("FUSEKI_HOME") )
+            params.put("FUSEKI_HOME", pathStringOrElse(FusekiEnv.FUSEKI_HOME, "unset")) ;
+    }
+
+    private static String pathStringOrElse(Path path, String dft) {
+        if ( path == null )
+            return dft ;
+        return path.toString() ;
+    }
+    
+    // DRY -- ActionDatasets (and others?)
+    private static Statement getOne(Model m, Resource s, Property p, RDFNode o) {
+        StmtIterator iter = m.listStatements(s, p, o) ;
+        if ( ! iter.hasNext() )
+            return null ;
+        Statement stmt = iter.next() ;
+        if ( iter.hasNext() )
+            return null ;
+        return stmt ;
+    }
+    
+    private static DataAccessPoint datasetDefaultConfiguration( String name, DatasetGraph dsg, boolean allowUpdate) {
+        name = DataAccessPoint.canonical(name) ;
+        DataService ds = FusekiBuilder.buildDataServiceStd(dsg, allowUpdate) ;
+        DataAccessPoint dap = new DataAccessPoint(name, ds) ;
+        return dap ;
+    }
+    
+    // ---- Helpers
+
+    /** Ensure a directory exists, creating it if necessary.
+     */
+    private static void ensureDir(Path directory) {
+        File dir = directory.toFile() ;
+        if ( ! dir.exists() ) {
+            boolean b = dir.mkdirs() ;
+            if ( ! b )
+                throw new FusekiConfigException("Failed to create directory: "+directory) ;
+        }
+        else if ( ! dir.isDirectory())
+            throw new FusekiConfigException("Not a directory: "+directory) ;
+    }
+
+    private static void mustExist(Path directory) {
+        File dir = directory.toFile() ;
+        if ( ! dir.exists() )
+            throw new FusekiConfigException("Does not exist: "+directory) ; 
+        if ( ! dir.isDirectory())
+            throw new FusekiConfigException("Not a directory: "+directory) ;
+    }
+    
+    private static boolean emptyDir(Path dir) {
+        return dir.toFile().list().length <= 2 ;
+    }
+    
+    private static boolean exists(Path directory) {
+        File dir = directory.toFile() ;
+        return dir.exists() ;
+    }
+
+    private static Path writeableDirectory(Path root , String relName ) {
+        Path p = makePath(root, relName) ;
+        ensureDir(p);
+        if ( ! Files.isWritable(p) )
+            throw new FusekiConfigException("Not writable: "+p) ;
+        return p ;
+    }
+    
+    private static Path makePath(Path root , String relName ) {
+        Path path = root.resolve(relName) ;
+        // Must exist
+//        try { path = path.toRealPath() ; }
+//        catch (IOException e) { IO.exception(e) ; }
+        return path ;
+    }
+
+    /**
+     * Dataset set name to configuration file name. Return a configuration file name -
+     * existing one or ".ttl" form if new
+     */
+    public static String datasetNameToConfigurationFile(HttpAction action, String dsName) {
+        List<String> existing = existingConfigurationFile(dsName) ;
+        if ( ! existing.isEmpty() ) {
+            if ( existing.size() > 1 ) {
+                action.log.warn(format("[%d] Multiple existing configuration files for %s : %s",
+                                       action.id, dsName, existing));
+                ServletOps.errorBadRequest("Multiple existing configuration files for "+dsName);
+                return null ;
+            }
+            return existing.get(0).toString() ;
+        }
+        
+        return generateConfigurationFilename(dsName) ;
+    }
+
+    /** New configuration file name - absiolute filename */
+    public static String generateConfigurationFilename(String dsName) {
+        String filename = dsName ;
+        // Without "/"
+        if ( filename.startsWith("/"))
+            filename = filename.substring(1) ;
+        Path p = FusekiWebapp.dirConfiguration.resolve(filename+".ttl") ;
+        return p.toString();
+    }
+
+    /** Return the filenames of all matching files in the configuration directory (absolute paths returned ). */  
+    public static List<String> existingConfigurationFile(String baseFilename) {
+        try { 
+            List<String> paths = new ArrayList<>() ;
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(FusekiWebapp.dirConfiguration, baseFilename+".*") ) {
+                stream.forEach((p)-> paths.add(FusekiWebapp.dirConfiguration.resolve(p).toString() ));
+            }
+            return paths ;
+        } catch (IOException ex) {
+            throw new InternalErrorException("Failed to read configuration directory "+FusekiWebapp.dirConfiguration) ;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/ShiroEnvironmentLoader.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/ShiroEnvironmentLoader.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/ShiroEnvironmentLoader.java
index b8eaa9b..9f30f11 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/ShiroEnvironmentLoader.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/ShiroEnvironmentLoader.java
@@ -47,7 +47,7 @@ public class ShiroEnvironmentLoader extends EnvironmentLoader implements Servlet
     
     @Override
     public void contextInitialized(ServletContextEvent sce) {
-        FusekiSystem.formatBaseArea() ; 
+        FusekiWebapp.formatBaseArea() ; 
         this.servletContext = sce.getServletContext() ;
         try { 
             // Shiro.

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
index c5431a2..d036ba0 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
@@ -78,7 +78,7 @@ public class SystemState {
         initialized = true ;
         
         if ( location == null )
-            location = Location.create(FusekiSystem.dirSystemDatabase.toString()) ;
+            location = Location.create(FusekiWebapp.dirSystemDatabase.toString()) ;
         
         if ( ! location.isMem() )
             FileOps.ensureDir(location.getDirectoryPath()) ;

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
index eddb6c7..7bce404 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
@@ -36,7 +36,7 @@ import org.apache.jena.fuseki.server.FusekiInitialConfig;
 import org.apache.jena.fuseki.system.FusekiNetLib;
 import org.apache.jena.fuseki.webapp.FusekiEnv;
 import org.apache.jena.fuseki.webapp.FusekiServerListener;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 import org.apache.jena.fuseki.webapp.SystemState;
 import org.apache.jena.riot.web.HttpOp ;
 import org.apache.jena.sparql.core.DatasetGraph ;
@@ -233,11 +233,11 @@ public class ServerCtl {
         // in the case of starting in the same location. FusekiSystem has statics.
         // Fuseki-full is designed to be the only server, not restartable.
         // Here, we want to reset for testing.
-        emptyDirectory(FusekiSystem.dirSystemDatabase);
-        emptyDirectory(FusekiSystem.dirBackups);
-        emptyDirectory(FusekiSystem.dirLogs);
-        emptyDirectory(FusekiSystem.dirConfiguration);
-        emptyDirectory(FusekiSystem.dirDatabases);
+        emptyDirectory(FusekiWebapp.dirSystemDatabase);
+        emptyDirectory(FusekiWebapp.dirBackups);
+        emptyDirectory(FusekiWebapp.dirLogs);
+        emptyDirectory(FusekiWebapp.dirConfiguration);
+        emptyDirectory(FusekiWebapp.dirDatabases);
         
         setupServer(port(), null, datasetPath(), updateable) ;
     }
@@ -272,7 +272,7 @@ public class ServerCtl {
         if ( server != null ) {
             // Clear out the registry.
             server.getDataAccessPointRegistry().clear() ;
-            FileOps.clearAll(FusekiSystem.dirConfiguration.toFile()) ;
+            FileOps.clearAll(FusekiWebapp.dirConfiguration.toFile()) ;
             server.stop() ;
         }
         server = null ;

http://git-wip-us.apache.org/repos/asf/jena/blob/6e8e0743/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
index 7128fae..bd0dcb5 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
@@ -31,7 +31,7 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.jena.atlas.web.HttpException;
 import org.apache.jena.atlas.web.TypedInputStream;
-import org.apache.jena.fuseki.webapp.FusekiSystem;
+import org.apache.jena.fuseki.webapp.FusekiWebapp;
 import org.apache.jena.query.QueryExecution;
 import org.apache.jena.rdfconnection.RDFConnection;
 import org.apache.jena.rdfconnection.RDFConnectionFactory;
@@ -77,7 +77,7 @@ public class TestAdminAPI extends AbstractFusekiTest {
         int x1 = count(conn);
         assertEquals(1, x1);
         
-        Path pathDB = FusekiSystem.dirDatabases.resolve(dbName);
+        Path pathDB = FusekiWebapp.dirDatabases.resolve(dbName);
             
         if ( hasFiles )
             assertTrue(Files.exists(pathDB));