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 2013/12/26 17:57:37 UTC

svn commit: r1553511 - in /jena/branches/jena-fuseki-new-ui: ./ bin/ src-dev/dev/ src/main/java/org/apache/jena/fuseki/ src/main/java/org/apache/jena/fuseki/mgt/ src/main/java/org/apache/jena/fuseki/server/

Author: andy
Date: Thu Dec 26 16:57:36 2013
New Revision: 1553511

URL: http://svn.apache.org/r1553511
Log:
Tidy up server building.
Put soh scripts in bin/

Added:
    jena/branches/jena-fuseki-new-ui/bin/
    jena/branches/jena-fuseki-new-ui/bin/s-delete   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-get   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-head   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-post   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-put   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-query   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-update   (with props)
    jena/branches/jena-fuseki-new-ui/bin/s-update-form   (with props)
    jena/branches/jena-fuseki-new-ui/bin/soh   (with props)
Removed:
    jena/branches/jena-fuseki-new-ui/s-delete
    jena/branches/jena-fuseki-new-ui/s-get
    jena/branches/jena-fuseki-new-ui/s-head
    jena/branches/jena-fuseki-new-ui/s-post
    jena/branches/jena-fuseki-new-ui/s-put
    jena/branches/jena-fuseki-new-ui/s-query
    jena/branches/jena-fuseki-new-ui/s-update
    jena/branches/jena-fuseki-new-ui/s-update-form
    jena/branches/jena-fuseki-new-ui/soh
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/X_Config.java
Modified:
    jena/branches/jena-fuseki-new-ui/config2.ttl
    jena/branches/jena-fuseki-new-ui/src-dev/dev/PROJECT.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/DEF.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiConfig.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiServletContextListener.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java
    jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/ServerInitialConfig.java

Added: jena/branches/jena-fuseki-new-ui/bin/s-delete
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-delete?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-delete (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-delete Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-delete
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-get
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-get?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-get (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-get Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-get
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-head
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-head?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-head (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-head Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-head
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-post
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-post?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-post (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-post Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-post
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-put
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-put?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-put (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-put Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-put
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-query
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-query?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-query (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-query Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-query
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-update
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-update?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-update (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-update Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-update
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/s-update-form
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/s-update-form?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/s-update-form (added)
+++ jena/branches/jena-fuseki-new-ui/bin/s-update-form Thu Dec 26 16:57:36 2013
@@ -0,0 +1 @@
+link soh
\ No newline at end of file

Propchange: jena/branches/jena-fuseki-new-ui/bin/s-update-form
------------------------------------------------------------------------------
    svn:special = *

Added: jena/branches/jena-fuseki-new-ui/bin/soh
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/bin/soh?rev=1553511&view=auto
==============================================================================
--- jena/branches/jena-fuseki-new-ui/bin/soh (added)
+++ jena/branches/jena-fuseki-new-ui/bin/soh Thu Dec 26 16:57:36 2013
@@ -0,0 +1,707 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+# 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.
+
+# SPARQL HTTP Update, client.
+
+require 'optparse'
+require 'net/http'
+require 'uri'
+require 'cgi'
+require 'pp'
+require 'ostruct'
+
+# ToDo
+#  Allow a choice of media type for GET
+#   --accept "content-type" (and abbreviations)
+#   --header "Add:this"
+#   --user, --password
+#  Basic authentication: request.basic_auth("username", "password")
+#  Follow redirects => 301:  puts response["location"] # All headers are lowercase?
+
+SOH_NAME="SOH"
+SOH_VERSION="0.0.0"
+
+$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new  
+
+# What about direct naming?
+
+# Names
+$mtTurtle           = 'text/turtle;charset=utf-8'
+$mtRDF              = 'application/rdf+xml'
+$mtText             = 'text/plain'
+$mtNQuads           = 'text/n-quads'
+$mtTriG             = 'application/trig'
+$mtSparqlResultsX   = 'application/sparql-results+xml'
+$mtSparqlResultsJ   = 'application/sparql-results+json'
+$mtAppJSON          = 'application/json'
+$mtAppXML           = 'application/xml'
+$mtSparqlResultsTSV = 'application/sparql-results+tsv'
+$mtSparqlResultsCSV = 'application/sparql-results+csv'
+$mtSparqlUpdate     = 'application/sparql-update'
+$mtWWWForm          = 'application/x-www-form-urlencoded'
+$mtSparqlQuery      = "application/sparql-query" ;
+
+# Global media type table.
+$fileMediaTypes = {}
+$fileMediaTypes['ttl']   = $mtTurtle
+$fileMediaTypes['n3']    = 'text/n3; charset=utf-8'
+$fileMediaTypes['nt']    = $mtText
+$fileMediaTypes['rdf']   = $mtRDF
+$fileMediaTypes['owl']   = $mtRDF
+$fileMediaTypes['nq']    = $mtNQuads
+$fileMediaTypes['trig']  = $mtTriG
+
+# Global charset : no entry means "don't set"
+$charsetUTF8      = 'utf-8'
+$charset = {}
+$charset[$mtTurtle]   = 'utf-8'
+$charset[$mtText]     = 'ascii'
+$charset[$mtTriG]     = 'utf-8'
+$charset[$mtNQuads]   = 'ascii'
+
+# Headers
+
+$hContentType         = 'Content-Type'
+# $hContentEncoding     = 'Content-Encoding'
+$hContentLength       = 'Content-Length'
+# $hContentLocation     = 'Content-Location'
+# $hContentRange        = 'Content-Range'
+
+$hAccept              = 'Accept'
+$hAcceptCharset       = 'Accept-Charset'
+$hAcceptEncoding      = 'Accept-Encoding'
+$hAcceptRanges        = 'Accept-Ranges' 
+
+$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"}
+$print_http = false
+
+# Default for GET
+# At least allow anythign (and hope!)
+$accept_rdf="#{$mtRDF};q=0.9 , #{$mtTurtle}"
+# For SPARQL query
+$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}"
+
+# Accept any in case of trouble.
+$accept_rdf="#{$accept_rdf} , */*;q=0.1"
+$accept_results="#{$accept_results} , */*;q=0.1" 
+
+# The media type usually forces the charset.
+$accept_charset=nil
+
+## Who we are.
+## Two styles:
+##    s-query .....
+##    soh query .....
+
+$cmd = File.basename($0)
+if $cmd == 'soh'
+then
+  $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift
+end
+
+if ! $cmd.start_with?('s-') && $cmd != 'soh'
+  $cmd = 's-'+$cmd
+end
+
+## -------- 
+
+def GET(dataset, graph)
+  print "GET #{dataset} #{graph}\n" if $verbose
+  requestURI = target(dataset, graph)
+  headers = {}
+  headers.merge!($headers)
+  headers[$hAccept] = $accept_rdf
+  headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil?
+  get_worker(requestURI, headers)
+end
+
+def get_worker(requestURI, headers)
+  uri = URI.parse(requestURI)
+  request = Net::HTTP::Get.new(uri.request_uri)
+  request.initialize_http_header(headers)
+  print_http_request(uri, request)
+  response_print_body(uri, request)
+end
+
+def HEAD(dataset, graph)
+  print "HEAD #{dataset} #{graph}\n" if $verbose
+  requestURI = target(dataset, graph)
+  headers = {}
+  headers.merge!($headers)
+  headers[$hAccept] = $accept_rdf
+  headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil?
+  uri = URI.parse(requestURI)
+  request = Net::HTTP::Head.new(uri.request_uri)
+  request.initialize_http_header(headers)
+  print_http_request(uri, request)
+  response_no_body(uri, request)
+end
+
+def PUT(dataset, graph, file)
+  print "PUT #{dataset} #{graph} #{file}\n" if $verbose
+  send_body(dataset, graph, file, Net::HTTP::Put)
+end
+
+def POST(dataset, graph, file)
+  print "POST #{dataset} #{graph} #{file}\n" if $verbose
+  send_body(dataset, graph, file, Net::HTTP::Post)
+end
+
+def DELETE(dataset, graph)
+  print "DELETE #{dataset} #{graph}\n" if $verbose
+  requestURI = target(dataset, graph)
+  uri = URI.parse(requestURI)
+  request = Net::HTTP::Delete.new(uri.request_uri)
+  headers = {}
+  headers.merge!($headers)
+  request.initialize_http_header(headers)
+  print_http_request(uri, request)
+  response_no_body(uri, request)
+end
+
+def uri_escape(string)
+  CGI.escape(string)
+end
+
+def target(dataset, graph)
+  return dataset+"?default" if graph == "default"
+  return dataset+"?graph="+uri_escape(graph)
+end
+
+def send_body(dataset, graph, file, method)
+  mt = content_type(file)
+  headers = {}
+  headers.merge!($headers)
+  headers[$hContentType] = mt
+  headers[$hContentLength] = File.size(file).to_s
+  ## p headers
+
+  requestURI = target(dataset, graph)
+  uri = URI.parse(requestURI)
+  
+  request = method.new(uri.request_uri)
+  request.initialize_http_header(headers)
+  print_http_request(uri, request)
+  request.body_stream = File.open(file)
+  response_no_body(uri, request)
+end
+
+def response_no_body(uri, request)
+  http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port)
+  http.read_timeout = nil
+  # check we can connect.
+  begin http.start
+  rescue Exception => e  
+    # puts e.message  
+    #puts e.backtrace.inspect  
+    warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3
+  end
+  response = http.request(request)
+  print_http_response(response)
+  case response
+  when Net::HTTPSuccess, Net::HTTPRedirection
+    # OK
+  when Net::HTTPNotFound
+    warn_exit "404 Not found: #{uri}", 9
+    #print response.body
+  else
+    warn_exit "#{response.code} #{response.message} #{uri}", 9
+    # Unreachable
+      response.error!
+  end
+  # NO BODY IN RESPONSE
+end
+
+def response_print_body(uri, request)
+  http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port)
+  http.read_timeout = nil
+  # check we can connect.
+  begin http.start
+  rescue => e  
+    #puts e.backtrace.inspect  
+    #print e.class
+    warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3
+  end
+
+  # Add a blank line if headers were output.
+  print "\n" if $http_print ;
+
+  begin
+    response = http.request(request) { |res| 
+      print_http_response(res)
+      #puts res.code
+      res.read_body do |segment|
+        print segment
+      end
+    }
+    case response
+    when Net::HTTPSuccess, Net::HTTPRedirection
+      # OK
+    when Net::HTTPNotFound
+      warn_exit "404 Not found: #{uri}", 9
+      #print response.body
+    else
+      warn_exit "#{response.code}: #{uri}", 9
+      # Unreachable
+      response.error!
+    end
+  rescue EOFError => e
+    warn_exit "IO Error: "+e.message, 3
+  end
+end
+
+def print_http_request(uri, request)
+  return unless $print_http
+  #print "Request\n"
+  print request.method," ",uri, "\n"
+  print_headers("  ",request)
+end
+
+def print_http_response(response)
+  return unless $print_http
+  #print "Response\n"
+  print response.code, " ", response.message, "\n"
+  print_headers("  ",response)
+end
+
+def print_headers(marker, headers)
+  headers.each do |k,v| 
+    k = k.split('-').map{|w| w.capitalize}.join('-')+':'
+    printf "%s%-20s %s\n",marker,k,v
+  end
+end
+
+def content_type(file)
+  file =~ /\.([^.]*)$/
+  ext = $1
+  mt = $fileMediaTypes[ext]
+  cs = $charset[mt]
+  mt = mt+';charset='+cs if ! cs.nil?
+  return mt
+end
+
+def charset(content_type)
+  return $charset[content_type]
+end
+
+def warn_exit(msg, rc)
+    warn msg
+    exit rc ;
+end
+
+def parseURI(uri_string)
+  begin
+    return URI.parse(uri_string).to_s
+  rescue URI::InvalidURIError => err
+    warn_exit "Bad URI: <#{uri_string}>", 2
+  end
+end
+
+## ---- Command
+
+def cmd_soh(command=nil)
+  ## Command line
+  options = {}
+  optparse = OptionParser.new do |opts|
+    # Set a banner, displayed at the top
+    # of the help screen.
+    case $cmd
+    when "s-http", "sparql-http", "soh"
+      banner="$cmd [get|post|put|delete] datasetURI graph [file]"
+    when "s-get", "s-head", "s-delete"
+      banner="$cmd  datasetURI graph"
+    end
+
+    opts.banner = $banner
+    # Define the options, and what they do
+    
+    options[:verbose] = false
+    opts.on( '-v', '--verbose', 'Verbose' ) do
+      options[:verbose] = true
+    end
+    
+    options[:version] = false
+    opts.on( '--version', 'Print version and exit' ) do
+      print "#{SOH_NAME} #{SOH_VERSION}\n"
+      exit
+    end
+    
+    # This displays the help screen, all programs are
+    # assumed to have this option.
+    opts.on( '-h', '--help', 'Display this screen and exit' ) do
+      puts opts
+      exit
+    end
+  end
+
+  begin optparse.parse!    
+  rescue OptionParser::InvalidArgument => e
+    warn e
+    exit
+  end
+
+  $verbose = options[:verbose]
+  $print_http = $verbose
+
+  if command.nil?
+    if ARGV.size == 0
+      warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'"
+      exit 1
+    end
+    cmdPrint=ARGV.shift
+    command=cmdPrint.upcase
+  else
+    cmdPrint=command
+  end
+
+  case command
+  when "HEAD", "GET", "DELETE"
+    requiredFile=false
+  when "PUT", "POST"
+    requiredFile=true
+  when "QUERY"
+    cmd_sparql_query
+  when "UPDATE"
+    cmd_sparql_update
+  else
+    warn_exit "Unknown command: #{command}", 2
+  end
+
+  if requiredFile 
+  then
+    if ARGV.size != 3
+      warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 
+    end
+  else
+    if ARGV.size != 2
+      warn_exit "Required: dataset URI and graph URI (or 'default')", 1 
+    end
+  end
+
+  dataset=parseURI(ARGV.shift)
+  # Relative URI?
+  graph=parseURI(ARGV.shift)
+  file=""
+  if requiredFile
+  then
+    file = ARGV.shift if requiredFile
+    if ! File.exist?(file)
+      warn_exit "No such file: "+file, 3
+    end
+    if File.directory?(file)
+      warn_exit "File is a directory: "+file, 3
+    end
+  end
+
+  case command
+  when "GET"
+    GET(dataset, graph)
+  when "HEAD"
+    HEAD(dataset, graph)
+  when "PUT"
+    PUT(dataset, graph, file)
+  when "DELETE"
+    DELETE(dataset, graph)
+  when "POST"
+    POST(dataset, graph, file)
+  else
+    warn_exit "Internal error: Unknown command: #{cmd}", 2
+  end
+  exit 0
+end
+
+## --------
+def string_or_file(arg)
+  return arg if ! arg.match(/^@/)
+  a=(arg[1..-1])
+  open(a, 'rb'){|f| f.read}
+end
+
+## -------- SPARQL Query
+
+## Choose method
+def SPARQL_query(service, query, query_file, forcePOST=false, args2={})
+   if ! query_file.nil?
+    query = open(query_file, 'rb'){|f| f.read}
+  end
+  if forcePOST || query.length >= 2*1024 
+    SPARQL_query_POST(service, query, args2)
+  else
+    SPARQL_query_GET(service, query, args2)
+  end
+end
+
+## By GET
+
+def SPARQL_query_GET(service, query, args2)
+  args = { "query" => query }
+  args.merge!(args2)
+  qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&')
+  action="#{service}?#{qs}"
+  headers={}
+  headers.merge!($headers)
+  headers[$hAccept]=$accept_results
+  get_worker(action, headers)
+end
+
+## By POST
+
+def SPARQL_query_POST(service, query, args2)
+  # DRY - body/no body for each of request and response.
+  post_params={ "query" => query }
+  post_params.merge!(args2)
+  uri = URI.parse(service)
+  headers={}
+  headers.merge!($headers)
+  headers[$hAccept]=$accept_results
+  execute_post_form_body(uri, headers, post_params)
+end
+
+def execute_post_form_body(uri, headers, post_params)
+  request = Net::HTTP::Post.new(uri.request_uri)
+  qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&')
+  headers[$hContentType] = $mtWWWForm
+  headers[$hContentLength] = qs.length.to_s
+  request.initialize_http_header(headers)
+  request.body = qs
+  print_http_request(uri, request)
+  response_print_body(uri, request)
+end
+
+# Usage: -v --help --file= --query=
+def cmd_sparql_query
+  options={}
+  optparse = OptionParser.new do |opts|
+    opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file"
+    opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri|
+      options[:service]=uri
+    end
+    opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file|
+      options[:file]=file
+    end
+    opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv],
+            'Set the output argument') do |type|
+      options[:output]=type
+    end
+    opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], 
+            'Set the accept header type') do |type|
+      options[:accept]=type
+    end
+    options[:verbose] = false
+    opts.on( '--post', 'Force use of POST' ) do
+      options[:post] = true
+    end
+    opts.on( '-v', '--verbose', 'Verbose' ) do
+      options[:verbose] = true
+    end
+    opts.on( '--version', 'Print version and exit' ) do
+      print "#{SOH_NAME} #{SOH_VERSION}\n"
+      exit
+    end 
+    opts.on( '-h', '--help', 'Display this screen and exit' ) do
+      puts opts
+      exit
+    end
+  end
+
+  begin optparse.parse!    
+  rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
+    warn e
+    exit 1
+  end
+
+  $verbose = options[:verbose]
+  $print_http = $verbose
+  usePOST = options[:post]
+
+  service = options[:service]
+  warn_exit 'No service specified.  Required --service=URI',1 if service.nil?
+
+  # Query
+  query=nil
+  query_file=options[:file]
+  if query_file.nil? && ARGV.size == 0
+  then
+    warn_exit 'No query specified.',1
+    end
+  if query_file.nil?
+    query = ARGV.shift
+    if query.match(/^@/)
+      query_file = query[1..-1]
+      query = nil
+    end
+  end
+
+  # --output ==> output= (non-standard)
+  args={}
+  case options[:output]
+  when nil
+  when  "json","xml","text","csv","tsv"
+    args['output'] = options[:output]
+  when :json,:xml,:text,:csv,:tsv
+    args['output'] = options[:output].to_s
+  else
+    warn_exit "Unrecognized output type: "+options[:output],2
+  end
+
+  # --accept
+  # options[:accept]
+
+  print "SPARQL #{service}\n" if $verbose
+  #args={"output"=>"text"}
+  SPARQL_query(service, query, query_file, usePOST, args)
+  exit(0)
+end
+
+## -------- SPARQL Update
+
+# Update sent as a WWW form.
+def SPARQL_update_by_form(service, update, args2={})
+  args = {}
+  args.merge!(args2)
+  headers={}
+  headers.merge!($headers)
+  # args? encode?
+  body="update="+uri_escape(update)
+  headers[$hContentType] = $mtWWWForm
+  headers[$hContentLength] = body.length.to_s
+  uri = URI.parse(service)
+  execute_post_form(uri, headers, body)
+end
+
+# DRY - query form.
+def execute_post_form(uri, headers, body)
+  request = Net::HTTP::Post.new(uri.request_uri)
+  request.initialize_http_header(headers)
+  request.body = body
+  print_http_request(uri, request)
+  response_no_body(uri, request)
+end
+
+def SPARQL_update(service, update, args2={})
+  args = {}
+  args.merge!(args2)
+  headers={}
+  headers.merge!($headers)
+  headers[$hContentType] = $mtSparqlUpdate
+  uri = URI.parse(service)
+  request = Net::HTTP::Post.new(uri.request_uri)
+  request.initialize_http_header(headers)
+  request.body = update
+  print_http_request(uri, request)
+  response_no_body(uri, request)
+end
+
+def cmd_sparql_update(by_raw_post=true)
+  # Share with cmd_sparql_query
+  options={}
+  optparse = OptionParser.new do |opts|
+    opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file"
+    opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri|
+      options[:service]=uri
+    end
+    opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file|
+      options[:file]=file
+    end
+    options[:verbose] = false
+    opts.on( '-v', '--verbose', 'Verbose' ) do
+      options[:verbose] = true
+    end
+    opts.on( '--version', 'Print version and exit' ) do
+      print "#{SOH_NAME} #{SOH_VERSION}\n"
+      exit
+    end 
+    opts.on( '-h', '--help', 'Display this screen and exit' ) do
+      puts opts
+      exit
+    end
+  end
+
+  begin optparse.parse!    
+  rescue OptionParser::InvalidArgument => e
+    warn e
+    exit
+  end
+
+  $verbose = options[:verbose]
+  $print_http = $verbose
+
+  service = options[:service]
+  warn_exit 'No service specified. Required --service=URI',1   if service.nil?
+  
+  update=nil
+  update_file=options[:file]
+
+  if update_file.nil? && ARGV.size == 0
+  then
+    warn_exit 'No update specified.',1
+    end
+  if update_file.nil?
+    update = ARGV.shift
+    if update.match(/^@/)
+      update_file = update[1..-1]
+      update = nil
+    end
+  end
+  
+  print "SPARQL-Update #{service}\n" if $verbose
+  args={}
+
+  # Reads in the file :-(
+  if update.nil?
+  then
+    update = open(update_file, 'rb'){|f| f.read}
+  else
+    update = string_or_file(update)
+  end
+
+  if by_raw_post
+    SPARQL_update(service, update, args)
+  else
+    SPARQL_update_by_form(service, update, args)
+  end
+  exit(0)
+end
+
+## -------
+
+case $cmd
+when "s-http", "sparql-http", "soh"
+  $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]"
+  cmd_soh
+when "s-get", "s-head", "s-put", "s-delete", "s-post"
+
+  case $cmd
+  when "s-get", "s-head", "s-delete"
+    $banner="#{$cmd} datasetURI graph"
+  when "s-put", "s-post"
+    $banner="#{$cmd} datasetURI graph file"
+  end
+  cmd2 = $cmd.sub(/^s-/, '').upcase
+  cmd_soh cmd2
+
+when "s-query", "sparql-query"
+  cmd_sparql_query
+when "s-update", "sparql-update"
+  cmd_sparql_update true
+when "s-update-form", "sparql-update-form"
+  cmd_sparql_update false
+else 
+  warn_exit "Unknown: "+$cmd, 1
+end

Propchange: jena/branches/jena-fuseki-new-ui/bin/soh
------------------------------------------------------------------------------
    svn:executable = *

Modified: jena/branches/jena-fuseki-new-ui/config2.ttl
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/config2.ttl?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/config2.ttl (original)
+++ jena/branches/jena-fuseki-new-ui/config2.ttl Thu Dec 26 16:57:36 2013
@@ -6,12 +6,12 @@
 @prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
 @prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .
 
-## ## ## Always.
-## ## @prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
-## ## [] ja:loadClass "com.hp.hpl.jena.tdb.TDB" .
-## ## tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .
-## ## tdb:GraphTDB    rdfs:subClassOf  ja:Model .
-## ## ##
+## ## Always.
+## @prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
+## [] ja:loadClass "com.hp.hpl.jena.tdb.TDB" .
+## tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .
+## tdb:GraphTDB    rdfs:subClassOf  ja:Model .
+## ##
 
 <#service_tdb> rdf:type fuseki:Service ;
     rdfs:label                      "TDB Service" ;

Modified: jena/branches/jena-fuseki-new-ui/src-dev/dev/PROJECT.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src-dev/dev/PROJECT.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src-dev/dev/PROJECT.java (original)
+++ jena/branches/jena-fuseki-new-ui/src-dev/dev/PROJECT.java Thu Dec 26 16:57:36 2013
@@ -19,9 +19,10 @@
 package dev;
 
 public class PROJECT {
-    
-    // WebConent tidying
-    //   SPARQL_Update
+    // Naming 
+    //  fuseki:Service is the endpoints = dataset
+
+    // WebContent tidying
     //   DEFs
     
     // Webapp-ization
@@ -30,10 +31,6 @@ public class PROJECT {
     //   ContextPath
     //   Fuseki.configure/defaultConfiguration
     
-    // 1/ have command line insert direct into the DatasetRegistry?
-    // 2/ 
-    
-    
     // All TODO and XXX
     // Configuration and startup.
     // Change to using a real webapp.
@@ -45,7 +42,6 @@ public class PROJECT {
     
     // Document (write/update) all protocol modes.
     
-    // The whole X_Config thing
     // Check compression enabled for UberServlet
 }
 

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/DEF.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/DEF.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/DEF.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/DEF.java Thu Dec 26 16:57:36 2013
@@ -20,38 +20,35 @@ package org.apache.jena.fuseki;
 
 import org.apache.jena.atlas.web.AcceptList ;
 import org.apache.jena.atlas.web.MediaType ;
-import org.apache.jena.riot.WebContent ;
+import static org.apache.jena.riot.WebContent.* ;
 
 public class DEF
 {
-    public static final MediaType acceptRDFXML          = MediaType.create(WebContent.contentTypeRDFXML) ;
-    public static final MediaType acceptNQuads          = MediaType.create(WebContent.contentTypeNQuads) ;
-    public static final MediaType acceptRSXML           = MediaType.create(WebContent.contentTypeResultsXML) ;
-    
-    private static final MediaType acceptTurtle1       = MediaType.create(WebContent.contentTypeTurtle) ;
-    private static final MediaType acceptTurtle2       = MediaType.create(WebContent.contentTypeTurtleAlt1) ;
-    private static final MediaType acceptTurtle3       = MediaType.create(WebContent.contentTypeTurtleAlt2) ;
-    private static final MediaType acceptNTriples      = MediaType.create(WebContent.contentTypeNTriples) ;
-    private static final MediaType acceptNTriplesAlt   = MediaType.create(WebContent.contentTypeNTriplesAlt) ;
-    private static final MediaType acceptTriG          = MediaType.create(WebContent.contentTypeTriG) ;
-    private static final MediaType acceptTriGAlt1      = MediaType.create(WebContent.contentTypeTriGAlt1) ;
-    private static final MediaType acceptTriGAlt2      = MediaType.create(WebContent.contentTypeTriGAlt2) ;
-    private static final MediaType acceptRDFJSON       = MediaType.create(WebContent.contentTypeRDFJSON) ; 
-    private static final MediaType acceptNQuadsAlt1    = MediaType.create(WebContent.contentTypeNQuadsAlt1) ;
-    private static final MediaType acceptNQuadsAlt2    = MediaType.create(WebContent.contentTypeNQuadsAlt2) ;
+    public static final MediaType acceptRDFXML        = MediaType.create(contentTypeRDFXML) ;
+    public static final MediaType acceptNQuads        = MediaType.create(contentTypeNQuads) ;
+    public static final MediaType acceptRSXML         = MediaType.create(contentTypeResultsXML) ;
 
-    public static final AcceptList rdfOffer           = AcceptList.create(acceptTurtle1, acceptTurtle2, acceptTurtle3, 
-                                                                          acceptNTriples, acceptNTriplesAlt,
-                                                                          acceptRDFXML, 
-                                                                          acceptRDFJSON) ;
+    public static final AcceptList rdfOffer           = AcceptList.create(contentTypeTurtle, 
+                                                                          contentTypeTurtleAlt1,
+                                                                          contentTypeTurtleAlt2,
+                                                                          contentTypeNTriples,
+                                                                          contentTypeNTriplesAlt,
+                                                                          contentTypeRDFXML,
+                                                                          contentTypeRDFJSON
+                                                                          ) ;
     
-    public static final AcceptList quadsOffer         = AcceptList.create(acceptTriG, acceptTriGAlt1, acceptTriGAlt2,
-                                                                          acceptNQuads, acceptNQuadsAlt1, acceptNQuadsAlt2 
+    public static final AcceptList quadsOffer         = AcceptList.create(contentTypeTriG,
+                                                                          contentTypeTriGAlt1,
+                                                                          contentTypeTriGAlt2,
+                                                                          contentTypeNQuads,
+                                                                          contentTypeNQuadsAlt1,
+                                                                          contentTypeNQuadsAlt2 
                                                                           ) ;
     
-    public static final AcceptList rsOffer            = AcceptList.create(WebContent.contentTypeResultsJSON,
-                                                                          WebContent.contentTypeTextCSV,
-                                                                          WebContent.contentTypeTextTSV,
-                                                                          WebContent.contentTypeResultsXML,
-                                                                          WebContent.contentTypeTextPlain) ;
+    public static final AcceptList rsOffer            = AcceptList.create(contentTypeResultsJSON,
+                                                                          contentTypeTextCSV,
+                                                                          contentTypeTextTSV,
+                                                                          contentTypeResultsXML,
+                                                                          contentTypeTextPlain
+                                                                          ) ;
 }

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java Thu Dec 26 16:57:36 2013
@@ -39,7 +39,6 @@ import org.apache.jena.atlas.lib.Interna
 import org.apache.jena.atlas.lib.StrUtils ;
 import org.apache.jena.atlas.web.ContentType ;
 import org.apache.jena.fuseki.FusekiLib ;
-import org.apache.jena.fuseki.X_Config ;
 import org.apache.jena.fuseki.server.* ;
 import org.apache.jena.fuseki.servlets.ActionLib ;
 import org.apache.jena.fuseki.servlets.HttpAction ;
@@ -81,8 +80,8 @@ public class ActionDatasets extends Acti
     private static final String paramDatasetType    = "dbType" ;
     private static final String tDatabasetTDB       = "tdb" ;
     private static final String tDatabasetMem       = "mem" ;
-    private static final String templateMemFN = "templates/config-mem" ;
-    private static final String templateTDBFN = "templates/config-tdb" ;
+    private static final String templateMemFN       = "templates/config-mem" ;
+    private static final String templateTDBFN       = "templates/config-tdb" ;
 
     public ActionDatasets() { super() ; }
     
@@ -220,6 +219,9 @@ public class ActionDatasets extends Acti
             else
                 assemblerFromBody(action, dest) ;
             
+            
+            //FusekiConfig.readConfiguration(model) ;
+            
             Statement stmt = getOne(model, null, pServiceName, null) ;
             if ( stmt == null ) {
                 StmtIterator sIter = model.listStatements(null, pServiceName, (RDFNode)null ) ;
@@ -253,7 +255,7 @@ public class ActionDatasets extends Acti
             
             // Need to be in Resource space at this point.
             DatasetRef dsRef = FusekiConfig.processService(subject) ;
-            X_Config.registerDataset(datasetPath, dsRef) ;
+            FusekiConfig.registerDataset(datasetPath, dsRef) ;
             action.getResponse().setContentType(WebContent.contentTypeTextPlain); 
             ServletOutputStream out = action.getResponse().getOutputStream() ;
             out.println("That went well") ;

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiConfig.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiConfig.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiConfig.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiConfig.java Thu Dec 26 16:57:36 2013
@@ -18,11 +18,16 @@
 
 package org.apache.jena.fuseki.server ;
 
+import static java.lang.String.format ;
+import static org.apache.jena.fuseki.Fuseki.serverLog ;
+
 import java.io.File ;
+import java.io.FileFilter ;
 import java.io.FilenameFilter ;
 import java.lang.reflect.Method ;
 import java.util.ArrayList ;
 import java.util.Arrays ;
+import java.util.Collections ;
 import java.util.List ;
 
 import org.apache.jena.atlas.iterator.Iter ;
@@ -30,6 +35,7 @@ import org.apache.jena.atlas.lib.StrUtil
 import org.apache.jena.fuseki.Fuseki ;
 import org.apache.jena.fuseki.FusekiConfigException ;
 import org.apache.jena.fuseki.HttpNames ;
+import org.apache.jena.riot.RDFDataMgr ;
 import org.slf4j.Logger ;
 
 import com.hp.hpl.jena.assembler.Assembler ;
@@ -41,6 +47,7 @@ import com.hp.hpl.jena.sparql.core.Datas
 import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ;
 import com.hp.hpl.jena.sparql.core.DatasetGraphReadOnly ;
 import com.hp.hpl.jena.sparql.core.assembler.AssemblerUtils ;
+import com.hp.hpl.jena.sparql.mgt.ARQMgt ;
 import com.hp.hpl.jena.update.UpdateAction ;
 import com.hp.hpl.jena.update.UpdateFactory ;
 import com.hp.hpl.jena.update.UpdateRequest ;
@@ -55,7 +62,52 @@ public class FusekiConfig {
     
     private static Logger log      = Fuseki.configLog ;
 
+    private static FileFilter visibleFilesX = null ; 
+        
+    private static FilenameFilter visibleFiles = 
+        new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                if ( name.startsWith(".") )
+                    return false ;
+                File f = new File(dir, name) ;
+                return f.isFile() ;
+            }
+        } ;
+
+    // ---- DatasetRef used where there isn't a real Dataset e.g. the SPARQL processor.
+    
+    private static DatasetRef   noDataset = new DatasetRef() ;
+
+    private static DatasetGraph dummyDSG  = new DatasetGraphReadOnly(DatasetGraphFactory.createMemFixed()) ;
+    static {
+        noDataset.name = "" ;
+        noDataset.dataset = dummyDSG ;
+        noDataset.query.endpoints.add(HttpNames.ServiceQuery) ;
+        noDataset.query.endpoints.add(HttpNames.ServiceQueryAlt) ;
+        noDataset.allowDatasetUpdate = false ;
+        noDataset.activate() ;
+        // Don't register it.
+        // This is used as a placeholder and shoudl not be found by
+        // "all datasets"
+        // DatasetRegistry.get().put("", noDataset) ;
+    }
+
+    // ---- DatasetRef used where there isn't a real Dataset e.g. the SPARQL processor.
+    
+    /**
+     * Return the DatasetRef (read-only) for when there is no dataset, just a
+     * SPARQL Query processor
+     */
+    public static DatasetRef serviceOnlyDatasetRef() {
+        return noDataset ;
+    }
+
+    /** Setup the server configuration based on ServerInitialConfig (from command line) */ 
     public static List<DatasetRef> defaultConfiguration(ServerInitialConfig params) {
+        if ( params.fusekiConfigFile != null )
+            log.warn("Configuration file found while processing command line dataset configuration") ;
+        
         DatasetRef dbDesc = new DatasetRef() ;
         dbDesc.name = DatasetRef.canocialDatasetPath(params.datasetPath) ;
         dbDesc.dataset = params.dsg ;
@@ -72,18 +124,60 @@ public class FusekiConfig {
         return Arrays.asList(dbDesc) ; 
     }
 
-    // NEW
-    public static final String configurationsDirectory = "configure" ;
-    public static final String fusekiService = "http://jena.apache.org/fuseki#Service" ;
-    private static FilenameFilter visibleFiles = 
-        new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-                return ! name.startsWith(".") ;
-            }
-        } ;
+//    /** Read one of more dataset descriptions in a model */
+//    public static List<DatasetRef> readConfiguration(Model m) {
+//        additionalRDF(m) ;
+//        List<Resource> services = getByType(FusekiVocab.fusekiService, m) ; 
+//            
+//        if ( services.size() == 0 ) {
+//            log.error("No services found") ;
+//            throw new FusekiConfigException() ;
+//        }
+//        
+//        // Remove?
+//        if ( services.size() > 1 ) {
+//            log.error("Multiple services found") ;
+//            throw new FusekiConfigException() ;
+//        }
+//        
+//        List<DatasetRef> refs = new ArrayList<DatasetRef>() ;
+//        
+//        Resource service = services.get(0) ;
+//        String name = ((Literal)getOne(service, "fuseki:name")).getLexicalForm() ;
+//        log.info("name = "+name); 
+//        DatasetRef dsDesc = processService(service) ;
+//        String datasetPath = dsDesc.name ;
+//        refs.add(dsDesc) ;
+//        return refs ;
+//    }
     
-    public static List<DatasetRef> additional() {
+    /** Has side effects in server setup */
+    public static List<DatasetRef> readConfigFile(String filename) {
+        // Old-style config file.
+        Model model = FileManager.get().loadModel(filename) ;
+        additionalRDF(model) ;
+        server(model) ;
+        return servicesAndDatasets(model) ;
+    }
+
+    public static List<DatasetRef> readConfigurationDirectory(String dir) {
+        List<DatasetRef> datasets = new ArrayList<DatasetRef>() ;
+        File d = new File(dir) ;
+        String[] aFiles = d.list(visibleFiles) ;
+        if ( aFiles == null ) {
+            log.warn("Not found: directory for assembler files for services: '"+dir+"'") ;
+            return Collections.emptyList() ;
+        }
+        for ( String assemFile : aFiles ) {
+            Model m = RDFDataMgr.loadModel(assemFile) ;
+            // Same code as ActionDatasets
+        }
+        
+        return datasets ;
+    }
+        
+        
+    public static List<DatasetRef> readSystemDatabase(Dataset ds) {
         String qs = StrUtils.strjoinNL
             (SystemState.PREFIXES ,
              "SELECT * {" ,
@@ -96,7 +190,6 @@ public class FusekiConfig {
         
         List<DatasetRef> refs = new ArrayList<DatasetRef>() ;
         
-        Dataset ds = SystemState.getDataset() ;
         ResultSet rs = query(qs, ds) ;
         
 //        ResultSetFormatter.out(rs); 
@@ -119,65 +212,7 @@ public class FusekiConfig {
         return refs ;
     }
     
-    public static List<DatasetRef> readConfiguration(Model m) {
-        additionalRDF(m) ;
-        Resource t = m.createResource(fusekiService) ;
-        List<Resource> services = getByType(t, m) ; 
-            
-        if ( services.size() == 0 ) {
-            log.error("No services found") ;
-            throw new FusekiConfigException() ;
-        }
-        
-        // Remove?
-        if ( services.size() > 1 ) {
-            log.error("Multiple services found") ;
-            throw new FusekiConfigException() ;
-        }
-        
-        List<DatasetRef> refs = new ArrayList<DatasetRef>() ;
-        
-        Resource service = services.get(0) ;
-        String name = ((Literal)getOne(service, "fuseki:name")).getLexicalForm() ;
-        log.info("name = "+name); 
-        DatasetRef dsDesc = FusekiConfig.processService(service) ;
-        String datasetPath = dsDesc.name ;
-        refs.add(dsDesc) ;
-        return refs ;
-    }
-    
-    private static Model additionalRDF(Model m ) {
-        String x1 = StrUtils.strjoinNL
-            ( SystemState.PREFIXES, 
-              "INSERT                    { [] ja:loadClass 'com.hp.hpl.jena.tdb.TDB' }",
-              "WHERE { FILTER NOT EXISTS { [] ja:loadClass 'com.hp.hpl.jena.tdb.TDB' } }"
-             ) ;
-        String x2 = StrUtils.strjoinNL
-            (SystemState.PREFIXES,
-             "INSERT DATA {",
-             "   tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .",
-             "   tdb:GraphTDB    rdfs:subClassOf  ja:Model .",
-             "}" 
-             ) ;
-        execute(m, x1) ;
-        execute(m, x2) ;
-        return m ;
-        
-    }
-    
-    private static void execute(Model m, String x) {
-        UpdateRequest req = UpdateFactory.create(x) ;
-        UpdateAction.execute(req, m);
-    }
-    
-    // OLD
-    
-    /** Has side effects in server setup */
-    public static List<DatasetRef> configure(String filename) {
-        Model model = FileManager.get().loadModel(filename) ;
-        server(model) ;
-        return servicesAndDatasets(model) ;
-    }
+    // ---- Old style config file processing
     
     private static void server(Model model) {
         // Find one server.
@@ -195,6 +230,7 @@ public class FusekiConfig {
     }
     
     private static List<DatasetRef> servicesAndDatasets(Model model) {
+        // Old style configuration file : server to services.
         // ---- Services
         ResultSet rs = query("SELECT * { ?s fu:services [ list:member ?member ] }", model) ;
         if ( !rs.hasNext() )
@@ -211,32 +247,6 @@ public class FusekiConfig {
         return services ;
     }
 
-    // DatasetRef used where there isn't a real Dataset e.g. the SPARQL
-    // processor.
-
-    private static DatasetRef   noDataset = new DatasetRef() ;
-    private static DatasetGraph dummyDSG  = new DatasetGraphReadOnly(DatasetGraphFactory.createMemFixed()) ;
-    static {
-        noDataset.name = "" ;
-        noDataset.dataset = dummyDSG ;
-        noDataset.query.endpoints.add(HttpNames.ServiceQuery) ;
-        noDataset.query.endpoints.add(HttpNames.ServiceQueryAlt) ;
-        noDataset.allowDatasetUpdate = false ;
-        noDataset.activate() ;
-        // Don't register it.
-        // This is used as a placeholder and shoudl not be found by
-        // "all datasets"
-        // DatasetRegistry.get().put("", noDataset) ;
-    }
-
-    /**
-     * Return the DatasetRef (read-only) for when there is no dataset, just a
-     * SPARQL Query processor
-     */
-    public static DatasetRef serviceOnlyDatasetRef() {
-        return noDataset ;
-    }
-
     private static void processServer(Resource server) {
         // Global, currently.
         AssemblerUtils.setContext(server, Fuseki.getContext()) ;
@@ -263,9 +273,11 @@ public class FusekiConfig {
                 className = ((Literal)rn).getLexicalForm() ;
             /* Loader. */loadAndInit(className) ;
         }
-        // ----
     }
 
+
+    // ---- DatasetRef used where there isn't a real Dataset e.g. the SPARQL processor.
+
     private static void loadAndInit(String className) {
         try {
             Class<? > classObj = Class.forName(className) ;
@@ -281,6 +293,7 @@ public class FusekiConfig {
         }
     }
 
+    /** Build a DatasetRef from an assember starting at Resource svc */
     public static DatasetRef processService(Resource svc) {
         log.info("Service: " + nodeLabel(svc)) ;
         DatasetRef sDesc = new DatasetRef() ;
@@ -313,6 +326,91 @@ public class FusekiConfig {
 
     }
 
+    
+    /** Initial configuration - for all the datasets, call the per dataset initization  */ 
+    public static void configureDatasets(List<DatasetRef> datasets) {
+        for (DatasetRef dsDesc : datasets)
+            configureOneDataset(dsDesc) ;
+    }
+
+    public static void configureOneDataset(DatasetRef dsDesc) {
+        String datasetPath = DatasetRef.canocialDatasetPath(dsDesc.name) ;
+        registerDataset(datasetPath, dsDesc) ;
+        // Add JMX beans to record dataset and it's services.
+        addJMX(dsDesc) ;
+    }
+    
+    /** Register a DatasetRef, which should no already be registered */  
+    
+    public static void registerDataset(String datasetPath, DatasetRef dsDesc) {
+        dsDesc.enable() ;
+        if ( DatasetRegistry.get().isRegistered(datasetPath) )
+            throw new FusekiConfigException("Already registered: key = "+datasetPath) ;
+        DatasetRegistry.get().put(datasetPath, dsDesc) ;
+        serverLog.info(format("Dataset path = %s", datasetPath)) ;
+        addJMX(dsDesc) ;
+    }
+    
+//    public static void addJMX() {
+//        DatasetRegistry registry = DatasetRegistry.get() ;
+//        for (String ds : registry.keys()) {
+//            DatasetRef dsRef = registry.get(ds) ;
+//            addJMX(dsRef) ;
+//        }
+//    }
+
+    private static void addJMX(DatasetRef dsRef) {
+        String x = dsRef.name ;
+        // if ( x.startsWith("/") )
+        // x = x.substring(1) ;
+        ARQMgt.register(Fuseki.PATH + ".dataset:name=" + x, dsRef) ;
+        // For all endpoints
+        for (ServiceRef sRef : dsRef.getServiceRefs()) {
+            ARQMgt.register(Fuseki.PATH + ".dataset:name=" + x + "/" + sRef.name, sRef) ;
+        }
+    }
+
+    public static void removeJMX() {
+        DatasetRegistry registry = DatasetRegistry.get() ;
+        for (String ds : registry.keys()) {
+            DatasetRef ref = registry.get(ds) ;
+            removeJMX(ref) ;
+        }
+    }
+
+    private static void removeJMX(DatasetRef dsRef) {
+        String x = dsRef.getName() ;
+        ARQMgt.unregister(Fuseki.PATH + ".dataset:name=" + x) ;
+        for (ServiceRef sRef : dsRef.getServiceRefs()) {
+            ARQMgt.unregister(Fuseki.PATH + ".dataset:name=" + x + "/" + sRef.name) ;
+        }
+    }
+
+    
+    private static Model additionalRDF(Model m) {
+        String x1 = StrUtils.strjoinNL
+            ( SystemState.PREFIXES, 
+              "INSERT                    { [] ja:loadClass 'com.hp.hpl.jena.tdb.TDB' }",
+              "WHERE { FILTER NOT EXISTS { [] ja:loadClass 'com.hp.hpl.jena.tdb.TDB' } }"
+             ) ;
+        String x2 = StrUtils.strjoinNL
+            (SystemState.PREFIXES,
+             "INSERT DATA {",
+             "   tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .",
+             "   tdb:GraphTDB    rdfs:subClassOf  ja:Model .",
+             "}" 
+             ) ;
+        execute(m, x1) ;
+        execute(m, x2) ;
+        return m ;
+    }
+
+    private static void execute(Model m, String x) {
+        UpdateRequest req = UpdateFactory.create(x) ;
+        UpdateAction.execute(req, m);
+    }
+
+    // Helpers
     private static RDFNode getOne(Resource svc, String property) {
         String ln = property.substring(property.indexOf(':') + 1) ;
         ResultSet rs = query("SELECT * { ?svc " + property + " ?x}", svc.getModel(), "svc", svc) ;
@@ -339,6 +437,8 @@ public class FusekiConfig {
         }
     }
 
+//    // ---- Helper code
+//    
     private static ResultSet query(String string, Model m) {
         return query(string, m, null, null) ;
     }

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiServletContextListener.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiServletContextListener.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiServletContextListener.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiServletContextListener.java Thu Dec 26 16:57:36 2013
@@ -18,6 +18,7 @@
 
 package org.apache.jena.fuseki.server;
 
+import java.util.ArrayList ;
 import java.util.List ;
 
 import javax.servlet.ServletContext ;
@@ -26,7 +27,6 @@ import javax.servlet.ServletContextListe
 
 import org.apache.jena.atlas.lib.DS ;
 import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.X_Config ;
 import org.slf4j.Logger ;
 
 public class FusekiServletContextListener implements ServletContextListener {
@@ -40,9 +40,10 @@ public class FusekiServletContextListene
 
     // --- later: Play the "hunt the config files" game 
     // Default.
-    static public String rootDirectory     = "/usr/share/fuseki" ;
-    static public String configurationFile = rootDirectory + "/config-fuseki.ttl" ;
+    static public final String rootDirectory     = "/usr/share/fuseki" ;
+    static public final String configurationFile = rootDirectory + "/config-fuseki.ttl" ;
     // ----
+    static public final String configDir = "configuration" ;
     
     private Boolean initialized = false ;
 
@@ -72,10 +73,22 @@ public class FusekiServletContextListene
             }
             
             if ( initialSetup != null ) {
-                List<DatasetRef> datasets = findDatasets(initialSetup) ;
-                List<DatasetRef> additionalDatasets = FusekiConfig.additional() ;
-                datasets.addAll(additionalDatasets) ;
-                X_Config.configureDatasets(datasets);
+                // Places to look:
+                // 1 - Fuseki v1 config file (deprecated)
+                // 2 - Directory of assemblers files "assemblers"
+                // 3 - The system database
+                 
+                List<DatasetRef> configFileDBs = findDatasets(initialSetup) ;
+                List<DatasetRef> directoryDBs = FusekiConfig.readConfigurationDirectory(configDir) ;
+                List<DatasetRef> systemDBs = FusekiConfig.readSystemDatabase(SystemState.getDataset()) ;
+                
+                List<DatasetRef> datasets = new ArrayList<DatasetRef>() ;
+                datasets.addAll(configFileDBs) ;
+                datasets.addAll(directoryDBs) ;
+                datasets.addAll(systemDBs) ;
+                
+                // Having found them, set them all running.
+                FusekiConfig.configureDatasets(datasets);
             }
         }
     }
@@ -87,7 +100,7 @@ public class FusekiServletContextListene
 
         if ( params.fusekiConfigFile != null ) {
             Fuseki.configLog.info("Configuration file: " + params.fusekiConfigFile) ;
-            List<DatasetRef> cmdLineDatasets = FusekiConfig.configure(params.fusekiConfigFile) ;
+            List<DatasetRef> cmdLineDatasets = FusekiConfig.readConfigFile(params.fusekiConfigFile) ;
             datasets.addAll(cmdLineDatasets) ;
         } else {
             List<DatasetRef> cmdLineDatasets = FusekiConfig.defaultConfiguration(params) ;

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/FusekiVocab.java Thu Dec 26 16:57:36 2013
@@ -32,6 +32,9 @@ public class FusekiVocab
 
     public static final Resource tServer = resource("Server") ;
 
+    // XXX Constants
+    public static final Resource fusekiService = resource("Service") ;
+
     public static final Property pServices = property("services") ;
     public static final Property pServiceName = property("name") ;
     

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java Thu Dec 26 16:57:36 2013
@@ -31,7 +31,6 @@ import javax.servlet.DispatcherType ;
 import org.apache.jena.atlas.lib.NotImplemented ;
 import org.apache.jena.fuseki.Fuseki ;
 import org.apache.jena.fuseki.FusekiException ;
-import org.apache.jena.fuseki.X_Config ;
 import org.apache.jena.fuseki.servlets.FusekiFilter ;
 import org.eclipse.jetty.security.* ;
 import org.eclipse.jetty.security.authentication.BasicAuthenticator ;
@@ -133,7 +132,7 @@ public class SPARQLServer {
         } catch (Exception ex) {
             Fuseki.serverLog.warn("SPARQLServer: Exception while stopping server: " + ex.getMessage(), ex) ;
         }
-        X_Config.removeJMX() ;
+        FusekiConfig.removeJMX() ;
     }
 
     /**

Modified: jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/ServerInitialConfig.java
URL: http://svn.apache.org/viewvc/jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/ServerInitialConfig.java?rev=1553511&r1=1553510&r2=1553511&view=diff
==============================================================================
--- jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/ServerInitialConfig.java (original)
+++ jena/branches/jena-fuseki-new-ui/src/main/java/org/apache/jena/fuseki/server/ServerInitialConfig.java Thu Dec 26 16:57:36 2013
@@ -22,8 +22,9 @@ import com.hp.hpl.jena.sparql.core.Datas
 
 /** Dataset setup (command line, config file) for a dataset (or several if config file) */
 public class ServerInitialConfig {
+    // Either dsg/datasetPath are null or fusekiConfigFile is null.
     public DatasetGraph dsg               = null ;
-    public String       datasetPath       = null ;
+    public String datasetPath             = null ;
     public boolean      allowUpdate       = false ;
     public String       fusekiConfigFile  = null ;
 }