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/01/30 20:02:33 UTC

svn commit: r1440588 - in /jena/Experimental/sparql-cache: ./ .settings/ src/ src/main/ src/main/java/ src/main/java/dev/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/jena/ src/main/java/org/apache/jena/atlas/ src/main/java/org...

Author: andy
Date: Wed Jan 30 19:02:32 2013
New Revision: 1440588

URL: http://svn.apache.org/viewvc?rev=1440588&view=rev
Log:
Prototype external cache for a SPARQL endpoint.

Added:
    jena/Experimental/sparql-cache/.classpath
    jena/Experimental/sparql-cache/.gitignore
    jena/Experimental/sparql-cache/.project
    jena/Experimental/sparql-cache/.settings/
    jena/Experimental/sparql-cache/.settings/org.eclipse.jdt.core.prefs
    jena/Experimental/sparql-cache/.settings/org.eclipse.m2e.core.prefs
    jena/Experimental/sparql-cache/DEPENDENCIES
    jena/Experimental/sparql-cache/LICENCE
    jena/Experimental/sparql-cache/NOTICE
    jena/Experimental/sparql-cache/README.markdown
    jena/Experimental/sparql-cache/http-delete   (with props)
    jena/Experimental/sparql-cache/http-get   (with props)
    jena/Experimental/sparql-cache/http-post   (with props)
    jena/Experimental/sparql-cache/http-put   (with props)
    jena/Experimental/sparql-cache/log4j.properties
    jena/Experimental/sparql-cache/logging.properties
    jena/Experimental/sparql-cache/pom.xml
    jena/Experimental/sparql-cache/run   (with props)
    jena/Experimental/sparql-cache/src/
    jena/Experimental/sparql-cache/src/main/
    jena/Experimental/sparql-cache/src/main/java/
    jena/Experimental/sparql-cache/src/main/java/dev/
    jena/Experimental/sparql-cache/src/main/java/dev/Main.scala
    jena/Experimental/sparql-cache/src/main/java/org/
    jena/Experimental/sparql-cache/src/main/java/org/apache/
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/AServlet.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/Http.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/HttpOperation.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/JettyServer.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/SLog.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/CacheFuture.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/QueryEngineCaching.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/RS.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SPARQLResult.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCache.scala
    jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCacheServer.scala
    jena/Experimental/sparql-cache/src/test/
    jena/Experimental/sparql-cache/src/test/java/

Added: jena/Experimental/sparql-cache/.classpath
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/.classpath?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/.classpath (added)
+++ jena/Experimental/sparql-cache/.classpath Wed Jan 30 19:02:32 2013
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="classes"/>
+</classpath>

Added: jena/Experimental/sparql-cache/.gitignore
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/.gitignore?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/.gitignore (added)
+++ jena/Experimental/sparql-cache/.gitignore Wed Jan 30 19:02:32 2013
@@ -0,0 +1,4 @@
+target
+classes
+.scala_dependencies
+.cache

Added: jena/Experimental/sparql-cache/.project
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/.project?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/.project (added)
+++ jena/Experimental/sparql-cache/.project Wed Jan 30 19:02:32 2013
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>SPARQLCache</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.scala-ide.sdt.core.scalabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.scala-ide.sdt.core.scalanature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: jena/Experimental/sparql-cache/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/.settings/org.eclipse.jdt.core.prefs?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/.settings/org.eclipse.jdt.core.prefs (added)
+++ jena/Experimental/sparql-cache/.settings/org.eclipse.jdt.core.prefs Wed Jan 30 19:02:32 2013
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.7

Added: jena/Experimental/sparql-cache/.settings/org.eclipse.m2e.core.prefs
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/.settings/org.eclipse.m2e.core.prefs?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/.settings/org.eclipse.m2e.core.prefs (added)
+++ jena/Experimental/sparql-cache/.settings/org.eclipse.m2e.core.prefs Wed Jan 30 19:02:32 2013
@@ -0,0 +1,5 @@
+#Wed Jan 04 11:26:41 GMT 2012
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

Added: jena/Experimental/sparql-cache/DEPENDENCIES
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/DEPENDENCIES?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/DEPENDENCIES (added)
+++ jena/Experimental/sparql-cache/DEPENDENCIES Wed Jan 30 19:02:32 2013
@@ -0,0 +1,2 @@
+Apache Jena - Apache License 2.0
+Googe Guava - Apache License 2.0

Added: jena/Experimental/sparql-cache/LICENCE
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/LICENCE?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/LICENCE (added)
+++ jena/Experimental/sparql-cache/LICENCE Wed Jan 30 19:02:32 2013
@@ -0,0 +1,224 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+- - - - - - - - - - - - - - - - - - - - - - - 
+
+==============================================================
+ Jetty Web Container
+ Copyright 1995-2012 Mort Bay Consulting Pty Ltd.
+==============================================================
+
+The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd
+unless otherwise noted.
+
+Jetty is dual licensed under both
+
+  * The Apache 2.0 License
+    http://www.apache.org/licenses/LICENSE-2.0.html
+
+      and
+
+  * The Eclipse Public 1.0 License
+    http://www.eclipse.org/legal/epl-v10.html
+
+Jetty may be distributed under either license.

Added: jena/Experimental/sparql-cache/NOTICE
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/NOTICE?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/NOTICE (added)
+++ jena/Experimental/sparql-cache/NOTICE Wed Jan 30 19:02:32 2013
@@ -0,0 +1,16 @@
+Apache Jena - module CacehSPARQL
+Copyright 2011-2013 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of this software were originally based on the following:
+  - Copyright 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP
+  - Copyright 2010, 2011 Epimorphics Ltd.
+  - Copyright 2010, 2011 Talis Systems Ltd.
+These have been licensed to the Apache Software Foundation under a software grant.
+
+- - - - - - - - - - - - - - - - - - - - - - - 
+
+Portions of this software include software from  Mort Bay Consulting Pty. Ltd.
+ - Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.

Added: jena/Experimental/sparql-cache/README.markdown
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/README.markdown?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/README.markdown (added)
+++ jena/Experimental/sparql-cache/README.markdown Wed Jan 30 19:02:32 2013
@@ -0,0 +1,9 @@
+This project is a collection of experimental concepts
+in the area of HTTP access to linked data.
+
+SPARQL caching: caching of SPARQL endpoints. 
+
+* simply request caching
+* rate control to limit unintended server overload
+* transcoding results from one format to another
+* pseudo paging via query analysis of ORDER BY / OFFSET / LIMIT access patterns.

Added: jena/Experimental/sparql-cache/http-delete
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/http-delete?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/http-delete (added)
+++ jena/Experimental/sparql-cache/http-delete Wed Jan 30 19:02:32 2013
@@ -0,0 +1,2 @@
+#!/bin/bash
+curl -X DELETE "$*"

Propchange: jena/Experimental/sparql-cache/http-delete
------------------------------------------------------------------------------
    svn:executable = *

Added: jena/Experimental/sparql-cache/http-get
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/http-get?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/http-get (added)
+++ jena/Experimental/sparql-cache/http-get Wed Jan 30 19:02:32 2013
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+wget -nv -O- "$@"

Propchange: jena/Experimental/sparql-cache/http-get
------------------------------------------------------------------------------
    svn:executable = *

Added: jena/Experimental/sparql-cache/http-post
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/http-post?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/http-post (added)
+++ jena/Experimental/sparql-cache/http-post Wed Jan 30 19:02:32 2013
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+wget -O- --post-data="" "$*"

Propchange: jena/Experimental/sparql-cache/http-post
------------------------------------------------------------------------------
    svn:executable = *

Added: jena/Experimental/sparql-cache/http-put
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/http-put?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/http-put (added)
+++ jena/Experimental/sparql-cache/http-put Wed Jan 30 19:02:32 2013
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+curl -T - "$@"
+

Propchange: jena/Experimental/sparql-cache/http-put
------------------------------------------------------------------------------
    svn:executable = *

Added: jena/Experimental/sparql-cache/log4j.properties
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/log4j.properties?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/log4j.properties (added)
+++ jena/Experimental/sparql-cache/log4j.properties Wed Jan 30 19:02:32 2013
@@ -0,0 +1,37 @@
+log4j.rootLogger=INFO, stdlog
+## log4j.rootLogger=INFO, FusekiFileLog
+
+log4j.appender.stdlog=org.apache.log4j.ConsoleAppender
+## log4j.appender.stdlog.target=System.err
+log4j.appender.stdlog.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdlog.layout.ConversionPattern=%d{HH:mm:ss} %-5p %-20c{1} :: %m%n
+
+## # Example for file logging.
+## log4j.appender.FusekiFileLog=org.apache.log4j.DailyRollingFileAppender
+## log4j.appender.FusekiFileLog.DatePattern='.'yyyy-MM-dd
+## log4j.appender.FusekiFileLog.File=fuseki-log
+## log4j.appender.FusekiFileLog.layout=org.apache.log4j.PatternLayout
+# Or %d{ISO8601}
+## log4j.appender.FusekiFileLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %-20c{1} :: %m%n
+
+# Jetty - Fuseki catches Jetty errors and reports them.
+log4j.logger.org.eclipse.jetty=FATAL
+
+# Execution logging
+log4j.logger.com.hp.hpl.jena.arq.info=INFO
+log4j.logger.com.hp.hpl.jena.arq.exec=INFO
+
+# Everything else in Jena
+log4j.logger.com.hp.hpl.jena=WARN
+log4j.logger.org.apache.jena=WARN
+log4j.logger.org.apache.jena.riot=INFO
+
+# Fuseki
+# Server log.
+log4j.logger.org.apache.jena.fuseki.Server=INFO
+# Request log.
+log4j.logger.org.apache.jena.fuseki.Fuseki=INFO
+# Internal logs
+log4j.logger.org.apache.jena.fuseki=INFO
+
+log4j.logger.org.apache.jena.sparqlcache=ALL
\ No newline at end of file

Added: jena/Experimental/sparql-cache/logging.properties
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/logging.properties?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/logging.properties (added)
+++ jena/Experimental/sparql-cache/logging.properties Wed Jan 30 19:02:32 2013
@@ -0,0 +1,6 @@
+# Java Logging
+
+handlers=org.apache.jena.atlas.logging.java.ConsoleHandlerStdout
+org.openjena.atlas.logging.java.ConsoleHandlerStdout.level=INFO
+org.openjena.atlas.logging.java.ConsoleHandlerStdout.formatter=org.apache.jena.atlas.logging.java.TextFormatter
+

Added: jena/Experimental/sparql-cache/pom.xml
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/pom.xml?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/pom.xml (added)
+++ jena/Experimental/sparql-cache/pom.xml Wed Jan 30 19:02:32 2013
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.jena</groupId>
+  <artifactId>server-thing</artifactId>
+  <packaging>jar</packaging>
+  <name>SPARQL-Cache</name>
+  <version>0.0.0-SNAPSHOT</version>
+  <description/>
+  <url>https://github.com/afs/SPARQL-Cache</url>
+
+  <organization>
+    <name>Apache Jena</name>
+    <url>http://incubator.apache.org/jena</url>
+  </organization>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0 License</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+    </license>
+  </licenses>
+
+  <scm>
+    <connection>git://github.com/afs/SPARQL-Cache.git</connection>
+    <url>https://github.com/afs/SPARQL-Cache</url>
+  </scm>
+
+  <properties>
+    <this.root>${project.artifactId}-${project.version}</this.root>
+
+    <ver.jena>2.10.0-SNAPSHOT</ver.jena>
+    <ver.arq>2.10.0-SNAPSHOT</ver.arq>
+    <ver.tdb>0.10.0-SNAPSHOT</ver.tdb>
+    <ver.fuseki>0.2.6-SNAPSHOT</ver.fuseki>
+    <ver.jetty>8.1.8.v20121106</ver.jetty>
+    <ver.junit>[4.9,)</ver.junit>
+    <ver.commonscodec>1.5</ver.commonscodec>
+    <ver.slf4j>1.6.4</ver.slf4j>
+    <ver.log4j>1.2.16</ver.log4j>
+    <ver.scala>[2.9.1,]</ver.scala>
+  </properties>
+
+  <dependencies>
+
+    <!-- Scala compiler acquired by the nature
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+      <version>${ver.scala}</version>
+    </dependency>
+    -->
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-tdb</artifactId>
+      <version>${ver.tdb}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-fuseki</artifactId>
+      <version>${ver.fuseki}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${ver.junit}</version>
+    </dependency>
+
+    <!--
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+      <version>${ver.jetty}</version>
+    </dependency>    
+
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
+      <version>${ver.jetty}</version>
+    </dependency>    
+
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-webapp</artifactId>
+      <version>${ver.jetty}</version>
+    </dependency>    
+    -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${ver.slf4j}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${ver.slf4j}</version>
+    </dependency>
+
+     <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jul-to-slf4j</artifactId>
+      <version>${ver.slf4j}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <version>${ver.slf4j}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- Needed if controlling logging in testing -->
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${ver.log4j}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.jms</groupId>
+          <artifactId>jms</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jdmk</groupId>
+          <artifactId>jmxtools</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jmx</groupId>
+          <artifactId>jmxri</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.mail</groupId>
+          <artifactId>mail</artifactId>
+        </exclusion>
+      </exclusions> 
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>[13.0.1.,)</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+	<version>2.4</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+
+      <!--
+      <plugin>
+        <groupId>org.scala-tools</groupId>
+        <artifactId>maven-scala-plugin</artifactId>
+
+        <configuration>
+          <jvmArgs>
+            <jvmArg>-Xmx1024m</jvmArg>
+          </jvmArgs>
+          <args>
+            <arg>-unchecked</arg>
+            <arg>-deprecation</arg>
+          </args>
+        </configuration> 
+
+        <executions>
+          <execution>
+            <id>scala-compile-first</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>add-source</goal>
+              <goal>compile</goal>
+            </goals>
+          </execution>                                                                  
+          <execution>
+            <id>scala-test-compile</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      -->
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+	<version>2.12</version>
+        <configuration>
+          <includes>
+            <include>**/TS_*.java</include>
+          </includes>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+	<version>2.4</version>
+        <configuration>
+          <overWriteReleases>false</overWriteReleases>
+          <overWriteIfNewer>true</overWriteIfNewer>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+	<version>2.5</version>
+        <configuration>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+
+    </plugins>
+
+    <pluginManagement>
+      <plugins>
+        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.scala-tools</groupId>
+                    <artifactId>
+                      maven-scala-plugin
+                    </artifactId>
+                    <versionRange>
+                      [2.15.2,)
+                    </versionRange>
+                    <goals>
+                      <goal>add-source</goal>
+                      <goal>compile</goal>
+                      <goal>testCompile</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+
+  </build>
+  
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>scala-tools.org</id>
+      <name>Scala-tools Maven2 Repository</name>
+        <url>http://scala-tools.org/repo-releases</url>
+    </pluginRepository>
+  </pluginRepositories>
+    
+  <repositories>
+    <repository>
+      <id>apache.snapshots</id>
+      <name>Apache Snapshot Repository</name>
+      <url>http://repository.apache.org/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository> 
+  </repositories>
+
+</project>

Added: jena/Experimental/sparql-cache/run
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/run?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/run (added)
+++ jena/Experimental/sparql-cache/run Wed Jan 30 19:02:32 2013
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+M2_REPO="${M2_REPO:-/home/afs/.m2/repo}"
+
+CP="$M2_REPO/org/apache/jena/jena-tdb/0.10.0-SNAPSHOT/jena-tdb-0.10.0-SNAPSHOT.jar:$M2_REPO/org/apache/jena/jena-arq/2.10.0-SNAPSHOT/jena-arq-2.10.0-SNAPSHOT.jar:$M2_REPO/commons-codec/commons-codec/1.5/commons-codec-1.5.jar:$M2_REPO/org/apache/httpcomponents/httpcore/4.2.3/httpcore-4.2.3.jar:$M2_REPO/org/apache/jena/jena-core/2.10.0-SNAPSHOT/jena-core-2.10.0-SNAPSHOT.jar:$M2_REPO/org/apache/jena/jena-iri/0.9.5-SNAPSHOT/jena-iri-0.9.5-SNAPSHOT.jar:$M2_REPO/xerces/xercesImpl/2.10.0/xercesImpl-2.10.0.jar:$M2_REPO/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar:$M2_REPO/org/apache/jena/jena-fuseki/0.2.6-SNAPSHOT/jena-fuseki-0.2.6-SNAPSHOT.jar:$M2_REPO/org/apache/httpcomponents/httpclient/4.2.2/httpclient-4.2.2.jar:$M2_REPO/commons-fileupload/commons-fileupload/1.2.2/commons-fileupload-1.2.2.jar:$M2_REPO/org/eclipse/jetty/jetty-server/8.1.8.v20121106/jetty-server-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/orbit/javax.servlet/3.0.0.v201112011016/javax.servlet-3.0.0.v201112011016
 .jar:$M2_REPO/org/eclipse/jetty/jetty-continuation/8.1.8.v20121106/jetty-continuation-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-http/8.1.8.v20121106/jetty-http-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-io/8.1.8.v20121106/jetty-io-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-servlet/8.1.8.v20121106/jetty-servlet-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-security/8.1.8.v20121106/jetty-security-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-servlets/8.1.8.v20121106/jetty-servlets-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-client/8.1.8.v20121106/jetty-client-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-util/8.1.8.v20121106/jetty-util-8.1.8.v20121106.jar:$M2_REPO/org/eclipse/jetty/jetty-xml/8.1.8.v20121106/jetty-xml-8.1.8.v20121106.jar:$M2_REPO/org/apache/velocity/velocity/1.7/velocity-1.7.jar:$M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar:$M2_REPO/commons-lang/commons-lang/2.4/
 commons-lang-2.4.jar:$M2_REPO/junit/junit/4.11/junit-4.11.jar:$M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:$M2_REPO/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4.jar:$M2_REPO/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.jar:$M2_REPO/org/slf4j/jul-to-slf4j/1.6.4/jul-to-slf4j-1.6.4.jar:$M2_REPO/org/slf4j/jcl-over-slf4j/1.6.4/jcl-over-slf4j-1.6.4.jar:$M2_REPO/log4j/log4j/1.2.16/log4j-1.2.16.jar:$M2_REPO/com/google/guava/guava/14.0-rc2/guava-14.0-rc2.jar"
+
+scala -cp "target/classes:$CP" dev.Main "$@"
\ No newline at end of file

Propchange: jena/Experimental/sparql-cache/run
------------------------------------------------------------------------------
    svn:executable = *

Added: jena/Experimental/sparql-cache/src/main/java/dev/Main.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/dev/Main.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/dev/Main.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/dev/Main.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,30 @@
+/*
+ * 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 dev
+
+import org.apache.jena.sparqlcache.SparqlCacheServer
+
+object Main {
+
+  def main(args: Array[String]): Unit = {
+    SparqlCacheServer.main(args)
+  }
+
+}
\ No newline at end of file

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/AServlet.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/AServlet.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/AServlet.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/AServlet.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,103 @@
+/*
+ * 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.atlas
+import javax.servlet.http.HttpServlet
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+
+/** Turn Java world into something a bit more Scala-ish. */
+abstract class AServlet extends HttpServlet {
+ 
+  val METHOD_PATCH = "PATCH" 
+  
+  override def doGet(request:HttpServletRequest, response:HttpServletResponse): Unit = {
+    val op = HttpOperation(request, response)
+    execGet(op)
+    }
+  
+  override def doPost(request:HttpServletRequest, response:HttpServletResponse) :Unit = {
+    val op = HttpOperation(request, response)
+    execPost(op)
+  }
+
+  //override def getLastModified(request: HttpServletRequest): Long = { -1 }
+  override def doHead(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+    val op = HttpOperation(request, response)
+    execHead(op)
+  }
+  
+  override def doPut(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+    val op = HttpOperation(request, response)
+    execPut(op)
+    
+  }
+  
+  override def doDelete(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+    val op = HttpOperation(request, response)
+    execDelete(op)
+    
+  }
+  
+  // Add PATCH
+  override def service(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+    if ( request.getMethod() == METHOD_PATCH )
+    {
+      doPatch(request, response)    
+      return
+    }
+    super.service(request, response)
+  }
+  
+  def doPatch(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+    val op = HttpOperation(request, response)
+    execPatch(op)
+  }
+  
+//  override def doOptions(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+//    val op = HttpOperation(request, response)
+//    execOptions(op)
+//  }
+  
+//  override def doTrace(request: HttpServletRequest, response: HttpServletResponse): Unit = {
+//    val op = HttpOperation(request, response)
+//    execOptions(op)
+//  }
+  
+  def execHead(op:HttpOperation) : Unit = { notSupported(op, "HEAD") }
+  
+  // You have to think about these
+  def execGet(op:HttpOperation) : Unit
+  def execPut(op:HttpOperation) : Unit
+  def execPost(op:HttpOperation) : Unit
+  def execDelete(op:HttpOperation) : Unit
+  
+  def execOptions(op:HttpOperation) :Unit = { notSupported(op, "OPTIONS") }
+  def execPatch(op:HttpOperation) : Unit =  { notSupported(op, "PATCH") }
+  
+  protected def notSupported(op:HttpOperation, method:String) = { 
+    val protocol = op.request.getProtocol();
+    val msg = "PATCH not supported" ;
+    if (protocol.endsWith("1.1")) {
+        op.response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+    } else {
+        op.response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+    }
+  }
+}
+  

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/Http.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/Http.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/Http.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/Http.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,84 @@
+/*
+ * 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.atlas
+
+/** Some HTTP support code */
+object Http extends SLog{
+
+  // HTTP SUPPORT -> elsewhere.  AServlet? object Http
+  def responseOK(op:HttpOperation) : Unit = {
+    op.response.setStatus(200)
+    op.response.flushBuffer()
+  }
+  
+  def badRequest(op:HttpOperation, msg:String)
+  {
+    bad(op, 400, msg)
+  }
+
+  def bad(op:HttpOperation, rc:Int, msg:String)
+  {
+    op.response.setStatus(rc)
+    op.response.setContentType("text/plain; charset=utf-8")
+    val out = op.response.getOutputStream()
+    out.println(msg)
+  }
+  
+  def notFound(op:HttpOperation, path:String)
+  {
+    INFO("Not found : %s", path)
+    logRequestDetails(op)
+
+    op.response.setStatus(404)
+    op.response.setContentType("text/plain; charset=utf-8")
+    
+    requestDetails(op)
+    op.response.getOutputStream().flush()
+  }
+  
+  def requestDetails(op:HttpOperation)
+  {
+    val containerName = op.request.getServletPath()
+    val entityName = op.uri
+    val relpath = op.uri.substring(containerName.length)
+    
+    val out = op.response.getOutputStream()
+    
+    out.println("Request URL  =  "+op.reqStringHost)
+    out.println("Request URI  =  "+op.reqString)
+    out.println("Container    =  "+containerName) ;
+    out.println("Entity       =  "+entityName) ;
+    out.println("RelPath      =  "+relpath) ;
+    out.println(op.params.toString())
+  }
+
+  def logRequestDetails(op:HttpOperation)
+  {
+    val containerName = op.request.getServletPath()
+    val entityName = op.uri
+    val relpath = op.uri.substring(containerName.length)
+    
+    INFO("Request URL  =  "+op.reqStringHost)
+    INFO("Request URI  =  "+op.reqString)
+    INFO("Container    =  "+containerName) ;
+    INFO("Entity       =  "+entityName) ;
+    INFO("RelPath      =  "+relpath) ;
+    INFO(op.params.toString())
+  }
+}
\ No newline at end of file

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/HttpOperation.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/HttpOperation.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/HttpOperation.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/HttpOperation.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,61 @@
+/*
+ * 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.atlas
+
+import javax.servlet.http.HttpServlet
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+
+class HttpOperation(val request:HttpServletRequest,  val response:HttpServletResponse) extends SLog
+{
+  val method = request.getMethod
+  val params = requestParams(request)
+  val uri = request.getRequestURI
+  private val x = request.getRequestURL.toString    // No query string.
+  
+  val tmp = if ( request.getQueryString == null ) "" else "?"+request.getQueryString
+  
+  val reqStringHost = x+tmp
+  val reqString     = uri+tmp
+  
+  override def toString:String = { return reqStringHost ; }
+  
+  //val z = request.getRequestURI
+  
+  INFO("URL = "+reqStringHost)
+  
+  // Only last seen param=value counts.
+  private def requestParams(request:HttpServletRequest):Map[String,String] = {
+    //    Hide old world.
+    // Assumes one mapping
+    val enum = request.getParameterNames()
+    val b = scala.collection.immutable.Map.newBuilder[String, String]
+    while(enum.hasMoreElements())
+    {
+      val pm:String = enum.nextElement().asInstanceOf[String]
+      val v = request.getParameterValues(pm).last
+      b += ((pm , v))
+    }
+    b.result
+  }
+}
+object HttpOperation
+{
+  def apply(request:HttpServletRequest, response:HttpServletResponse): HttpOperation = { return new HttpOperation(request, response) }
+}
\ No newline at end of file

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/JettyServer.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/JettyServer.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/JettyServer.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/JettyServer.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,55 @@
+/*
+ * 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.atlas
+import org.eclipse.jetty.server._
+import org.eclipse.jetty.server.nio.BlockingChannelConnector
+import org.eclipse.jetty.servlet._
+import org.eclipse.jetty.server.handler._
+import javax.servlet.http.HttpServlet
+
+class JettyServer(port:Int, servlets:(String, HttpServlet)*)
+{
+    val server = new Server();
+
+    val connector:Connector = new BlockingChannelConnector() // SelectChannelConnector
+    connector.setMaxIdleTime(0)             // Jetty outputs a lot of messages if this goes off.
+    connector.setPort(port)
+    server.addConnector(connector)
+    
+    val context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+    server.setHandler(context);  
+
+    for ( (spec, servlet) <- servlets )
+        addServlet(spec, servlet)
+
+    def start() = { server.start() ; }
+
+    private def addServlet(pathSpec:String, servlet:HttpServlet) = {
+        val holder = new ServletHolder(servlet) ;
+        context.addServlet(holder, pathSpec) ;
+    }
+    
+    def addStaticContent(pathSpec:String, base:String): Unit =
+    {
+        val staticServlet = new DefaultServlet()
+        val staticContent = new ServletHolder(staticServlet)
+        staticContent.setInitParameter("resourceBase", base)
+        context.addServlet(staticContent, pathSpec) ;
+  }
+}

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/SLog.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/SLog.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/SLog.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/atlas/SLog.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,49 @@
+/*
+ * 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.atlas
+
+/** Simple wrapper for logging - delays argument evaluation until needed */
+trait SLog
+{
+    org.apache.jena.atlas.logging.Log.setLog4j
+
+    val log = org.slf4j.LoggerFactory.getLogger(this.getClass) ;
+
+    // Choice:
+    // 1/ Use delayed args  (msg: => AnyRef) -- ugly if it pushed .format into app code
+    // 2/ Varargs
+    // Both!
+    
+    private def str(msg:String, args:Any*):String = {
+      if ( args.size == 0 ) return msg
+      msg.format(args:_*)
+    }
+    
+    def INFO(msg: => String, args:Any*):Unit = 
+    {
+        if ( log.isInfoEnabled )
+            log.info(str(msg, args:_*))
+    }
+
+    def DEBUG(msg: => String, args:Any*) : Unit =
+    {
+        if ( log.isDebugEnabled() )
+            log.debug(str(msg, args:_*))
+    }
+}

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/CacheFuture.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/CacheFuture.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/CacheFuture.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/CacheFuture.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,75 @@
+/*
+ * 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.sparqlcache
+import scala.actors.Futures
+
+object CacheFuture {
+  def main(args: Array[String]): Unit = {
+      
+    def creator(key:String):String = { return key.toUpperCase() }
+    val x = new CacheFuture[String, String](creator, 5)
+    
+    //val x = new CacheFutureA[String, String]()
+    
+    Console.println(x.get("Hello"))
+    Console.println(x.get("Hello"))
+    Console.println(x.get("Hello"))
+    Console.println(x.get("Goodbye"))
+  }
+}
+
+class CacheFuture[K,V] (creator: (K => V), poolSize:Int ) {
+    import java.util.concurrent._
+    import scala.collection.mutable.{Map=>MMap}
+
+    val map = MMap[K, Future[V]]()
+    val executor:ExecutorService = new ForkJoinPool(poolSize)
+
+    def get(key:K): V = {
+        map.synchronized[Future[V]] {
+            map.getOrElseUpdate(key, future(key))
+        }.get
+    }
+
+//     def get2(key:K): V = {
+//        map.synchronized[Future[V]] {
+//          // Avoid the function creation by future() until needed. 
+//          map.get(key) match { 
+//            case Some(x) => x
+//            // Create a task and future.
+//            case None =>
+//              // Create a task and future.
+//              val f = future(key)
+//              map.put(key, f)
+//              f }
+//        }.get
+//    }
+    
+    private def future(key:K):Future[V] = {
+        def task = new Callable[V] {
+            override def call:V = { return creator(key) } }
+        executor.submit(task)
+    }
+    
+    // Same but using actors.
+    private def futureA(key:K):scala.actors.Future[V] = {
+      Futures.future({ creator(key) }) 
+    }
+}
+

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/QueryEngineCaching.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/QueryEngineCaching.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/QueryEngineCaching.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/QueryEngineCaching.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,95 @@
+/*
+ * 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.sparqlcache
+
+import com.hp.hpl.jena.sparql.engine.binding.Binding
+import com.hp.hpl.jena.sparql.engine.QueryEngineBase
+import com.hp.hpl.jena.sparql.util.Context
+import com.hp.hpl.jena.sparql.core.DatasetGraph
+import com.hp.hpl.jena.sparql.algebra.Op
+import com.hp.hpl.jena.sparql.engine.QueryIterator
+import com.hp.hpl.jena.util.FileManager
+import com.hp.hpl.jena.query._
+import com.hp.hpl.jena.rdf.model.Model
+import java.util.concurrent.TimeUnit
+import org.apache.jena.atlas.lib.NotImplemented
+import com.hp.hpl.jena.sparql.graph.GraphFactory
+import com.hp.hpl.jena.sparql.engine.QueryExecutionBase
+import com.hp.hpl.jena.sparql.engine.QueryEngineFactory
+import com.hp.hpl.jena.sparql.engine.Plan
+import com.hp.hpl.jena.sparql.engine.QueryEngineRegistry
+
+abstract class QueryExecutionCaching extends QueryExecution {
+
+  // Better interface?
+  
+  // Use from Fuseki:
+  //   SPARQL_Query()
+  //     validate -> default
+  //     decideDataset -> null (not used)
+  //     createQueryExecution(Query, Dataset) -> this
+  //   or
+  //     validate
+  //     override executeQuery
+  
+  def execSelect(): ResultSet
+  def execAsk(): Boolean
+
+  def execConstruct(model: Model): Model = notImplemented
+  def execDescribe(model: Model): Model = notImplemented
+  def getContext(): Context
+
+  def execConstruct(): Model = execConstruct(GraphFactory.makeJenaDefaultModel())
+  def execDescribe(): Model = execDescribe(GraphFactory.makeJenaDefaultModel())
+  
+  def setFileManager(fileMgr: FileManager): Unit = notImplemented
+  def setInitialBinding(qs: QuerySolution): Unit = notImplemented 
+  def setTimeout(timeout: Long): Unit = notImplemented
+  def setTimeout(timeout1: Long, timeout2: Long): Unit = notImplemented
+  def setTimeout(timeout: Long, unit: TimeUnit): Unit = notImplemented
+  def setTimeout(timeout1: Long, unit1: TimeUnit, timeout2: Long, unit2: TimeUnit): Unit = notImplemented
+  
+  private def notImplemented() = throw new NotImplemented() ;
+}
+
+class QueryExecutionCaching2(query:Query , dataset:Dataset, context:Context, qeFactory:QueryEngineFactory) 
+    extends QueryExecutionBase(query, dataset, context, qeFactory) {
+  
+  // A SELECT query.
+  override def getPlan:Plan = throw new NotImplemented() ;
+}
+
+object QueryExecutionCachingSetup
+{
+    def init: Unit = {
+      val factory: QueryEngineFactory = new QueryEngineFactory() {
+        def accept(query:Query, dataset:DatasetGraph, context:Context): Boolean = { true }
+        def create(query:Query, dataset:DatasetGraph, inputBinding:Binding, context:Context):Plan = { null ; }
+        
+        def accept(op:Op, dataset:DatasetGraph, context:Context ):Boolean = { true }
+        def create(op:Op, dataset:DatasetGraph, inputBinding:Binding, context:Context):Plan = { null ; }
+      }
+
+      QueryEngineRegistry.addFactory(factory) 
+    }
+
+  
+}
+
+// Or from Fuseki, 
\ No newline at end of file

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/RS.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/RS.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/RS.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/RS.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,50 @@
+/*
+ * 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.sparqlcache
+import com.hp.hpl.jena.sparql.core.Var
+import com.hp.hpl.jena.sparql.engine.ResultSetStream
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterPlainWrapper
+import com.hp.hpl.jena.query.ResultSet
+import com.hp.hpl.jena.sparql.engine.binding.Binding
+
+class RS(val vars:List[Var], val rows:Array[Binding]) 
+ {
+    def toResultSet(): ResultSet = {
+      import scala.collection.JavaConversions._
+      val x = new QueryIterPlainWrapper(rows.iterator)
+      new ResultSetStream(Var.varNames(vars), null, x)
+    }
+}
+  
+object RS
+{
+    def apply(rs:RS, offset:Int, limit:Int):RS = {
+        new RS(rs.vars, rs.rows.slice(offset, (offset+limit)) )
+    }
+    
+    def apply(rows:ResultSet):RS = {
+        import com.hp.hpl.jena.sparql.engine.binding.BindingUtils
+        import scala.collection.JavaConversions._
+
+        val x : Array[Binding] = rows.map{BindingUtils.asBinding(_)}.toArray
+        val v = Var.varList(rows.getResultVars())
+        val vars:List[Var] = v.toList
+        return new RS(vars, x)
+    }
+}

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SPARQLResult.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SPARQLResult.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SPARQLResult.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SPARQLResult.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,58 @@
+/*
+ * 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.sparqlcache
+import com.hp.hpl.jena.query.ResultSet
+import com.hp.hpl.jena.graph.Graph
+
+// Like Option[] but 3 way.
+// Is there a better scala idiom?
+
+object SPARQLResult {
+    def apply(rs:ResultSet) = new SPARQLResultRS(rs)
+    def apply(bool:Boolean) = new SPARQLResultBoolean(bool)
+    def apply(graph:Graph) = new SPARQLResultGraph(graph)
+}
+
+class SPARQLResult()
+{
+    def resultSet():Option[ResultSet] = None
+    def boolean():Option[Boolean] = None
+    def graph():Option[Graph] = None
+    def get():Object = List(resultSet, graph, boolean) map { return _ }
+    
+    def isResultSet:Boolean = resultSet.isDefined 
+    def isBoolean:Boolean = boolean.isDefined
+    def isGraph:Boolean = graph.isDefined
+}
+
+class SPARQLResultRS(rs:ResultSet) extends SPARQLResult
+{
+  override def resultSet():Option[ResultSet] = Option(rs)
+}
+
+case class SPARQLResultBoolean(bool:Boolean) extends SPARQLResult
+{
+  override def boolean():Option[Boolean] = Option(bool)
+}
+
+case class SPARQLResultGraph(g:Graph) extends SPARQLResult
+{
+  override def graph():Option[Graph] = Option(g)
+}
+

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCache.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCache.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCache.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCache.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,251 @@
+/*
+ * 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.sparqlcache
+
+import java.net.URLEncoder
+import java.util.{HashMap => JHashMap}
+
+import scala.collection.JavaConversions.asJavaIterator
+import scala.collection.JavaConversions.asScalaBuffer
+import scala.collection.JavaConversions.asScalaIterator
+import scala.collection.JavaConversions.seqAsJavaList
+import scala.collection.mutable.{Map => MMap}
+
+import org.apache.jena.atlas.AServlet
+import org.apache.jena.atlas.HttpOperation
+import org.apache.jena.atlas.JettyServer
+import org.apache.jena.atlas.SLog
+import org.apache.jena.fuseki.servlets.ResponseResultSet
+import org.apache.jena.riot.web.HttpOp
+import org.apache.jena.riot.web.HttpResponseHandler
+import org.apache.jena.riot.web.HttpResponseLib
+import org.apache.jena.riot.WebContent
+
+import com.hp.hpl.jena.query.Query
+import com.hp.hpl.jena.query.QueryException
+import com.hp.hpl.jena.query.QueryFactory
+import com.hp.hpl.jena.query.ResultSet
+import com.hp.hpl.jena.query.ResultSetFormatter
+import com.hp.hpl.jena.sparql.core.Var
+import com.hp.hpl.jena.sparql.engine.binding.Binding
+import com.hp.hpl.jena.sparql.engine.binding.BindingUtils
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterPlainWrapper
+import com.hp.hpl.jena.sparql.engine.ResultSetStream
+import com.hp.hpl.jena.sparql.resultset.ResultsFormat
+
+
+class SparqlCache(remote:String) extends AServlet with SLog {
+  import com.hp.hpl.jena.query._
+  import java.util.concurrent.{ConcurrentMap => JConcurrentMap, ConcurrentHashMap => JConcurrentHashMap }
+  trait Chooser { def accept(query: Query): Option[Action] }
+  trait Action { def process(query: Query, op: HttpOperation): Unit }
+  
+  // -->CacheFuture
+  val queryCacheMap = MMap[Query, RS]()
+
+  protected trait DebugAction extends Action {
+    protected val msg: String
+    override def process(query: Query, op: HttpOperation): Unit = { println(msg) }
+  }
+
+  class ReplyResultSet(rs:RS) extends Action {
+    import org.apache.jena.fuseki.servlets.ResponseResultSet
+    def process(query: Query, op: HttpOperation): Unit = sendResultSet(rs.toResultSet, op)
+    
+    def foo() = remote
+  }
+  
+  class ReplyTextAction(rs: ResultSet) extends Action {
+    def process(query: Query, op: HttpOperation): Unit = {
+      import com.hp.hpl.jena.sparql.resultset.ResultsFormat
+      // Need mime type to ResultsFormat
+
+      // send reply as resultset
+      // Decide content type.
+      val ct = "application/sparql-results+json"
+      val rsType = ResultsFormat.FMT_RS_JSON
+
+      op.response.setHeader("Content-type", "ct");
+      op.response.setStatus(200)
+      val out = op.response.getOutputStream()
+      ResultSetFormatter.output(out, rs, rsType)
+      out.flush
+    }
+  }
+
+  object querySeenBefore extends Chooser with SLog {
+    override def accept(query: Query): Option[Action] = {
+      if (queryCacheMap.contains(query)) {
+        INFO("Answer from cache")
+        val rs:RS = queryCacheMap.get(query).get
+        //return Some(new ReplyTextAction(rs))
+        return Some(new ReplyResultSet(rs))
+      }
+      None
+    }
+  }
+  
+  /* This does not strip and issue a query if it has not been seen and it's LIMIT/OFFSET.
+   *  
+   */
+  object applySlice extends Chooser with SLog {
+    override def accept(query: Query): Option[Action] = {
+      
+      if (query.hasLimit() || query.hasOffset())
+      {
+        var limit = if ( query.hasLimit() ) query.getLimit().asInstanceOf[Int] else -1 
+        var offset = if ( query.hasOffset() ) query.getOffset().asInstanceOf[Int] else 0
+        
+        val query2:Query = query.cloneQuery()
+        query2.setLimit(Query.NOLIMIT)
+        query2.setOffset(Query.NOLIMIT)
+        
+        if (queryCacheMap.contains(query2)) {
+            val rs = queryCacheMap.get(query2).get
+            limit = if ( limit < 0 ) rs.rows.length else limit 
+            INFO("Answer from cache (%d,%d)", offset, limit)
+            val rs2 = RS(rs, offset, limit)
+            return Some(new ReplyResultSet(rs2))
+        }
+        
+      }
+      None
+    }
+  }
+  
+//  object orderLimit extends Chooser with DebugAction {
+//    val msg = "orderLimit"
+//    override def accept(query: Query) = {
+//      if (query.hasOrderBy && query.hasLimit && !query.hasOffset)
+//        Some(this)
+//      else
+//        None
+//    }
+//  }
+//
+//  object orderLimitOffset extends Chooser with DebugAction {
+//    val msg = "orderLimitOffset"
+//    override def accept(query:Query) = {
+//      if ( query.isSelectType && query.hasOrderBy && query.hasLimit && query.hasOffset )
+//        Some(this)
+//      else
+//        None
+//    }
+//  }
+
+  // This is a mess.
+  // We need to work consistently in Var/Binding space, or String/ResultSet space
+  // queryForReal has a conversion and we work in Var/Array[Binding] space
+  // Wrap in ResultSet engine to reuse Fuseki HTTP response. 
+
+  // ??Ideal: ARQ has a better (fixed) wrapping of results 
+  
+  
+  // Should be install in cache
+  object fillCache extends Chooser with Action with SLog {
+    override def accept(query: Query) = Some(this)
+
+    def process(query: Query, op: HttpOperation): Unit = {
+      INFO("Fill cache")
+      val rs = queryForReal(remote, query)
+      queryCacheMap.put(query, rs)
+      val action = new ReplyResultSet(rs)
+      action.process(query, op)
+    }
+  }
+
+  //val inspectors: List[Chooser] = List(orderLimit, orderLimitOffset, seenBefore, fillCache)
+  val inspectors: List[Chooser] = List(applySlice, querySeenBefore, fillCache)
+
+  override def execPut(op:HttpOperation) : Unit = { notSupported(op, "PUT") }
+  override def execDelete(op:HttpOperation) : Unit = { notSupported(op, "DELETE") }
+  
+  override def execGet(op: HttpOperation): Unit = exec(op)
+  override def execPost(op: HttpOperation): Unit = exec(op)
+
+  def exec(op: HttpOperation): Unit = {
+    // Check for default-graph-uri and named-graph-uri
+    // Check for other (non-std params).
+    val query =
+      try { QueryFactory.create(op.params.get("query").get) }
+      catch { case ex: QueryException => { op.response.sendError(400, "Bad query argument"); INFO(ex.getMessage); return } }
+    INFO(query.toString.replace("\n", " ").replaceAll(" +", " "))
+
+    // ** Start critical section
+    // get slot.
+    // lock on slot.
+    // do stuff
+    // ** end critical section
+    //http://www.scala-lang.org/node/6876
+    
+    
+    // .collect?
+    chooseAction(query) match {
+      case Some(action) => action.process(query, op); return
+      case None => INFO("No action")
+    }
+  }
+
+  // An action maybe somethign that needs to lock the cache slot.
+  // e.g. if fill cache, want every request on this slot to wait until filled. 
+  def chooseAction(query: Query): Option[Action] = {
+    def chooser(query: Query, list: List[Chooser]): Option[Action] = {
+      if (list == Nil) return None
+      list.head.accept(query) match { case Some(x) => return Some(x); case None => }
+      chooser(query, list.tail)
+    }
+
+    chooser(query, inspectors)
+  }
+  
+   def sendResultSet(rs:ResultSet, op: HttpOperation): Unit = {
+    import org.apache.jena.fuseki.servlets.ResponseResultSet
+    ResponseResultSet.doResponseResultSet(rs, null, op.request, op.response)
+  }
+
+  // SPARQLResult
+  
+  def queryForReal(destination: String, query: Query): RS = {
+
+    import java.net.URLEncoder
+    import java.util.{ Map => JMap, HashMap => JHashMap }
+
+    val handlers = new JHashMap[String, HttpResponseHandler]();
+    val captureRS = new HttpResponseLib.HttpCaptureResponseResultSet();
+    handlers.put(WebContent.contentTypeResultsXML, captureRS);
+    handlers.put(WebContent.contentTypeResultsJSON, captureRS);
+    handlers.put(WebContent.contentTypeTextTSV, captureRS);
+    val acceptables = "application/sparql-results+json;q=0.9 , application/sparql-results+xml;q=0.1"
+    val url = destination + "?query=" + URLEncoder.encode(query.toString, "UTF-8")
+      
+    INFO(url)
+    HttpOp.execHttpGet(url, acceptables, handlers)
+      
+    return RS(captureRS.get)
+  }
+
+  //      override def getLastModified(request:HttpServletRequest): Long = { -1 }
+  //      override def doHead(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def doPost(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def doPut(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def doDelete(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def doOptions(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def doTrace(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+  //      override def service(request:HttpServletRequest, response:HttpServletResponse) :Unit = {}
+}
\ No newline at end of file

Added: jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCacheServer.scala
URL: http://svn.apache.org/viewvc/jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCacheServer.scala?rev=1440588&view=auto
==============================================================================
--- jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCacheServer.scala (added)
+++ jena/Experimental/sparql-cache/src/main/java/org/apache/jena/sparqlcache/SparqlCacheServer.scala Wed Jan 30 19:02:32 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.sparqlcache
+import org.apache.jena.atlas.JettyServer
+import org.apache.jena.atlas.SLog
+
+object SparqlCacheServer extends SLog {
+
+  def main(args: Array[String]): Unit = {
+    org.apache.jena.atlas.logging.Log.setLog4j()
+    val server = new JettyServer(2010, 
+                 ("/", new SparqlCache("http://sparql.org/books/sparql"))
+                 )
+    //server.addStaticContent("/", "pages")
+    server.start()
+    INFO("running SPARQL cache")
+  }
+}
\ No newline at end of file