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/08/07 12:02:15 UTC

[03/16] jena git commit: JENA-1585: Fuseki core reorg

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiEnv.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiEnv.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiEnv.java
deleted file mode 100644
index c794459..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiEnv.java
+++ /dev/null
@@ -1,168 +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.server;
-
-import java.nio.file.Path ;
-import java.nio.file.Paths ;
-
-/** 
- * Separate initialization for FUSEKI_HOME and FUSEKI_BASE so that 
- * FusekiLogging can use these values.
- * This code must not touch Jena.  
- * 
- * @see FusekiSystem 
- */ 
-public class FusekiEnv {
-    // Initialization logging happens via stdout/stderr directly.
-    // Fuseki logging is not initialized to avoid going in circles.
-    
-    private static final boolean LogInit         = false ;
-    
-    /** Unused */
-    // public static final String DFT_FUSEKI_HOME = isWindows 
-    //        ? /*What's correct here?*/ "/usr/share/fuseki"
-    //        : "/usr/share/fuseki" ;
-    static final boolean isWindows = determineIfWindows() ;
-    static final String  DFT_FUSEKI_BASE = isWindows ? /* What's correct here? */"/etc/fuseki" : "/etc/fuseki" ;
-    
-    /** Initialization mode, depending on the way Fuseki is started:
-        <ul>
-        <li>{@code WAR} - Running as a WAR file.</li>
-        <li>{@code EMBEDDED}</li>
-        <li>{@code STANDALONE} - Running as the standalone server in Jetty</li>
-        <li>{@code TEST} - Running inside maven/JUnit and as the standalone server</li>
-        <li>{@code UNSET} - Initial state.</li>
-        </ul>
-        <p> 
-        If at server initialization, the MODE is UNSET, then assume WAR setup.
-        A WAR file does not have the opportunity to set the mode.
-        <p>
-        TEST:  (better to set FUSEKI_HOME, FUSEKI_BASE from the test environment</li>
-    */
-    public enum INIT {
-        // Default values of FUSEKI_HOME, and FUSEKI_BASE. 
-        WAR         (null, "/etc/fuseki") , 
-        EMBEDDED    (null, null) ,
-        STANDALONE  (".", "run") ,
-        TEST        ("src/main/webapp", "target/run") ,
-        UNSET       (null, null) ;
-        
-        final String dftFusekiHome ;
-        final String dftFusekiBase ;
-        
-        INIT(String home, String base) {
-            this.dftFusekiHome = home ;
-            this.dftFusekiBase = base ;
-        }
-    }
-    
-    public static INIT mode = INIT.UNSET ;
-    
-    /** 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 ;
-    
-    // Copied from SystemTDB to avoid dependency.
-    // This code must not touch Jena.  
-    private static boolean determineIfWindows() {
-        String s = System.getProperty("os.name") ;
-        if ( s == null )
-            return false ;
-        return s.startsWith("Windows ") ;
-    }
- 
-    public static final String   ENV_runArea     = "run" ;
-    private static boolean       initialized     = false ;
-    
-    /** Initialize the server : standalone and WAR versions : not embedded */
-    public static synchronized void setEnvironment() {
-        if ( initialized )
-            return ;
-        resetEnvironment();
-    }
-    
-    /** Reset environment - use with care and before server start up */ 
-    public static synchronized void resetEnvironment() {
-        initialized = true ;
-        logInit("FusekiEnv:Start: ENV_FUSEKI_HOME = %s : ENV_FUSEKI_BASE = %s : MODE = %s", FUSEKI_HOME, FUSEKI_BASE, mode) ;
-        
-        if ( mode == null || mode == INIT.UNSET )
-            mode = INIT.WAR ;
-
-        if ( FUSEKI_HOME == null ) {
-            // Make absolute
-            String x1 = getenv("FUSEKI_HOME") ;
-            if ( x1 == null )
-                x1 = mode.dftFusekiHome ;
-            if ( x1 != null )
-                FUSEKI_HOME = Paths.get(x1) ;
-        }
-
-        if ( FUSEKI_BASE == null ) {
-            String x2 = getenv("FUSEKI_BASE") ;
-            if ( x2 == null )
-                x2 = mode.dftFusekiBase ;
-            if ( x2 != null )
-                FUSEKI_BASE = Paths.get(x2) ;
-            else {
-                if ( FUSEKI_HOME != null )
-                    FUSEKI_BASE = FUSEKI_HOME.resolve(ENV_runArea) ;
-                else {
-                    // This is bad - there should have been a default by now.
-                    logInitError("Can't find a setting for FUSEKI_BASE - guessing wildy") ;
-                    // Neither FUSEKI_HOME nor FUSEKI_BASE set.
-                    FUSEKI_BASE = Paths.get(DFT_FUSEKI_BASE) ;
-                }
-            }
-        }
-
-        if ( FUSEKI_HOME != null )
-            FUSEKI_HOME = FUSEKI_HOME.toAbsolutePath() ;
-
-        FUSEKI_BASE = FUSEKI_BASE.toAbsolutePath() ;
-
-        logInit("FusekiEnv:Finish: ENV_FUSEKI_HOME = %s : ENV_FUSEKI_BASE = %s", FUSEKI_HOME, FUSEKI_BASE) ;
-    }
-    
-    private static void logInit(String fmt, Object ... args) {
-        if ( LogInit ) {
-            System.out.printf(fmt, args) ; 
-            System.out.println() ;
-        }
-    }
-    
-    private static void logInitError(String fmt, Object ... args) {
-        System.err.printf(fmt, args) ; 
-        System.err.println() ;
-    }
-
-    /** Get environment variable value (maybe in system properties) */
-    public static String getenv(String name) {
-        String x = System.getenv(name) ;
-        if ( x == null )
-            x = System.getProperty(name) ;
-        return x ;
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerEnvironmentInit.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerEnvironmentInit.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerEnvironmentInit.java
deleted file mode 100644
index 1b5f298..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerEnvironmentInit.java
+++ /dev/null
@@ -1,53 +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.server;
-
-import javax.servlet.ServletContextEvent ;
-import javax.servlet.ServletContextListener ;
-
-import org.apache.jena.fuseki.FusekiLogging ;
-import org.apache.jena.sys.JenaSystem ;
-
-/** Setup the environment and logging.
- *  Runs before the {@link ShiroEnvironmentLoader}.
- *  The main configuration happens in {@link FusekiServerListener} which runs after {@link ShiroEnvironmentLoader}.
- */
-public class FusekiServerEnvironmentInit implements ServletContextListener {
-
-    public FusekiServerEnvironmentInit() { }
-    
-    @Override
-    public void contextInitialized(ServletContextEvent sce) {
-        FusekiLogging.setLogging();
-        JenaSystem.init() ;
-        FusekiEnv.setEnvironment() ;
-    }
-
-    @Override
-    public void contextDestroyed(ServletContextEvent sce) {
-        // Stop handling requests.
-        
-        // ActionService uses DataAccessPointRegistry to map URI to services (DataAccessPoint)
-        
-        // DataService -> DataService
-//        DataAccessPointRegistry.shutdown() ;
-//        DatasetDescriptionRegistry.reset() ;
-        JenaSystem.shutdown(); 
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
deleted file mode 100644
index ba3d85b..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
+++ /dev/null
@@ -1,105 +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.server;
-
-import javax.servlet.ServletContext ;
-import javax.servlet.ServletContextEvent ;
-import javax.servlet.ServletContextListener ;
-
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiException;
-import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
-import org.apache.jena.tdb.StoreConnection ;
-
-/** Setup configuration.
- * The order is controlled by {@code web.xml}:
- * <ul>
- * <li>{@link FusekiServerEnvironmentInit}
- * <li>{@link ShiroEnvironmentLoader}
- * <li>{@link FusekiServerListener}, the main configuration
- * </ul>
- */
-
-public class FusekiServerListener implements ServletContextListener {
-
-    public FusekiServerListener() { }
-    
-    public static FusekiInitialConfig initialSetup = null ;
-
-    private boolean initialized = false ;
-
-    @Override
-    public void contextInitialized(ServletContextEvent sce) {
-        ServletContext servletContext = sce.getServletContext() ;
-        String x = servletContext.getContextPath() ;
-        if ( ! x.isEmpty() ) 
-            Fuseki.configLog.info("Context path = "+x) ;
-        serverInitialization(servletContext) ;
-    }
-
-    @Override
-    public void contextDestroyed(ServletContextEvent sce) {
-//        DataAccessPointRegistry.get().forEach((key, dap) -> {
-//            ??
-//        }) ;
-        // But in flight-transactions?
-        StoreConnection.reset();
-    }
-
-    private synchronized void serverInitialization(ServletContext servletContext) {
-        if ( initialized )
-            return ;
-        initialized = true ;
-
-        ServiceDispatchRegistry serviceDispatchRegistry = new ServiceDispatchRegistry(true);
-        ServiceDispatchRegistry.set(servletContext, serviceDispatchRegistry);
-        DataAccessPointRegistry dataAccessPointRegistry = new DataAccessPointRegistry() ;
-        DataAccessPointRegistry.set(servletContext, dataAccessPointRegistry);
-        
-        
-        try {
-            FusekiSystem.formatBaseArea() ; 
-            if ( ! FusekiSystem.serverInitialized ) {
-                Fuseki.serverLog.error("Failed to initialize : Server not running") ;
-                return ;
-            }
-            
-            // The command line code sets initialSetup.
-            // 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() ;
-                initialSetup.fusekiServerConfigFile = cfg ;
-            }
-
-            if ( initialSetup == null ) {
-                Fuseki.serverLog.error("No configuration") ;
-                throw new FusekiException("No configuration") ;
-            }                
-            Fuseki.setVerbose(servletContext, initialSetup.verbose);
-            FusekiSystem.initializeDataAccessPoints(dataAccessPointRegistry,
-                                                    initialSetup, FusekiSystem.dirConfiguration.toString()) ;
-        } catch (Throwable th) { 
-            Fuseki.serverLog.error("Exception in initialization: {}", th.getMessage()) ;
-            throw th ;
-        }
-        FusekiInfo.info(initialSetup, dataAccessPointRegistry);
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java
deleted file mode 100644
index 23a2485..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java
+++ /dev/null
@@ -1,453 +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.server;
-
-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.* ;
-
-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.* ;
-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 assmbler 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, e);
-                e.printStackTrace();
-            }
-        } else {
-            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: "+src, 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()) ;
-            registry.register(dap.getName(), 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 = FusekiBuilder.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/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceMXBean.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceMXBean.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceMXBean.java
deleted file mode 100644
index 11c7330..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ServiceMXBean.java
+++ /dev/null
@@ -1,32 +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.server;
-
-public interface ServiceMXBean
-{
-    String getName() ;
-    
-    long getRequests() ;
-    long getRequestsGood() ;
-    long getRequestsBad() ;
-    
-//    void enable() ;
-//    void disable() ;
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ShiroEnvironmentLoader.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ShiroEnvironmentLoader.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ShiroEnvironmentLoader.java
deleted file mode 100644
index 1521cf1..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/ShiroEnvironmentLoader.java
+++ /dev/null
@@ -1,163 +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.server;
-
-import java.io.IOException ;
-import java.io.InputStream ;
-import java.nio.file.Path ;
-import java.nio.file.Paths ;
-
-import javax.servlet.ServletContext ;
-import javax.servlet.ServletContextEvent ;
-import javax.servlet.ServletContextListener ;
-
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.util.FileUtils ;
-import org.apache.shiro.config.ConfigurationException ;
-import org.apache.shiro.io.ResourceUtils ;
-import org.apache.shiro.web.env.EnvironmentLoader ;
-import org.apache.shiro.web.env.ResourceBasedWebEnvironment ;
-import org.apache.shiro.web.env.WebEnvironment ;
-
-/** A place to perform Fuseki-specific initialization of Apache Shiro.
- *  Runs after listener {@link FusekiServerEnvironmentInit} and before {@link FusekiServerListener}.
- *  This means finding shiro.ini in multiple possible places, based on
- *  different deployment setups.
- */
-public class ShiroEnvironmentLoader extends EnvironmentLoader implements ServletContextListener {
-    private ServletContext servletContext ; 
-    
-    public ShiroEnvironmentLoader() {}
-    
-    @Override
-    public void contextInitialized(ServletContextEvent sce) {
-        FusekiSystem.formatBaseArea() ; 
-        this.servletContext = sce.getServletContext() ;
-        try { 
-            // Shiro.
-            initEnvironment(servletContext);
-        } catch (ConfigurationException  ex) {
-            Fuseki.configLog.error("Shiro initialization failed: "+ex.getMessage());
-            // Exit?
-            throw ex ;
-        }
-    }
-
-    @Override
-    public void contextDestroyed(ServletContextEvent sce) {
-        destroyEnvironment(sce.getServletContext());
-    }
-
-    /** 
-     * Normal Shiro initialization only supports one location for an INI file.
-     *  
-     * When given multiple locations for the shiro.ini file, and 
-     * if a {@link ResourceBasedWebEnvironment}, check the list of configuration
-     * locations, testing whether the name identified an existing resource.  
-     * For the first resource name found to exist, reset the {@link ResourceBasedWebEnvironment}
-     * to name that resource alone so the normal Shiro initialization  
-     */
-    @Override
-    protected void customizeEnvironment(WebEnvironment environment) {
-        if ( environment instanceof ResourceBasedWebEnvironment ) {
-            ResourceBasedWebEnvironment env = (ResourceBasedWebEnvironment)environment ;
-            String[] locations = env.getConfigLocations() ;
-            String loc = huntForShiroIni(locations) ;
-            Fuseki.configLog.info("Shiro file: "+loc);
-            if (loc != null )
-                locations = new String[] {loc} ;
-            env.setConfigLocations(locations);
-        }
-    }
-    
-    private static final String FILE = "file" ;
-    
-    /** Look for a Shiro ini file, or return null */
-    private static String huntForShiroIni(String[] locations) {
-        FusekiEnv.setEnvironment() ;
-        Fuseki.init();
-        for ( String loc : locations ) {
-            // If file:, look for that file.
-            // If a relative name without scheme, look in FUSEKI_BASE, FUSEKI_HOME, webapp. 
-            String scheme = FileUtils.getScheme(loc) ;
-            
-            // Covers C:\\ as a "scheme name"
-            if ( scheme != null ) {
-                if ( scheme.equalsIgnoreCase(FILE)) {
-                    // Test file: for exists
-                    Path p = Paths.get(loc.substring(FILE.length()+1)) ;
-                    if ( ! p.toFile().exists() )
-                        continue ;
-                    // Fall through.
-                }
-                // Can't test - try 
-                return loc ;
-            }
-            // No scheme .
-            Path p = Paths.get(loc) ;
-            
-            String fn = resolve(FusekiEnv.FUSEKI_BASE, p) ;
-            if ( fn != null )
-                return "file://"+fn ;
-            fn = resolve(FusekiEnv.FUSEKI_HOME, p) ;
-            if ( fn != null )
-                return "file://"+fn ;
-            
-            // Try in webapp.
-            
-            try ( InputStream is = ResourceUtils.getInputStreamForPath(loc); ) {
-                boolean exists = (is != null ) ;
-                return loc ;
-            } catch (IOException e) { }
-        }
-        return null ;
-    }
-    
-    /** Directory + name -> filename if it exists */ 
-    private static String resolve(Path dir, Path file) {
-        Path p = dir.resolve(file) ;
-        if ( p.toFile().exists() )
-            return p.normalize().toString() ;
-        return null ;
-    }
-
-//    /** 
-//     * Test whether a name identified an existing resource
-//     * @param resource    A String in Shiro-resource name format (e.g. URL scheme names) 
-//     * @return True/false as to whether the resource can be found or not. 
-//     */
-//    
-//    private boolean resourceExists(String resource) {
-//        try {
-//            // See IniWebEnvironment.convertPathToIni
-//            if (!ResourceUtils.hasResourcePrefix(resource)) {
-//                //Sort out "path" and open as a webapp resource.
-//                resource = WebUtils.normalize(resource);
-//                URL url = servletContext.getResource(resource) ;
-//                return ( url == null ) ;
-//            } else {
-//                // Treat as a plain name. 
-//                InputStream is = ResourceUtils.getInputStreamForPath(resource);
-//                boolean exists = (is != null ) ;
-//                is.close() ;
-//                return exists ;
-//            }
-//        } catch (IOException e) { return false ; }
-//    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/SystemState.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/SystemState.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/SystemState.java
deleted file mode 100644
index 460fda1..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/SystemState.java
+++ /dev/null
@@ -1,108 +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.server;
-
-import org.apache.jena.atlas.lib.FileOps ;
-import org.apache.jena.atlas.lib.StrUtils ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.tdb.StoreConnection ;
-import org.apache.jena.tdb.TDB ;
-import org.apache.jena.tdb.TDBFactory ;
-import org.apache.jena.tdb.base.block.FileMode ;
-import org.apache.jena.tdb.base.file.Location ;
-import org.apache.jena.tdb.setup.StoreParams ;
-import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
-
-public class SystemState {
-    private static String SystemDatabaseLocation ;
-    // Testing may reset this.
-    public static Location location ; 
-    
-    private  static Dataset                 dataset   = null ;
-    private  static DatasetGraphTransaction dsg       = null ;
-    
-    public static Dataset getDataset() {
-        init() ;
-        return dataset ;
-    }
-    
-    public static DatasetGraphTransaction getDatasetGraph() {
-        init() ;
-        return dsg ;
-    }
-    
-    private static boolean initialized = false ; 
-    private static void init() {
-        init$() ;
-    }
-    
-    /** Small footprint database.  The system database records the server state.
-     * It should not be performance critical, mainly being used for system admin
-     * functions.
-     * <p>Direct mode so that it is not competing for OS file cache space.
-     * <p>Small caches - 
-     */
-    private static final StoreParams systemDatabaseParams = StoreParams.builder()
-        .fileMode(FileMode.direct)
-        .blockSize(1024)
-        .blockReadCacheSize(50)
-        .blockWriteCacheSize(20)
-        .node2NodeIdCacheSize(500)
-        .nodeId2NodeCacheSize(500)
-        .nodeMissCacheSize(100)
-        .build() ;
-    
-    public /* for testing */ static void init$() {
-        if ( initialized )
-            return ;
-        initialized = true ;
-        
-        if ( location == null )
-            location = Location.create(FusekiSystem.dirSystemDatabase.toString()) ;
-        
-        if ( ! location.isMem() )
-            FileOps.ensureDir(location.getDirectoryPath()) ;
-        
-        // Force it into the store connection as a low footprint
-        if ( StoreConnection.getExisting(location) != null )
-            Fuseki.serverLog.warn("System database already in the StoreConnection cache") ;
-        StoreConnection.make(location, systemDatabaseParams) ;
-        
-        dataset = TDBFactory.createDataset(location) ;
-        dsg     = (DatasetGraphTransaction)(dataset.asDatasetGraph()) ;
-        dsg.getContext().set(TDB.symUnionDefaultGraph, false) ;
-    }
-    
-    public static String PREFIXES = StrUtils.strjoinNL
-        ("BASE            <http://example/base#>",
-         "PREFIX ja:      <http://jena.hpl.hp.com/2005/11/Assembler#>",
-         "PREFIX fu:      <http://jena.apache.org/fuseki#>",
-         "PREFIX fuseki:  <http://jena.apache.org/fuseki#>",
-         "PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>",
-         "PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>",
-         "PREFIX tdb:     <http://jena.hpl.hp.com/2008/tdb#>",
-         "PREFIX sdb:     <http://jena.hpl.hp.com/2007/sdb#>",
-         "PREFIX list:    <http://jena.apache.org/ARQ/list#>",
-         "PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>",
-         "PREFIX apf:     <http://jena.apache.org/ARQ/property#>",
-         "PREFIX afn:     <http://jena.apache.org/ARQ/function#>",
-         "") ;
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java
deleted file mode 100644
index 63e6562..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java
+++ /dev/null
@@ -1,53 +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.servlets;
-
-import java.io.* ;
-
-/** 
-* Code needed to implement an OutputStream that does nothing.
-*/
-
-
-public class NullOutputStream extends /*Filter*/OutputStream
-{
-	public NullOutputStream()
-	{
-	}
-
-	// The OutputStream operations
-	@Override
-    public void close() { /* .close() ;*/ }
-	@Override
-    public void flush() { /* .flush() ;*/ }
-
-	// Need to implement this one.
-	@Override
-    public void write(int b) { /* .write(b) ;*/ }
-	@Override
-    public void write(byte b[]) { /* this.write(b, 0, b.length) ; */}
-
-	// Good to implement this one.
-	@Override
-    public void write(byte[] b, int off, int len)
-	{
-		// Work function
-	}
-	
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
index fdc04b8..10e36ac 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
@@ -19,6 +19,8 @@
 package org.apache.jena.fuseki.servlets ;
 
 import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.system.Upload;
+import org.apache.jena.fuseki.system.UploadDetails;
 import org.apache.jena.riot.RiotException ;
 import org.apache.jena.riot.system.StreamRDF ;
 import org.apache.jena.riot.system.StreamRDFLib ;

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
index 7dfe1e1..7b964e2 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
@@ -26,7 +26,9 @@ import org.apache.jena.atlas.web.MediaType ;
 import org.apache.jena.fuseki.DEF ;
 import org.apache.jena.fuseki.FusekiLib ;
 import org.apache.jena.fuseki.conneg.ConNeg ;
-import org.apache.jena.fuseki.servlets.UploadDetails.PreState ;
+import org.apache.jena.fuseki.system.Upload;
+import org.apache.jena.fuseki.system.UploadDetails;
+import org.apache.jena.fuseki.system.UploadDetails.PreState;
 import org.apache.jena.graph.Graph ;
 import org.apache.jena.riot.RiotException ;
 import org.apache.jena.riot.system.StreamRDF ;

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
index 21038f4..3cf0d0d 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
@@ -23,7 +23,7 @@ import static java.lang.String.format ;
 import java.util.List ;
 
 import org.apache.jena.atlas.lib.InternalErrorException ;
-import org.apache.jena.fuseki.migrate.GraphLoadUtils ;
+import org.apache.jena.fuseki.system.GraphLoadUtils;
 import org.apache.jena.query.Dataset ;
 import org.apache.jena.query.DatasetFactory ;
 import org.apache.jena.query.Query ;

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
index b250250..0fa6add 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
@@ -26,7 +26,8 @@ import javax.servlet.http.HttpServletResponse ;
 
 import org.apache.jena.atlas.json.JSON ;
 import org.apache.jena.atlas.json.JsonValue ;
-import org.apache.jena.fuseki.servlets.UploadDetails.PreState ;
+import org.apache.jena.fuseki.system.UploadDetails;
+import org.apache.jena.fuseki.system.UploadDetails.PreState;
 import org.apache.jena.riot.WebContent ;
 import org.apache.jena.riot.web.HttpNames ;
 import org.apache.jena.web.HttpSC ;

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Upload.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Upload.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Upload.java
deleted file mode 100644
index 89c5038..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Upload.java
+++ /dev/null
@@ -1,164 +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.servlets;
-
-import static java.lang.String.format ;
-import static org.apache.jena.riot.WebContent.ctMultipartFormData ;
-import static org.apache.jena.riot.WebContent.ctTextPlain ;
-import static org.apache.jena.riot.WebContent.matchContentType ;
-
-import java.io.IOException ;
-import java.io.InputStream ;
-import java.util.zip.GZIPInputStream ;
-
-import org.apache.commons.fileupload.FileItemIterator ;
-import org.apache.commons.fileupload.FileItemStream ;
-import org.apache.commons.fileupload.servlet.ServletFileUpload ;
-import org.apache.commons.fileupload.util.Streams ;
-import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.atlas.web.ContentType ;
-import org.apache.jena.fuseki.FusekiLib ;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFLanguages ;
-import org.apache.jena.riot.RiotParseException ;
-import org.apache.jena.riot.lang.StreamRDFCounting ;
-import org.apache.jena.riot.system.StreamRDF ;
-import org.apache.jena.riot.system.StreamRDFLib ;
-
-public class Upload {
-    public static UploadDetails incomingData(HttpAction action, StreamRDF dest) {
-        ContentType ct = FusekiLib.getContentType(action) ;
-        
-        if ( ct == null ) {
-            ServletOps.errorBadRequest("No content type") ;
-            return null ;
-        }
-         
-        if ( matchContentType(ctMultipartFormData, ct) ) {
-            return fileUploadWorker(action, dest) ;
-        }
-        // Single graph (or quads) in body.
-        
-        String base = ActionLib.wholeRequestURL(action.request) ;
-        Lang lang = RDFLanguages.contentTypeToLang(ct.getContentType()) ;
-        if ( lang == null ) {
-            ServletOps.errorBadRequest("Unknown content type for triples: " + ct) ;
-            return null ;
-        }
-        InputStream input = null ;
-        try { input = action.request.getInputStream() ; } 
-        catch (IOException ex) { IO.exception(ex) ; }
-    
-        long len = action.request.getContentLengthLong();
-
-        StreamRDFCounting countingDest = StreamRDFLib.count(dest) ;
-        try {
-            ActionLib.parse(action, countingDest, input, lang, base) ;
-            UploadDetails details = new UploadDetails(countingDest.count(), countingDest.countTriples(),countingDest.countQuads()) ;
-            action.log.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s : %s", 
-                                   action.id, len, ct.getContentType(), ct.getCharset(), lang.getName(),
-                                   details.detailsStr())) ;
-            return details ;
-        } catch (RiotParseException ex) {
-            action.log.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s : %s",
-                                   action.id, len, ct.getContentType(), ct.getCharset(), lang.getName(),
-                                   ex.getMessage())) ;
-            throw ex ;
-        }
-    }
-    
-    /**  Process an HTTP upload of RDF files (triples or quads)
-     *   Stream straight into a graph or dataset -- unlike SPARQL_Upload the destination
-     *   is known at the start of the multipart file body
-     */
-    
-    public static UploadDetails fileUploadWorker(HttpAction action, StreamRDF dest) {
-        String base = ActionLib.wholeRequestURL(action.request) ;
-        ServletFileUpload upload = new ServletFileUpload();
-        //log.info(format("[%d] Upload: Field=%s ignored", action.id, fieldName)) ;
-        
-        // Overall counting.
-        StreamRDFCounting countingDest =  StreamRDFLib.count(dest) ;
-        
-        try {
-            FileItemIterator iter = upload.getItemIterator(action.request);
-            while (iter.hasNext()) {
-                FileItemStream fileStream = iter.next();
-                if (fileStream.isFormField()) {
-                    // Ignore?
-                    String fieldName = fileStream.getFieldName() ;
-                    InputStream stream = fileStream.openStream();
-                    String value = Streams.asString(stream, "UTF-8") ;
-                    ServletOps.errorBadRequest(format("Only files accepted in multipart file upload (got %s=%s)",fieldName, value)) ;
-                }
-                //Ignore the field name.
-                //String fieldName = fileStream.getFieldName();
-    
-                InputStream stream = fileStream.openStream();
-                // Process the input stream
-                String contentTypeHeader = fileStream.getContentType() ;
-                ContentType ct = ContentType.create(contentTypeHeader) ;
-                Lang lang = null ;
-                if ( ! matchContentType(ctTextPlain, ct) )
-                    lang = RDFLanguages.contentTypeToLang(ct.getContentType()) ;
-    
-                if ( lang == null ) {
-                    String name = fileStream.getName() ; 
-                    if ( name == null || name.equals("") ) 
-                        ServletOps.errorBadRequest("No name for content - can't determine RDF syntax") ;
-                    lang = RDFLanguages.filenameToLang(name) ;
-                    if (name.endsWith(".gz"))
-                        stream = new GZIPInputStream(stream);
-                }
-                if ( lang == null )
-                    // Desperate.
-                    lang = RDFLanguages.RDFXML ;
-    
-                String printfilename = fileStream.getName() ; 
-                if ( printfilename == null  || printfilename.equals("") )
-                    printfilename = "<none>" ; 
-    
-                // Before
-                // action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s", 
-                //                        action.id, printfilename,  ct.getContentType(), ct.getCharset(), lang.getName())) ;
-                
-                // count just this step
-                StreamRDFCounting countingDest2 =  StreamRDFLib.count(countingDest) ;
-                try {
-                    ActionLib.parse(action, countingDest2, stream, lang, base);
-                    UploadDetails details1 = new UploadDetails(countingDest2.count(), countingDest2.countTriples(),countingDest2.countQuads()) ;
-                    action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s : %s", 
-                                           action.id, printfilename,  ct.getContentType(), ct.getCharset(), lang.getName(),
-                                           details1.detailsStr())) ;
-                } catch (RiotParseException ex) {
-                    action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s : %s",
-                                           action.id, printfilename,  ct.getContentType(), ct.getCharset(), lang.getName(),
-                                           ex.getMessage())) ;
-                    throw ex ;
-                }
-            }
-        }
-        catch (ActionErrorException ex) { throw ex ; }
-        catch (Exception ex)            { ServletOps.errorOccurred(ex.getMessage()) ; }
-        // Overall results.
-        UploadDetails details = new UploadDetails(countingDest.count(), countingDest.countTriples(),countingDest.countQuads()) ;
-        return details ;
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java
deleted file mode 100644
index a5c144b..0000000
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java
+++ /dev/null
@@ -1,86 +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.servlets;
-
-import org.apache.jena.atlas.json.JsonBuilder ;
-import org.apache.jena.atlas.json.JsonValue ;
-
-/** Record of an upload */
-public class UploadDetails {
-    public enum PreState { EXISTED, ABSENT, UNKNOWN } 
-    
-    private final long count ;
-    private final long tripleCount ;
-    private final long quadCount ;
-    private PreState state = PreState.UNKNOWN ;
-    
-    /*package*/ UploadDetails(long parserCount, long parserTripleCount, long parserQuadCount) {
-        this.count = parserCount ;
-        this.tripleCount = parserTripleCount ;
-        this.quadCount = parserQuadCount ;
-    }
-    
-    public static String detailsStr(long count, long tripleCount, long quadCount) {
-        return String.format("Count=%d Triples=%d Quads=%d", count, tripleCount, quadCount) ;
-    }
-    
-    public String detailsStr() {
-        return detailsStr(count, tripleCount, quadCount) ;
-    }
-    
-    public static String jCount = "count" ; 
-    public static String jTriplesCount = "tripleCount" ; 
-    public static String jQuadsCount = "quadCount" ; 
-    
-    public static JsonValue detailsJson(long count, long tripleCount, long quadCount) {
-        JsonBuilder b = new JsonBuilder() ;
-        b.startObject("details") ;
-        b.key(jCount).value(count) ;
-        b.key(jTriplesCount).value(tripleCount) ;
-        b.key(jQuadsCount).value(quadCount) ;
-        b.finishObject("details") ;
-        return b.build() ;
-    }
-
-    public JsonValue detailsJson() {
-        return detailsJson(count, tripleCount, quadCount) ;
-    }
-
-    public long getCount() {
-        return count ;
-    }
-
-    public long getTripleCount() {
-        return tripleCount ;
-    }
-
-    public long getQuadCount() {
-        return quadCount ;
-    }
-
-    public void setExistedBefore(boolean existedBefore) {
-        if ( existedBefore )
-            setExistedBefore(PreState.EXISTED) ;
-        else
-            setExistedBefore(PreState.ABSENT) ;
-    }
-    public void setExistedBefore(PreState state) { this.state = state ; }
-    
-    public PreState getExistedBefore() { return state ; }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiLogging.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiLogging.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiLogging.java
new file mode 100644
index 0000000..404c581
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/FusekiLogging.java
@@ -0,0 +1,191 @@
+/**
+ * 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.system;
+
+import java.io.File ;
+import java.net.URL ;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.webapp.FusekiEnv;
+import org.apache.jena.riot.SysRIOT ;
+import org.apache.log4j.PropertyConfigurator ;
+import org.apache.log4j.helpers.Loader ;
+
+public class FusekiLogging
+{
+    // This class must not have static constants, or otherwise not "Fuseki.*"
+    // or any class else where that might kick off logging.  Otherwise, the 
+    // setLogging is pointless (it's already set).
+    // PlanB - reinitialize logging regardless on first call. 
+    
+    // Set logging.
+    // 1/ Use log4j.configuration if defined.
+    // 2/ Use file:log4j.properties if exists
+    // 3/ Use log4j.properties on the classpath.
+    // 4/ Use built-in org/apache/jena/fuseki/log4j.properties on the classpath.
+    // 5/ Use Built in string
+
+    /** Places for the log4j properties file at (3) */ 
+    private static final String[] resourcesForLog4jProperties = {
+        // Hmm - 
+        "log4j.properties",
+        "org/apache/jena/fuseki/log4j.properties"
+    } ;
+    
+    private static final boolean LogLogging     = false ;
+    private static boolean loggingInitialized   = false ;
+    private static boolean allowLoggingReset    = true ;
+    
+    /**
+     * Switch off logging setting. 
+     * Used by the embedded server so that the application's
+     * logging setup is not overwritten.
+     */
+    public static synchronized void allowLoggingReset(boolean value) {
+        allowLoggingReset = value ;
+    }
+    
+    /** Set up logging - standalone and war packaging */
+    public static synchronized void setLogging() {
+        if ( ! allowLoggingReset )
+            return ;
+        if ( loggingInitialized )
+            return ;
+        loggingInitialized = true ;
+        FusekiEnv.setEnvironment() ;
+        
+        logLogging("Fuseki logging") ;
+        // No loggers have been created but configuration may have been set up.
+        String x = System.getProperty("log4j.configuration", null) ;
+        logLogging("log4j.configuration = %s", x) ;
+
+        if ( x != null ) { 
+            // log4j will initialize in the usual way. This includes a value of
+            // "set", which indicates that logging was set before by some other Jena code.
+            if ( x.equals("set") )
+                Fuseki.serverLog.warn("Fuseki logging: Unexpected: Log4j was setup by some other part of Jena") ;
+            return ;
+        }
+        logLogging("Fuseki logging - setup") ;
+        // Look for a log4j.properties in the current working directory
+        // and an existing FUSEKI_BASE for easy customization.
+        String fn1 = "log4j.properties" ;
+        String fn2 = null ;
+        
+        if ( FusekiEnv.FUSEKI_BASE != null ) 
+            fn2 = FusekiEnv.FUSEKI_BASE.toString()+"/log4j.properties" ;
+        if ( attempt(fn1) ) return ; 
+        if ( attempt(fn2) ) return ;
+        
+        // Try classpath
+        for ( String resourceName : resourcesForLog4jProperties ) {
+            // The log4j general initialization is done in a class static
+            // in LogManager so it can't be called again in any sensible manner.
+            // Instead, we include the same basic mechanism ...
+            logLogging("Fuseki logging - classpath %s", resourceName) ;
+            URL url = Loader.getResource(resourceName) ;
+            if ( url != null ) {
+                // Problem - test classes can be on the classpath (development mainly).
+                if ( url.toString().contains("-tests.jar") || url.toString().contains("test-classes") )
+                    url = null ;
+            }
+            
+            if ( url != null ) {
+                PropertyConfigurator.configure(url) ;
+                logLogging("Fuseki logging - found via classpath %s", url) ;
+                System.setProperty("log4j.configuration", url.toString()) ;
+                return ;
+            }
+        }
+        // Use builtin.
+        logLogging("Fuseki logging - Fallback log4j.properties string") ;
+        String dftLog4j = log4JsetupFallback() ;
+        LogCtl.resetLogging(dftLog4j);
+        // Stop anything attempting to do it again.
+        System.setProperty("log4j.configuration", "set") ;
+    }
+
+    private static boolean attempt(String fn) {
+        try {
+            File f = new File(fn) ;
+            if ( f.exists() ) {
+                logLogging("Fuseki logging - found file:log4j.properties") ;
+                PropertyConfigurator.configure(fn) ;
+                System.setProperty("log4j.configuration", "file:" + fn) ;
+                return true ;
+            }
+        }
+        catch (Throwable th) {}
+        return false ;
+    }
+
+    private static void logLogging(String fmt, Object ... args) {
+        if ( LogLogging ) {
+            System.out.printf(fmt, args) ; 
+            System.out.println() ;
+        }
+    }
+
+    private static String log4JsetupFallback() {
+        return StrUtils.strjoinNL
+            // Preferred: classes/log4j.properties, from src/main/resources/log4j.properties
+            // Keep these in-step.  Different usages cause different logging initalizations;
+            // if the jar is rebundled, it may loose the associated log4.properties file.
+            ("## Plain output to stdout",
+             "log4j.appender.jena.plainstdout=org.apache.log4j.ConsoleAppender",
+             "log4j.appender.jena.plainstdout.target=System.out",
+             "log4j.appender.jena.plainstdout.layout=org.apache.log4j.PatternLayout",
+             "log4j.appender.jena.plainstdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %-10c{1} %-5p %m%n",
+             //"log4j.appender.jena.plainstdout.layout.ConversionPattern=%d{HH:mm:ss} %-10c{1} %-5p %m%n",
+
+             "# Unadorned, for the requests log.",
+             "log4j.appender.fuseki.plain=org.apache.log4j.ConsoleAppender",
+             "log4j.appender.fuseki.plain.target=System.out",
+             "log4j.appender.fuseki.plain.layout=org.apache.log4j.PatternLayout",
+             "log4j.appender.fuseki.plain.layout.ConversionPattern=%m%n",
+             
+             "## Most things", 
+             "log4j.rootLogger=INFO, jena.plainstdout",
+             "log4j.logger.com.hp.hpl.jena=WARN",
+             "log4j.logger.org.apache.jena=WARN",
+
+             "# Fuseki System logs.",
+             "log4j.logger." + Fuseki.serverLogName     + "=INFO",
+             "log4j.logger." + Fuseki.actionLogName     + "=INFO",
+             "log4j.logger." + Fuseki.adminLogName      + "=INFO",
+             "log4j.logger." + Fuseki.validationLogName + "=INFO",
+             "log4j.logger." + Fuseki.configLogName     + "=INFO",
+
+             "log4j.logger.org.apache.jena.tdb.loader=INFO",
+             "log4j.logger.org.eclipse.jetty=WARN" ,
+             "log4j.logger.org.apache.shiro=WARN",
+
+             "# NCSA Request Access log",
+             "log4j.additivity."+Fuseki.requestLogName   + "=false",
+             "log4j.logger."+Fuseki.requestLogName       + "=OFF, fuseki.plain",
+
+             "## Parser output", 
+             "log4j.additivity" + SysRIOT.riotLoggerName + "=false",
+             "log4j.logger." + SysRIOT.riotLoggerName + "=INFO, plainstdout"
+                ) ;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/GraphLoadUtils.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/GraphLoadUtils.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/GraphLoadUtils.java
new file mode 100644
index 0000000..f91abef
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/GraphLoadUtils.java
@@ -0,0 +1,71 @@
+/*
+ * 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.system;
+
+import org.apache.jena.fuseki.Fuseki ;
+import org.apache.jena.graph.Factory ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.rdf.model.Model ;
+import org.apache.jena.rdf.model.ModelFactory ;
+import org.apache.jena.riot.RDFParser ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+
+/** A packaging of code to do a controlled read of a graph or model */
+
+public class GraphLoadUtils
+{
+    // ---- Model level
+    
+    public static Model readModel(String uri, int limit)
+    {
+        Graph g = Factory.createGraphMem() ;
+        readUtil(g, uri, limit) ;
+        return ModelFactory.createModelForGraph(g) ;
+    }
+    
+    public static void loadModel(Model model, String uri, int limit) 
+    {
+        Graph g = model.getGraph() ;
+        readUtil(g, uri, limit) ;
+    }
+
+    // ---- Graph level
+    
+    public static Graph readGraph(String uri, int limit)
+    {
+        Graph g = Factory.createGraphMem() ;
+        readUtil(g, uri, limit) ;
+        return g ;
+    }
+    
+    public static void loadGraph(Graph g, String uri, int limit) 
+    {
+        readUtil(g, uri, limit) ;
+    }
+    
+    // ** Worker.
+    private static void readUtil(Graph graph, String uri, int limit)
+    {
+        StreamRDF sink = StreamRDFLib.graph(graph) ;
+        sink = new StreamRDFLimited(sink, limit) ;
+        RDFParser.source(uri).streamManager(Fuseki.webStreamManager).parse(sink);
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1d41d2ce/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/StreamRDFLimited.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/StreamRDFLimited.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/StreamRDFLimited.java
new file mode 100644
index 0000000..11229d8
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/system/StreamRDFLimited.java
@@ -0,0 +1,62 @@
+/*
+ * 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.system ;
+
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFWrapper ;
+import org.apache.jena.sparql.core.Quad ;
+
+/**
+ * Limit triples/quads and stop passing through after a limit is reached.
+ */
+public class StreamRDFLimited extends StreamRDFWrapper {
+    private long       count = 0 ;
+    private final long limit ;
+
+    public StreamRDFLimited(StreamRDF output, long limit) {
+        super(output) ;
+        this.limit = limit ;
+    }
+
+    @Override
+    public void triple(Triple triple) {
+        count++ ;
+        if ( count > limit )
+            throw new RiotException("Limit ("+limit+") reached") ; 
+        super.triple(triple) ;
+    }
+
+    @Override
+    public void quad(Quad quad) {
+        count++ ;
+        if ( count > limit )
+            throw new RiotException("Limit ("+limit+") reached") ; 
+        super.quad(quad) ;
+    }
+
+    public long getCount() {
+        return count ;
+    }
+
+    public long getLimit() {
+        return limit ;
+    }
+}