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 2012/08/16 15:04:52 UTC

svn commit: r1373816 [1/3] - in /jena/Experimental/riot-reader: ./ .settings/ src/ src/main/ src/main/java/ src/main/java/dev/ src/main/java/riot_reader/ src/main/java/riot_reader/fm2/ src/main/resources/ src/test/ src/test/java/ src/test/java/riot_rea...

Author: andy
Date: Thu Aug 16 13:04:49 2012
New Revision: 1373816

URL: http://svn.apache.org/viewvc?rev=1373816&view=rev
Log:
Initial codebase for a new reader sub-system for Jena.

Added:
    jena/Experimental/riot-reader/.classpath
    jena/Experimental/riot-reader/.project
    jena/Experimental/riot-reader/.settings/
    jena/Experimental/riot-reader/.settings/org.eclipse.core.resources.prefs
    jena/Experimental/riot-reader/.settings/org.eclipse.jdt.core.prefs
    jena/Experimental/riot-reader/.settings/org.eclipse.m2e.core.prefs
    jena/Experimental/riot-reader/pom.xml
    jena/Experimental/riot-reader/src/
    jena/Experimental/riot-reader/src/main/
    jena/Experimental/riot-reader/src/main/java/
    jena/Experimental/riot-reader/src/main/java/dev/
    jena/Experimental/riot-reader/src/main/java/dev/MainWebReader.java
    jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/
    jena/Experimental/riot-reader/src/main/java/riot_reader/HttpOp2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/Lang2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/Langs.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderFactoryRIOT.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT_ARP.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOT.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTBase.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTFactory.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/Registry2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStream2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStreamHttp.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/WebReader2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/FileManager2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/JenaIOEnvironment.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/LocationMapper.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/Locator.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/LocatorClassLoader.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/LocatorFile2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/LocatorURL2.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/LocatorZip.java
    jena/Experimental/riot-reader/src/main/java/riot_reader/fm2/StreamManager.java
    jena/Experimental/riot-reader/src/main/resources/
    jena/Experimental/riot-reader/src/test/
    jena/Experimental/riot-reader/src/test/java/
    jena/Experimental/riot-reader/src/test/java/riot_reader/
    jena/Experimental/riot-reader/src/test/java/riot_reader/TC_ReaderRIOT.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/TS_ReaderRIOT.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/TestFileManagerRIOT.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/TestJenaReaderRIOT.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/TestLangRIOT.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/TestReadDataset.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/TS_IO2.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/TestFileManager.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/TestLocationMapper.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/TestLocators.java
    jena/Experimental/riot-reader/src/test/java/riot_reader/fm2/TestStreamManager.java
    jena/Experimental/riot-reader/src/test/resources/
    jena/Experimental/riot-reader/testing/
    jena/Experimental/riot-reader/testing/RIOT/
    jena/Experimental/riot-reader/testing/RIOT/FileManager/
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.json
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.nq
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.nt
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.rdf
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.trig
    jena/Experimental/riot-reader/testing/RIOT/FileManager/D.ttl
    jena/Experimental/riot-reader/testing/RIOT/Reader/
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-json
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-no-base.rdf
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-no-base.ttl
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-not-TTL.ttl
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-nq
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-nt
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-rdf
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-trig
    jena/Experimental/riot-reader/testing/RIOT/Reader/D-ttl
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.json
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.nq
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.nt
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.rdf
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.trig
    jena/Experimental/riot-reader/testing/RIOT/Reader/D.ttl

Added: jena/Experimental/riot-reader/.classpath
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/.classpath?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/.classpath (added)
+++ jena/Experimental/riot-reader/.classpath Thu Aug 16 13:04:49 2012
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: jena/Experimental/riot-reader/.project
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/.project?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/.project (added)
+++ jena/Experimental/riot-reader/.project Thu Aug 16 13:04:49 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>riot-reader</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: jena/Experimental/riot-reader/.settings/org.eclipse.core.resources.prefs
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/.settings/org.eclipse.core.resources.prefs?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/.settings/org.eclipse.core.resources.prefs (added)
+++ jena/Experimental/riot-reader/.settings/org.eclipse.core.resources.prefs Thu Aug 16 13:04:49 2012
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8

Added: jena/Experimental/riot-reader/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/.settings/org.eclipse.jdt.core.prefs?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/.settings/org.eclipse.jdt.core.prefs (added)
+++ jena/Experimental/riot-reader/.settings/org.eclipse.jdt.core.prefs Thu Aug 16 13:04:49 2012
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6

Added: jena/Experimental/riot-reader/.settings/org.eclipse.m2e.core.prefs
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/.settings/org.eclipse.m2e.core.prefs?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/.settings/org.eclipse.m2e.core.prefs (added)
+++ jena/Experimental/riot-reader/.settings/org.eclipse.m2e.core.prefs Thu Aug 16 13:04:49 2012
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

Added: jena/Experimental/riot-reader/pom.xml
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/pom.xml?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/pom.xml (added)
+++ jena/Experimental/riot-reader/pom.xml Thu Aug 16 13:04:49 2012
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="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.
+-->
+
+<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>webreader</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-arq</artifactId>
+      <version>2.9.4-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-arq</artifactId>
+      <version>2.9.4-SNAPSHOT</version>
+      <classifier>tests</classifier>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.9</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.4</version>
+          <configuration>
+            <encoding>UTF-8</encoding>
+            <debug>true</debug>
+            <debuglevel>source,lines,vars</debuglevel>
+            <optimize>true</optimize>
+            <source>1.6</source>
+            <target>1.6</target>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+</project>
\ No newline at end of file

Added: jena/Experimental/riot-reader/src/main/java/dev/MainWebReader.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/dev/MainWebReader.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/dev/MainWebReader.java (added)
+++ jena/Experimental/riot-reader/src/main/java/dev/MainWebReader.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,78 @@
+/**
+ * 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.openjena.atlas.logging.Log ;
+import org.openjena.riot.WebContent ;
+import riot_reader.Langs ;
+import riot_reader.WebReader2 ;
+import riot_reader.fm2.FileManager2 ;
+
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+
+public class MainWebReader
+{
+    public static void main(String ... argv)
+    {
+        WebReader2.wireIntoJena() ;
+        Log.enable(WebReader2.class) ;
+
+        {
+            Model m = FileManager2.get().loadModel("http://jena.apache.org/about_jena/jena.rdf") ;
+            System.out.println(m.size()) ;
+        }
+        System.out.println("DONE") ;
+        System.exit(0) ;
+        
+        dwim("http://people.apache.org/~andy/RIOT-test/D.ttl") ;
+        dwim("http://people.apache.org/~andy/RIOT-test/D.nt") ;
+        dwim("http://people.apache.org/~andy/RIOT-test/D.rdf") ;
+        dwim("http://people.apache.org/~andy/RIOT-test/D.trig") ;
+        dwim("http://people.apache.org/~andy/RIOT-test/elephant") ;
+        
+        
+        
+        System.out.println("DONE") ;
+        System.exit(0) ;
+        
+        
+        
+        Model m = ModelFactory.createDefaultModel() ;
+        WebReader2.read(m, "http://localhost:3030/ds/data?default", Langs.nameToLang(WebContent.contentTypeTurtle), null) ;
+        WebReader2.read(m, "file:./D.ttl", null, null, null) ;
+        //SSE.write(m) ;
+        System.out.println("triples = "+m.size()) ;
+    }
+    
+    public static void dwim(String uri)
+    {
+        System.out.println(uri) ;
+        try {
+            Model m = ModelFactory.createDefaultModel() ;
+            m.read(uri) ;
+        } catch (RuntimeException ex)
+        {
+            System.out.flush() ;
+            ex.printStackTrace(System.err) ;
+        }
+        System.out.println() ;
+    }
+}
+

Added: jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java (added)
+++ jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,78 @@
+/**
+ * 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;
+
+public class PROJECT_RiotReader
+{
+    // ready to integrate
+    
+    // packaging:
+    // Datasets ... so in ARQ. 
+    
+    // Issue is RDFREader mode..read integration. 
+    
+    // WebReaderModel (no context) 
+    // WebReaderDataset (no context) 
+    
+    //  c.h.h.j.reader (understands Model and Dataset) 
+    //  o.oj.riot => o.a.j.riot
+    //  c.h.h.j.u for FileManager et al.
+    
+    // c.h.h.j.util.FileManager
+    // with compatibility for FileManager
+    
+    // Step 1 : 
+    // Type stream , FileManager
+    // Step 2 : reader
+    
+    // ****
+    // Testing (ready)
+    // 6 errors need changes to ModelCom to fix.
+    //    read_base_1  - ModelCom.read(url, base, lang) does : InputStream is = new URL( url ) .openStream() (no conneg)
+    //                        ==> WebReader2.read)
+    //    read_input_1 - lang not passed on ModelCom:  { readerFactory.getReader(lang) .read(this, reader, base); }
+    //    read_input_2 - same
+    //    read_30      - looses hint lang (could fix with per-lang readers but just use WebReader2.read) 
+    //    read_31      - looses hint lang (ditto)
+    //    read_32      - looses hint lang (ditto)
+    
+    /* read-30
+     * "D-not-TTL.ttl"
+     * m1.read(in.getInput(), null, "RDF/XML") ;
+     * ModelCom.read: readerFactory .getReader(lang) .read(this, reader, base);
+     *   => generic reader
+     *   but hint does not go to .read(this,reader,base)
+     *   ==> generic reader .getHint?
+     */
+
+    // Integration into Jena:
+    // Remove: RDFReaderF etc.
+    
+    // tests
+    // File extension and HTTP
+    // 303's
+    
+    // Lang/Lang2 :: Use of Lang as an enum in switch statements.
+    
+    // Update documentation
+    //  http://jena.apache.org/documentation/io/index.html
+    //  http://jena.apache.org/documentation/io/iohowto.html
+    //  http://jena.apache.org/documentation/io/riot.html
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/HttpOp2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/HttpOp2.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/HttpOp2.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/HttpOp2.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,115 @@
+/**
+ * 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 riot_reader;
+
+import static java.lang.String.format ;
+
+import java.io.IOException ;
+import java.util.concurrent.atomic.AtomicLong ;
+
+import org.apache.http.HttpEntity ;
+import org.apache.http.HttpResponse ;
+import org.apache.http.StatusLine ;
+import org.apache.http.client.HttpClient ;
+import org.apache.http.client.methods.HttpGet ;
+import org.apache.http.impl.client.DefaultHttpClient ;
+import org.openjena.atlas.io.IO ;
+import org.openjena.atlas.web.HttpException ;
+import org.openjena.atlas.web.MediaType ;
+import org.openjena.riot.web.HttpNames ;
+
+public class HttpOp2
+{
+
+    static private AtomicLong counter = new AtomicLong(0) ;
+
+    public static TypedInputStreamHttp execHttpGet(String url, String acceptHeader)
+    {
+        try {
+            long id = counter.incrementAndGet() ;
+            String requestURI = determineRequestURI(url) ;
+            String baseIRI = determineBaseIRI(requestURI) ;
+    
+            HttpGet httpget = new HttpGet(requestURI);
+            if ( WebReader2.log.isDebugEnabled() )
+                WebReader2.log.debug(format("[%d] %s %s",id ,httpget.getMethod(),httpget.getURI().toString())) ;
+            // Accept
+            if ( acceptHeader != null )
+                httpget.addHeader(HttpNames.hAccept, acceptHeader) ;
+            
+            // Execute
+            HttpClient httpclient = new DefaultHttpClient();        // Pool?
+            HttpResponse response = httpclient.execute(httpget) ;
+            
+            // Response
+            StatusLine statusLine = response.getStatusLine() ;
+            if ( statusLine.getStatusCode() >= 404 )
+            {
+                WebReader2.log.debug(format("[%d] %s %s",id, statusLine.getStatusCode(), statusLine.getReasonPhrase())) ;
+                return null ;
+            }
+            if ( statusLine.getStatusCode() >= 400 )
+            {
+                WebReader2.log.debug(format("[%d] %s %s",id, statusLine.getStatusCode(), statusLine.getReasonPhrase())) ;
+                throw new HttpException(statusLine.getStatusCode()+" "+statusLine.getReasonPhrase()) ;
+            }
+    
+            HttpEntity entity = response.getEntity() ;
+            if ( entity == null )
+            {
+                
+            }
+                
+            MediaType mt = MediaType.create(entity.getContentType().getValue()) ;
+            if ( WebReader2.log.isDebugEnabled() )
+                WebReader2.log.debug(format("[%d] %d %s :: %s",id, statusLine.getStatusCode(), statusLine.getReasonPhrase() , mt)) ;
+                
+            return new TypedInputStreamHttp(entity.getContent(), mt,
+                                       httpclient.getConnectionManager()) ;
+        }
+        catch (IOException ex) { IO.exception(ex) ; return null ; }
+    }
+
+    private static String determineRequestURI(String url)
+    {
+        String requestURI = url ;
+        if ( requestURI.contains("#") )
+        {
+            // No frag ids.
+            int i = requestURI.indexOf('#') ;
+            requestURI = requestURI.substring(0,i) ;
+        }
+        return requestURI ;
+    }
+
+    private static String determineBaseIRI(String requestURI)
+    {
+        // Technically wrong, but including the query string is "unhelpful"
+        String baseIRI = requestURI ;
+        if ( requestURI.contains("?") )
+        {
+            // No frag ids.
+            int i = requestURI.indexOf('?') ;
+            baseIRI = requestURI.substring(0,i) ;
+        }
+        return baseIRI ;
+    }
+
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/Lang2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/Lang2.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/Lang2.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/Lang2.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,79 @@
+/**
+ * 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 riot_reader;
+
+import org.openjena.atlas.web.ContentType ;
+
+
+public class Lang2 
+{
+    public static final Lang2 RDFXML    = Langs.langRDFXML ;
+    public static final Lang2 NTRIPLES  = Langs.langNTriples ;
+    public static final Lang2 N3        = Langs.langN3 ;
+    public static final Lang2 TURTLE    = Langs.langTurtle ;
+    public static final Lang2 RDFJSON   = Langs.langRDFJSON ;
+   
+    public static final Lang2 NQUADS    = Langs.langNQuads ;
+    public static final Lang2 TRIG      = Langs.langTriG ;
+    
+    private final String label ;
+    private final ContentType contentType ;
+
+    /** Create a language with a well-known name,
+     * All languages with the same name will be treated as the same language.
+     */
+    static public Lang2 create(String label, String mediaType)
+    {
+        return new Lang2(label, mediaType) ;
+    }
+    
+    protected Lang2(String label, String mediaType)
+    { 
+        if ( label == null )
+            throw new IllegalArgumentException("Null not allowed for language name") ;
+        else
+            label = label.intern();
+        this.label = label ;
+        this.contentType = mediaType==null ? null : ContentType.parse(mediaType) ;
+    }
+    
+    public boolean isTriples()  { return Langs.isTriples(this) ; }
+    public boolean isQuads()    { return Langs.isQuads(this) ; }
+    
+    @Override
+    public int hashCode() { return label.hashCode() ; } 
+
+    @Override
+    public boolean equals(Object other)
+    {
+        if ( this == other ) return true ;
+
+        if ( ! ( other instanceof Lang2 ) )
+            return false ;
+
+        Lang2 otherLang = (Lang2)other ;
+        return this.label == otherLang.label ; // String interning.
+    }
+
+    public String getName()             { return label ; }
+    public ContentType getContentType() { return contentType ; }
+    @Override
+    public String toString()  { return "Lang:"+label ; }
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/Langs.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/Langs.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/Langs.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/Langs.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,340 @@
+/**
+ * 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 riot_reader;
+
+import java.io.InputStream ;
+import java.util.Locale ;
+import java.util.Map ;
+
+import org.openjena.atlas.lib.DS ;
+import org.openjena.atlas.lib.MultiMap ;
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+import org.openjena.riot.Lang ;
+import org.openjena.riot.RiotException ;
+import org.openjena.riot.RiotReader ;
+import org.openjena.riot.WebContent ;
+import org.openjena.riot.lang.LangRIOT ;
+
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.util.FileUtils ;
+
+public class Langs
+{
+    // Constants and wiring. 
+
+    // Languages as constants.  
+    // Lang is an "open enum" (you can add your own),
+    // Registered with their MIME type or official name,
+    static Lang2 langRDFXML     = Lang2.create("RDF/XML",   WebContent.contentTypeRDFXML) ;
+    static Lang2 langTurtle     = Lang2.create("Turtle",    WebContent.contentTypeTurtle) ;
+    static Lang2 langNTriples   = Lang2.create("N-Triples", WebContent.contentTypeNTriplesAlt) ; // Exception: not text/plain.
+    static Lang2 langN3         = Lang2.create("N3",        WebContent.contentTypeN3) ;
+    static Lang2 langRDFJSON    = Lang2.create("RDF/JSON",  WebContent.contentTypeRDFJSON) ;
+    // JSON-LD
+    
+    static Lang2 langNQuads     = Lang2.create("NQuads",    WebContent.contentTypeNQuads) ;
+    static Lang2 langTriG       = Lang2.create("TriG",      WebContent.contentTypeTriG) ;
+
+    private static Map<Lang2, ReaderRIOTFactory<Triple>> langToTriples  = DS.map() ;
+    private static Map<Lang2, ReaderRIOTFactory<Quad>> langToQuads      = DS.map() ;
+    private static Map<String, Lang2> mapContentTypeToLang              = DS.map() ;
+    private static MultiMap<Lang2, String> langToExt                    = MultiMap.createMapList() ;
+    private static Map<String, Lang2> extToLang                         = DS.map() ;
+    private static Map<String, Lang2> shortNameToLang                   = DS.map() ;
+   
+    // This code understands different types of things it can read:
+    //   triples, quads, result sets, unknown
+    // These form (disjoint) value spaces static ReaderFactory<Triple> pfTriples = new ReaderFactory<Triple>() {
+    // This is needed because we need to determine the output type of the reading process.
+    // The decision is driven by the Content-Type.
+
+    // Triples : Generic parser factory.
+    static ReaderRIOTFactory<Triple> pfTriples = new ReaderRIOTFactory<Triple>() {
+        @Override
+        public ReaderRIOT<Triple> create(final Lang2 language)
+        {
+            return new ReaderRIOT<Triple>() {
+                // Needs sorting out
+                @Override
+                public void read(InputStream in, String baseURI, ContentType ct, Sink<Triple> sink, Context context)
+                {
+                    Lang lang = convert(language) ;
+                    LangRIOT parser = RiotReader.createParserTriples(in, lang, baseURI, sink) ;
+                    parser.parse() ;
+                }
+            } ;
+        }
+    } ;
+
+    // Quads : Generic parser factory.
+    static ReaderRIOTFactory<Quad> pfQuads = new ReaderRIOTFactory<Quad>() {
+        @Override
+        public ReaderRIOT<Quad> create(final Lang2 language)
+        {
+            return new ReaderRIOT<Quad>() {
+                // Needs sorting out
+                @Override
+                public void read(InputStream in, String baseURI, ContentType ct, Sink<Quad> sink, Context context)
+                {
+                    Lang lang = convert(language) ;
+                    LangRIOT parser = RiotReader.createParserQuads(in, lang, baseURI, sink) ;
+                    parser.parse() ;
+                }
+            } ;
+        }
+    } ;
+
+    static { initStandard(); }
+    
+    private static void addLangTriplesFactory$(Lang2 lang, ReaderRIOTFactory<Triple> factory)
+    {
+        langToTriples.put(lang, factory) ;
+    }
+        
+
+    private static void addLangQuadFactory$(Lang2 lang, ReaderRIOTFactory<Quad> factory)
+    {
+        langToQuads.put(lang, factory) ;
+    }
+    
+    /*package*/ static ReaderRIOTFactory<Triple> getFactoryTriples(Lang2 language)
+    {
+        return langToTriples.get(language) ;
+    }
+    
+    /*package*/ static ReaderRIOTFactory<Quad> getFactoryQuads(Lang2 language)
+    {
+        return langToQuads.get(language) ;
+    }
+
+    private static void registerShortNameForLang(String name, Lang2 lang)
+    {
+        shortNameToLang.put(lowerCase(name), lang) ;
+    }
+
+    /** Turn a short name for a language into a Lang object. 
+     */
+
+    private static Lang2 shortNameToLang(String name)
+    {
+        return shortNameToLang.get(lowerCase(name)) ;
+    }
+    
+    /** Turn a for a language into a Lang object.
+     *  The name can be a short form, or a content type.
+     */
+    public static Lang2 nameToLang(String langName)
+    { 
+        if ( langName == null )
+            return null ;
+        Lang2 lang = shortNameToLang(langName) ;
+        if ( lang != null )
+            return lang ;
+        lang = contentTypeToLang(langName) ;
+        return lang ;
+    }
+    
+    private static String lowerCase(String x) { return x.toLowerCase(Locale.US) ; }
+    
+    static void addTripleSyntax$(Lang2 language, String contentType, ReaderRIOTFactory<Triple> factory, String ... fileExt)
+    {
+        addTripleSyntax$(language, ContentType.parse(contentType), factory, fileExt) ;
+    }
+    
+    static void addTripleSyntax$(Lang2 language, ContentType contentType, ReaderRIOTFactory<Triple> factory, String ... fileExt)
+    { 
+        if ( fileExt != null )
+            extension(language, fileExt) ;
+        addLangTriplesFactory$(language, factory) ;
+        addContentTypeLang(contentType, language) ;
+    } 
+    
+    static void addQuadSyntax$(Lang2 language, String contentType, ReaderRIOTFactory<Quad> factory, String ... fileExt)
+    {
+        addQuadSyntax$(language, ContentType.parse(contentType), factory, fileExt) ;
+    }
+
+    static void addQuadSyntax$(Lang2 language, ContentType contentType, ReaderRIOTFactory<Quad> factory, String ... fileExt)
+    {
+        extension(language, fileExt) ;
+        addLangQuadFactory$(language, factory) ;
+        addContentTypeLang(contentType, language) ;
+    }
+    
+    private static void extension(Lang2 lang, String ... exts)
+    {
+        langToExt.putAll(lang, exts) ;
+        for ( String ext : exts )
+            extToLang.put(ext, lang) ;
+    }
+
+    // Initialize standard setup.
+    // In Webreader2?
+    private static void initStandard()
+    {
+        // RDF/XML
+        addTripleSyntax$(langRDFXML, WebContent.contentTypeRDFXML, pfTriples,       "rdf", "owl", "xml") ;
+        
+        // Turtle
+        addTripleSyntax$(langTurtle, WebContent.contentTypeTurtle, pfTriples,       "ttl") ;
+        addContentTypeLang$(WebContent.contentTypeTurtleAlt1, langTurtle) ;
+        addContentTypeLang$(WebContent.contentTypeTurtleAlt2, langTurtle) ;
+
+        // N-triples
+        addTripleSyntax$(langNTriples, WebContent.contentTypeNTriples, pfTriples,   "nt") ;
+        addContentTypeLang$(WebContent.contentTypeNTriplesAlt, langNTriples) ;
+        
+        // N3 (redirect to Turtle)
+        addTripleSyntax$(langN3, WebContent.contentTypeN3, pfTriples,               "n3") ;
+
+        // RDF/JSON (this is not JSON-LD)
+        addTripleSyntax$(langRDFJSON, WebContent.contentTypeRDFJSON, pfTriples,     "rj", "json") ;
+        
+        // TriG
+        addQuadSyntax$(langTriG, WebContent.contentTypeTriG, pfQuads,               "trig") ;
+        addContentTypeLang$(WebContent.contentTypeTriGAlt, langTriG) ;
+
+        // N-Quads
+        addQuadSyntax$(langNQuads, WebContent.contentTypeNQuads, pfQuads,           "nq") ;
+        addContentTypeLang$(WebContent.contentTypeNQuadsAlt, langNQuads) ;
+        
+        // Reader name and variations to lang - must include Jena old-name.
+        registerShortNameForLang("RDF/XML",         langRDFXML) ;
+        registerShortNameForLang("RDFXML",          langRDFXML) ;
+        registerShortNameForLang("RDF/XML-ABBREV",  langRDFXML) ;
+        
+        registerShortNameForLang("N-TRIPLE",        langNTriples) ;
+        registerShortNameForLang("N-TRIPLES",       langNTriples) ;
+        registerShortNameForLang("NTRIPLE",         langNTriples) ;
+        registerShortNameForLang("NTRIPLES",        langNTriples) ;
+        registerShortNameForLang("NT",              langNTriples) ;
+            
+        registerShortNameForLang("TURTLE",          langTurtle) ;
+        registerShortNameForLang("TTL",             langTurtle) ;
+
+        registerShortNameForLang("RDF/JSON",        langRDFJSON) ;
+        registerShortNameForLang("RDFJSON",         langRDFJSON) ;
+        
+        registerShortNameForLang("N-QUADS",         langNQuads) ;
+        registerShortNameForLang("NQUADS",          langNQuads) ;
+        registerShortNameForLang("N-QUAD",          langNQuads) ;
+        registerShortNameForLang("NQUAD",           langNQuads) ;
+        registerShortNameForLang("NQ",              langNQuads) ;
+            
+        registerShortNameForLang("TRIG",            langTriG) ;
+    }
+    
+    
+    private static void addContentTypeLang$(String contentType, Lang2 lang)
+    { addContentTypeLang(ContentType.parse(contentType), lang) ; }
+    
+    private static void addContentTypeLang(ContentType contentType, Lang2 lang)
+    { mapContentTypeToLang.put(contentType.getContentType(), lang) ; }
+    
+    static Lang2 contentTypeToLang(String contentType)
+    { return mapContentTypeToLang.get(contentType) ; }
+    
+    static Lang2 contentTypeToLang(ContentType contentType)
+    { return contentTypeToLang(contentType.getContentType()) ; }
+
+    // ** Lang upgrade.
+    
+    public static boolean isTriples(Lang2 lang) { return langToTriples.containsKey(lang) ; }
+    public static boolean isQuads(Lang2 lang)   { return langToQuads.containsKey(lang) ; }
+
+    
+    /** Guess the language, based on filename, or URL, extenstion.
+     * Returns null if there isn't a guess available
+     */
+    public static ContentType guessContentType(String filenameOrIRI)
+    {
+        Lang2 lang = guess(filenameOrIRI) ;
+        if ( lang == null ) return null ;
+        return lang.getContentType() ;
+    }
+
+    public static Lang2 guess(String resourceIRI)
+    {
+        if ( resourceIRI == null )
+            return null ;
+        String ext = FileUtils.getFilenameExt(resourceIRI).toLowerCase() ;
+        if ( ext != null && ext.equals("gz") )
+        {
+            resourceIRI = resourceIRI.substring(0, resourceIRI.length()-".gz".length()) ;
+            ext = FileUtils.getFilenameExt(resourceIRI).toLowerCase() ;
+        }
+
+        return extToLang.get(ext) ;
+    }
+    
+    //** Merge with Lang.guess
+    public static Lang2 guess(String resourceIRI, Lang2 dftLang)
+    {
+        Lang2 lang = guess(resourceIRI) ;
+        if ( lang == null ) return dftLang ;
+        return lang ;
+    }
+    
+    /** Attempt to guess the content type string from a language name */   
+    public static String shortNameToContentTypeStr(String jenaShortName)
+    {
+        return shortNameToContentTypeStr(jenaShortName, null) ;
+    }
+
+    /** Attempt to guess the content type string from a language name */   
+    public static String shortNameToContentTypeStr(String jenaShortName, String dft)
+    {
+        ContentType ct = shortNameToContentType(jenaShortName) ;
+        if ( ct == null )
+            return dft ;
+        return ct.getContentType() ;
+    }
+    
+    /** Attempt to guess the content type string from a language name */   
+    public static ContentType shortNameToContentType(String jenaShortName)
+    {
+        Lang2 lang = shortNameToLang(jenaShortName) ;
+        if ( lang == null )
+            return null ;
+        return lang.getContentType() ;
+    }
+
+//    /** Attempt to guess the content type string from a language name */   
+//    public static Lang2 jenaNameToLang(String jenaShortName)
+//    {
+//        return shortNameToLang.get(jenaShortName) ;
+//    }
+//
+    static Lang convert(Lang2 language)
+    {
+        if ( language == null ) throw new RiotException("Null language") ;
+        if ( language.equals(langRDFXML))     return Lang.RDFXML ;
+        if ( language.equals(langTurtle))     return Lang.TURTLE ;
+        if ( language.equals(langNTriples))   return Lang.NTRIPLES ;
+        if ( language.equals(langNQuads))     return Lang.NQUADS ;
+        if ( language.equals(langTriG))       return Lang.TRIG ;
+        if ( language.equals(langN3))         return Lang.N3 ;
+        if ( language.equals(langRDFJSON))    return Lang.RDFJSON ;
+        throw new RiotException("Can't convert: "+language) ;
+    }
+
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderFactoryRIOT.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderFactoryRIOT.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderFactoryRIOT.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderFactoryRIOT.java Thu Aug 16 13:04:49 2012
@@ -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 riot_reader;
+
+import org.openjena.riot.WebContent ;
+
+import com.hp.hpl.jena.rdf.model.RDFReader ;
+import com.hp.hpl.jena.rdf.model.RDFReaderF ;
+
+public class RDFReaderFactoryRIOT implements RDFReaderF
+{
+
+    // Map language to base.
+    // .. crudely ... 
+    
+    @Override
+    public RDFReader getReader()
+    {
+        return new RDFReaderRIOT() ;
+    }
+
+    @Override
+    public RDFReader getReader(String lang)
+    {
+        // If RDF/XML, then return an ARP 
+        if (WebContent.contentTypeRDFXML.equals(Langs.shortNameToContentType(lang)) )
+            return new RDFReaderRIOT_ARP() ;
+        
+        return new RDFReaderRIOT(lang) ; 
+    }
+
+    @Override
+    public String setReaderClassName(String lang, String className)
+    {
+        return null ;
+    }
+
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT.java Thu Aug 16 13:04:49 2012
@@ -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 riot_reader;
+
+import java.io.InputStream ;
+import java.io.Reader ;
+import java.util.Locale ;
+
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.RDFErrorHandler ;
+import com.hp.hpl.jena.rdf.model.RDFReader ;
+import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.sparql.util.Symbol ;
+
+/** Adapter from Jena2 original style adapter to RIOT reader. */ 
+public class RDFReaderRIOT implements RDFReader
+{
+    // See also JenaReaderBase, JenaReaderRiot
+
+    private final String base ; // This will be per reader instance.
+    private final String hintlang ;
+    Context context = new Context() ;
+    
+    RDFErrorHandler errorHandler = new RDFDefaultErrorHandler();
+    
+    public RDFReaderRIOT()
+    {
+        base = "org.apache.jena.lang.generic" ;
+        hintlang = null ;
+    }
+    
+    public RDFReaderRIOT(String lang)
+    {
+        base = "org.apache.jena.lang."+lang.toLowerCase(Locale.US) ;
+        hintlang = lang ;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void read(Model model, Reader r, String base)
+    { WebReader2.read(model, r, base, Langs.nameToLang(hintlang)) ; }
+
+    @Override
+    public void read(Model model, InputStream r, String base)
+    { WebReader2.read(model, r, base, Langs.nameToLang(hintlang)) ; }
+    
+    @Override
+    public void read(Model model, String url)
+    { WebReader2.read(model, url, Langs.nameToLang(hintlang)) ; }
+
+    @Override
+    public Object setProperty(String propName, Object propValue)
+    {
+        Symbol sym = Symbol.create(base+propName) ;
+        Object oldObj = context.get(sym) ;
+        return oldObj ;
+    }
+    
+    @Override
+    public RDFErrorHandler setErrorHandler(RDFErrorHandler errHandler)
+    {
+        RDFErrorHandler old = errorHandler ;
+        errorHandler = errHandler ;
+        return old ;
+    }
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT_ARP.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT_ARP.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT_ARP.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/RDFReaderRIOT_ARP.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,108 @@
+/**
+ * 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 riot_reader;
+
+import java.io.File ;
+import java.io.InputStream ;
+import java.io.Reader ;
+
+import com.hp.hpl.jena.rdf.arp.JenaReader ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.RDFErrorHandler ;
+import com.hp.hpl.jena.rdf.model.RDFReader ;
+import com.hp.hpl.jena.util.FileManager ;
+import com.hp.hpl.jena.util.FileUtils ;
+
+/** Adapter from Jena2 original style adapter for ARP - adds the file: */
+
+public class RDFReaderRIOT_ARP implements RDFReader
+{
+    // A FileManager sort out baseURIs for files.
+    static FileManager fileMgr = new FileManager() ;
+    static {
+        fileMgr.addLocatorFile() ;
+        fileMgr.addLocatorURL() ;
+    }
+    
+    JenaReader reader = new JenaReader() ;
+    
+    public RDFReaderRIOT_ARP() {}
+
+    @Override
+    public void read(Model model, Reader r, String base)
+    { reader.read(model, r, base) ; }
+
+    @Override
+    public void read(Model model, InputStream r, String base)
+    { reader.read(model, r, base) ; }
+    
+    @Override
+    public void read(Model model, String url)
+    {
+        String base = chooseBaseURI(url) ;
+        reader.read(model, base) ;
+    }
+
+    private static String chooseBaseURI(String baseURI)
+    {
+        String scheme = FileUtils.getScheme(baseURI) ;
+
+        if ( scheme != null )
+        {
+            if ( scheme.equals("file") )
+            {
+                if ( ! baseURI.startsWith("file:///") )
+                {
+                    try {
+                        // Fix up file URIs.  Yuk.
+                        String tmp = baseURI.substring("file:".length()) ;
+                        File f = new File(tmp) ;
+                        baseURI = "file:///"+f.getCanonicalPath() ;
+                        baseURI = baseURI.replace('\\','/') ;
+
+//                            baseURI = baseURI.replace(" ","%20");
+//                            baseURI = baseURI.replace("~","%7E");
+                        // Convert to URI.  Except that it removes ///
+                        // Could do that and fix up (again)
+                        //java.net.URL u = new java.net.URL(baseURI) ;
+                        //baseURI = u.toExternalForm() ;
+                    } catch (Exception ex) {}
+                }
+            }
+            return baseURI ;
+        }
+
+        if ( baseURI.startsWith("/") )
+            return "file://"+baseURI ;
+        return "file:"+baseURI ;
+    }
+
+    @Override
+    public Object setProperty(String propName, Object propValue)
+    {
+        return reader.setProperty(propName, propValue) ;
+    }
+    
+    @Override
+    public RDFErrorHandler setErrorHandler(RDFErrorHandler errHandler)
+    {
+        return reader.setErrorHandler(errHandler) ;
+    }
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOT.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOT.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOT.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOT.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,36 @@
+/**
+ * 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 riot_reader;
+
+import java.io.InputStream ;
+
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+
+import com.hp.hpl.jena.sparql.util.Context ;
+
+/** Interface to parsing processes that takes an input stream and emit T items.
+ *  The "read" operation may be called repeatedly for a single Reader, with different
+ *  arguments but calsl are not overlapping.
+ */
+
+public interface ReaderRIOT<T>
+{
+    public void read(InputStream in, String baseURI, ContentType ct, Sink<T> sink, Context context) ;
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTBase.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTBase.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTBase.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTBase.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,39 @@
+/*
+ * 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 riot_reader;
+
+import java.io.InputStream ;
+
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public abstract class ReaderRIOTBase<T> implements ReaderRIOT<T>
+{
+    @Override
+    public void read(InputStream in, String baseURI, ContentType ct, Sink<T> sink, Context context)
+    {
+        Lang2 lang = Langs.contentTypeToLang(ct) ;
+        read(in, baseURI,lang, sink, context) ;
+    }
+
+    public abstract void read(InputStream in, String baseURI, Lang2 lang, Sink<T> sink, Context context) ;
+}
+

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTFactory.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTFactory.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTFactory.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/ReaderRIOTFactory.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,24 @@
+/*
+ * 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 riot_reader;
+
+public interface ReaderRIOTFactory<T>
+{
+    public ReaderRIOT<T> create(Lang2 language) ;
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/Registry2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/Registry2.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/Registry2.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/Registry2.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,42 @@
+/**
+ * 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 riot_reader;
+
+import java.util.HashMap ;
+import java.util.Iterator ;
+import java.util.Map ;
+
+// ----- Copied from Fuseki migrate
+public class Registry2<T>
+{
+    protected Map<String, T> registry = new HashMap<String, T>() ;
+    
+    public Registry2() {}
+    
+    public void put(String key, T value) { registry.put(key, value) ; }
+    
+    public T get(String key) { return registry.get(key) ; }
+    
+    public boolean isRegistered(String key) { return registry.containsKey(key) ; }
+    public void remove(String key) { registry.remove(key) ; } 
+    public Iterator<String> keys() { return registry.keySet().iterator() ; }
+    
+    public int size() { return registry.size() ; }
+    public boolean isEmpty() { return registry.isEmpty() ; }
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStream2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStream2.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStream2.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStream2.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,57 @@
+/*
+ * 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 riot_reader;
+
+import java.io.InputStream;
+
+import org.openjena.atlas.io.IO ;
+import org.openjena.atlas.web.ContentType ;
+
+public class TypedInputStream2
+{ 
+    private InputStream input ;
+    private ContentType mediaType ;
+    // The URI to use when parsing.
+    // May be different from the URI used to access the resource 
+    // e.g. 303 redirection, mapped URI redirection 
+    private String baseURI ;
+    
+    public TypedInputStream2(InputStream in)
+    { this(in, null, null) ; }
+    
+    public TypedInputStream2(InputStream in, String mediaType, String charset, String baseURI)
+    {
+        this(in, ContentType.create(mediaType, charset), baseURI) ;
+    }
+    
+    public TypedInputStream2(InputStream in, ContentType ct, String baseURI)
+    {
+        this.input = in ;
+        this.mediaType = ct ;
+        this.baseURI = baseURI ;
+    }
+    
+    public InputStream getInput()           { return input ; }
+    public String getContentType()          { return mediaType == null ? null : mediaType.getContentType() ; }
+    public String getCharset()              { return mediaType == null ? null : mediaType.getCharset() ; }
+    public ContentType getMediaType()       { return mediaType ; }
+    public String getBaseURI()              { return baseURI ; }
+    
+    public void close()                     { IO.close(input) ; }
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStreamHttp.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStreamHttp.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStreamHttp.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/TypedInputStreamHttp.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,45 @@
+/**
+ * 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 riot_reader;
+
+import java.io.InputStream ;
+
+import org.apache.http.conn.ClientConnectionManager ;
+import org.openjena.atlas.web.MediaType ;
+
+/** Type streams for HTTP connections - includes Apache HTTP client specific cleanup */
+public class TypedInputStreamHttp extends TypedInputStream2 
+{
+    private ClientConnectionManager connectMgr ;
+
+    TypedInputStreamHttp(InputStream input, MediaType mt, ClientConnectionManager connectMgr)
+    {
+        super(input, mt.getContentType(), mt.getCharset(), null) ;
+        this.connectMgr = connectMgr ;
+    }
+    
+    @Override
+    public void close()
+    {
+        super.close() ;
+        if ( connectMgr != null )
+            connectMgr.shutdown() ;
+    }
+    
+}

Added: jena/Experimental/riot-reader/src/main/java/riot_reader/WebReader2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/riot_reader/WebReader2.java?rev=1373816&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/riot_reader/WebReader2.java (added)
+++ jena/Experimental/riot-reader/src/main/java/riot_reader/WebReader2.java Thu Aug 16 13:04:49 2012
@@ -0,0 +1,531 @@
+/**
+ * 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 riot_reader;
+
+import java.io.InputStream ;
+import java.io.Reader ;
+import java.io.StringReader ;
+
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+import org.openjena.riot.* ;
+import org.openjena.riot.lang.LangRDFXML ;
+import org.openjena.riot.lang.LangRIOT ;
+import org.openjena.riot.lang.SinkQuadsToDataset ;
+import org.openjena.riot.lang.SinkTriplesToGraph ;
+import org.openjena.riot.tokens.Tokenizer ;
+import org.openjena.riot.tokens.TokenizerFactory ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+import riot_reader.fm2.FileManager2 ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.query.Dataset ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.impl.RDFReaderFImpl ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.sparql.util.Symbol ;
+import com.hp.hpl.jena.sparql.util.Utils ;
+
+/** <p>General purpose reader framework for RDF (triples and quads) syntaxes.</p>   
+ *  <ul>
+ *  <li>HTTP Content negotiation</li>
+ *  <li>File type hint by the extension</li>
+ *  <li>Application language hint</li>
+ *  </ul>
+ * <p>
+ *  It also provide a way to lookup names in different
+ *  locations and to remap URIs to other URIs. 
+ *  </p>
+ *  <p>
+ *  Extensible - a new syntax can be added to the framework. 
+ *  </p>
+ */
+
+public class WebReader2
+{
+    /* Maybe:
+     * static for global (singleton) and locally tailored. 
+     */
+    
+    static Logger log = LoggerFactory.getLogger(WebReader2.class) ;
+    private static String riotBase = "http://jena.apache.org/riot/" ; 
+    private static String fileManagerSymbolStr = riotBase+"filemanager" ; 
+    public static Symbol fileManagerSymbol = Symbol.create(fileManagerSymbolStr) ; 
+
+    public static void wireIntoJena()
+    {
+        // Wire in generic 
+        String readerRDF = RDFReaderRIOT.class.getName() ;
+        RDFReaderFImpl.setBaseReaderClassName("RDF/XML",    readerRDF) ;           // And default
+        RDFReaderFImpl.setBaseReaderClassName("RDF/XML-ABBREV", readerRDF) ;
+
+        RDFReaderFImpl.setBaseReaderClassName("N-TRIPLES",  readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("N-TRIPLE",   readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("N3",         readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("TURTLE",     readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("Turtle",     readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("TTL",        readerRDF) ;
+        RDFReaderFImpl.setBaseReaderClassName("RDF/JSON",   readerRDF) ;
+    }
+    
+    public static void resetJenaReaders()
+    {
+        SysRIOT.resetJenaReaders() ;
+    }
+    
+    /** Read triples into a Model from the given location. 
+     *  The synatx is detemined from input source URI (content negotiation or extension). 
+     * @see #read(Model,String,Lang2,Context) 
+     * @param model Destination for the RDF read.
+     * @param uri   URI to read from (includes file: and a plain file name).
+     */
+    public static void read(Model model, String uri)                    { read(model, uri, null, null, null) ; }
+    
+    /** Read triples into a Model from the given location, with a hint of the language (MIME type) 
+     * @see #read(Model,String,String,Lang2,Context) 
+     * @param model     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Hint for the syntax.
+     */
+    public static void read(Model model, String uri, Lang2 hintLang)   { read(model, uri, hintLang, null) ; }
+    
+    /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader 
+     * @see #read(Model,String,String,Lang2,Context) 
+     * Throws parse errors depending on the language and reader; the Model model may be partially updated.
+     * @param model     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param base      Base URI (defaults to uri).
+     * @param hintLang  Hint for the syntax
+     * @throws RiotNotFoundException if the location is not found - the model is unchanged.
+     */
+    public static void read(Model model, String uri, String base, Lang2 hintLang) { read(model, uri, base, hintLang, null) ; }
+    
+    /** Read triples into a Model from the given location, with some parameters for the reader
+     * @see #read(Model,String,String,Lang2,Context) 
+     * @param model     Destination for the RDF read
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param context   Content object to control reading process.
+     */ 
+    public static void read(Model model, String uri, Context context)   { read(model, uri, null, context) ; }
+    
+    /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader 
+     * @see #read(Model,String,String,Lang2,Context) 
+     * @param model     Destination for the RDF read
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+    */
+    public static void read(Model model, String uri, Lang2 hintLang, Context context)
+    {
+        read(model, uri, uri, hintLang, context) ;
+    }
+    
+    /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader 
+     * Throws parse errors depending on the language and reader; the Model model may be partially updated.
+     * @param model     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param base      Base URI (defaults to uri).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+     * @throws RiotNotFoundException if the location is not found - the model is unchanged.
+     */
+    public static void read(Model model, String uri, String base, Lang2 hintLang, Context context)
+    {
+        Graph g = model.getGraph() ;
+        Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+        readTriples(sink, uri, base, hintLang, context) ;
+    }
+
+    /** Read triples into a Model with bytes from an InputStream.
+     *  A base URI and a syntax can be provided.
+     *  The base URI defualts to "no base" in which case the data should have no relative URIs.
+     *  The lang gives the syntax of the stream. 
+     * @param model     Destination for the RDF read.
+     * @param in        InputStream
+     * @param lang      Language syntax
+     */
+
+    public static void read(Model model, InputStream in, Lang2 lang)
+    {
+        read(model, in, null, lang) ;
+    }
+        
+    /** Read triples into a Model with bytes from an InputStream.
+     *  A base URI and a syntax can be provided.
+     *  The base URI defualts to "no base" in which case the data should have no relative URIs.
+     *  The lang gives the syntax of the stream. 
+     * @param model     Destination for the RDF read.
+     * @param in        InputStream
+     * @param base      Base URI 
+     * @param lang      Language syntax
+     */
+    public static void read(Model model, InputStream in, String base, Lang2 lang)
+    {
+        Graph g = model.getGraph() ;
+        Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+        processTriples(sink, base, new TypedInputStream2(in), lang, null) ;
+    }
+
+    /** Read triples into a model with chars from an Reader.
+     * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+     * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+     * @deprecated Use an InputStream or StringReader.
+     * @param model     Destination for the RDF read.
+     * @param in        Reader
+     * @param base      Base URI 
+     * @param lang      Language syntax
+     */
+    @Deprecated
+    public static void read(Model model, Reader in, String base, Lang2 lang)
+    {
+        Graph g = model.getGraph() ;
+        Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+        processTriples(sink, base, in, lang, null) ;
+    }
+
+    /** Read triples into a model with chars from a StringReader.
+     * @param model     Destination for the RDF read.
+     * @param in        InputStream
+     * @param base      Base URI 
+     * @param lang      Language syntax
+     */
+    public static void read(Model model, StringReader in, String base, Lang2 lang)
+    {
+        Graph g = model.getGraph() ;
+        Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+        processTriples(sink, base, in, lang, null) ;
+    }
+
+    
+    /** Read quads into a Dataset from the given location, with hint of langauge.
+     * @see #read(Dataset, String, String, Lang2, Context) 
+     * @param dataset   Destination
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Language syntax
+     */
+    public static void read(Dataset dataset, String uri, Lang2 hintLang)
+    {
+        read(dataset, uri, hintLang, null) ;
+    }
+
+    /** Read quads or triples into a Dataset from the given location. 
+     * @see #read(Dataset, String, String, Lang2, Context) 
+     * @param dataset   Destination
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Language syntax
+     */
+    public static void read(Dataset dataset, String uri, Lang2 hintLang, Context context)
+    {
+        read(dataset, uri, uri, hintLang, context) ;
+    }
+    
+    /** Read quads or triples into a Dataset from the given location.
+     * @see #read(Dataset, String, String, Lang2, Context) 
+     * @param dataset   Destination
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Language syntax
+    *  @throws RiotNotFoundException if the location is not found - the model is unchanged.
+    *  Throws parse errors depending on the language and reader; the Model model may be partially updated. 
+    */ 
+
+    public static void read(Dataset dataset, String uri, String base, Lang2 hintLang, Context context)
+    {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+        readQuads(sink, uri, base, hintLang, context) ;
+    }
+
+    /** Read quads or triples into a dataset with bytes from an input stream.
+     * @param dataset   Destination
+     * @param in        InputStream
+     * @param lang      Language syntax
+     */
+    public static void read(Dataset dataset, InputStream in, Lang2 lang)
+    {
+        read(dataset, in, null, lang) ;
+    }
+    
+    /** Read quads or triples into a dataset with bytes from an input stream.
+     * @param dataset   Destination
+     * @param in        InputStream
+     * @param base      Base URI
+     * @param lang      Language syntax
+     */
+    public static void read(Dataset dataset, InputStream in, String base, Lang2 lang)
+    {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+        processQuads(sink, base, new TypedInputStream2(in), lang, null) ;
+    }
+    
+    /** Read quads into a dataset with chars from an Reader.
+     * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+     * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+     * @param dataset   Destination
+     * @param in        InputStream
+     * @param base      Base URI
+     * @param lang      Language syntax
+     * @deprecated use an InputStream or a Stringreader.
+     */
+    @Deprecated
+    public static void read(Dataset dataset, Reader in, String base, Lang2 lang)
+    {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+        processQuads(sink, base, in, lang, null) ;
+    }
+
+    /** Read quads into a dataset with chars from a StringReader.
+     * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+     * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+     * @param dataset   Destination
+     * @param in        InputStream
+     * @param base      Base URI
+     * @param lang      Language syntax
+     */
+    public static void read(Dataset dataset, StringReader in, String base, Lang2 lang)
+    {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+        processQuads(sink, base, in, lang, null) ;
+    }
+
+//    public static void addTripleSyntax(Lang2 language, ContentType contentType, ReaderRIOTFactory<Triple> factory, String ... fileExt )
+//    { 
+//        Langs.addTripleSyntax$(language, contentType, factory, fileExt) ;
+//    } 
+//    
+//    public static void addQuadSyntax(Lang2 language, ContentType contentType, ReaderRIOTFactory<Quad> factory, String ... fileExt )
+//    {
+//        Langs.addQuadSyntax$(language, contentType, factory, fileExt) ;
+//    }
+    
+    /** Read triples - send to a sink.
+     * @param sink     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+     */
+    public static void readTriples(Sink<Triple> sink, String uri, Lang2 hintLang, Context context)
+    {
+        readTriples(sink, uri, uri, hintLang, context) ;
+    }
+    
+    /** Read triples - send to a sink.
+     * @param sink     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param base      Base URI (defaults to uri).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+     */
+    public static void readTriples(Sink<Triple> sink, String uri, String base, Lang2 hintLang, Context context)
+    {
+        TypedInputStream2 in = open(uri, context) ;
+        if ( in == null )
+            throw new RiotException("Not found: "+uri) ;
+        processTriples(sink, base, in, hintLang, context) ;
+        in.close() ;
+    }
+    
+    /** Read quads - send to a sink.
+     * @param sink     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+     */
+    public static void readQuads(Sink<Quad> sink, String uri, Lang2 hintLang, Context context)
+    {
+        readQuads(sink, uri, uri, hintLang, context) ;
+    }
+
+    /** Read quads - send to a sink.
+     * @param sink     Destination for the RDF read.
+     * @param uri       URI to read from (includes file: and a plain file name).
+     * @param base      Base URI (defaults to uri).
+     * @param hintLang  Hint for the syntax
+     * @param context   Content object to control reading process.
+     */
+    public static void readQuads(Sink<Quad> sink, String uri, String base, Lang2 hintLang, Context context)
+    {
+        TypedInputStream2 in = open(uri, context) ;
+        if ( in == null )
+            throw new RiotException("Not found: "+uri) ;
+        processQuads(sink, base, in, hintLang, context) ;
+        in.close() ;
+    }
+
+    /** Open a stream to the destination (URI or filename)
+     * Performs content negotition, including looking at file extension. 
+     */
+    public static TypedInputStream2 open(String filenameOrURI)
+    { return open(filenameOrURI, (Context)null) ; }
+    
+    /** Open a stream to the destination (URI or filename)
+     * Performs content negotition, including looking at file extension. 
+     */
+    public static TypedInputStream2 open(String filenameOrURI, Context context)
+    {
+        FileManager2 fMgr = FileManager2.get() ;
+        if ( context != null )
+        {
+            try { fMgr = (FileManager2)context.get(fileManagerSymbol, context) ; }
+            catch (ClassCastException ex) 
+            { log.warn("Context symbol '"+fileManagerSymbol+"' is not a "+Utils.classShortName(FileManager2.class)) ; }
+        }
+        
+        return open(filenameOrURI, fMgr) ;
+    }
+    
+    private static TypedInputStream2 open(String filenameOrURI, FileManager2 fMgr)
+    {
+        TypedInputStream2 in = fMgr.open(filenameOrURI) ;
+            
+        if ( in == null )
+        {
+            if ( log.isDebugEnabled() )
+                //log.debug("Found: "+filenameOrURI+" ("+loc.getName()+")") ;
+                log.debug("Not Found: "+filenameOrURI) ;
+            throw new RiotNotFoundException("Not found: "+filenameOrURI) ;
+            //return null ;
+        }
+        if ( log.isDebugEnabled() )
+            //log.debug("Found: "+filenameOrURI+" ("+loc.getName()+")") ;
+            log.debug("Found: "+filenameOrURI) ;
+        return in ;
+    }
+    
+    // ----- 
+    // Readers are algorithms and must be stateless (or they must create a per run
+    // instance of something) because they may be called concurrency from different threads.
+    // The Context Readerobject gives the per-run configuration.  
+    
+    // Alternative: A two step factory-instance design means
+    // readers can be created and passed around (e,.g. to set specific features)
+    // We could have had two step design - ReaderFactory-ReaderInstance
+    // no - put the bruden on complicated readers, not everyone. 
+    
+    private static void processTriples(Sink<Triple> sink, String baseUri, TypedInputStream2 in, Lang2 hintLang, Context context)
+    {
+        ContentType ct = determineCT(baseUri, in.getContentType(), hintLang ) ;
+        
+        if ( ct == null )
+            throw new RiotException("Failed to determine the triples content type: (URI="+baseUri+" : stream="+in.getContentType()+" : hint="+hintLang+")") ;
+
+        ReaderRIOT<Triple> reader = getReaderTriples(ct) ;
+        if ( reader == null )
+            throw new RiotException("No triples reader for content type: "+ct.getContentType()) ;
+        
+        reader.read(in.getInput(), baseUri, ct, sink, context) ;
+    }
+
+    private static ReaderRIOT<Triple> getReaderTriples(ContentType ct)
+    {
+        Lang2 lang = Langs.contentTypeToLang(ct) ;
+        ReaderRIOTFactory<Triple> r = Langs.getFactoryTriples(lang) ;
+        if ( r == null )
+            return null ;
+        return r.create(lang) ;
+    }
+
+    // java.io.Readers are NOT preferred.
+    @SuppressWarnings("deprecation")
+    private static void processTriples(Sink<Triple> sink, String base, Reader in, Lang2 hintLang, Context context)
+    {
+        // Not as good as from an InputStream - RDF/XML not supported 
+        ContentType ct = determineCT(base, null, hintLang) ;
+        if ( ct == null )
+            throw new RiotException("Failed to determine the triples content type: (URI="+base+" : hint="+hintLang+")") ;
+        
+        Tokenizer tokenizer = TokenizerFactory.makeTokenizer(in) ;
+        if ( hintLang == null )
+            throw new RiotException("No language specificied") ;
+        Lang lang = Langs.convert(hintLang) ;
+        LangRIOT parser ;
+        if ( lang == Lang.RDFXML )
+            parser = LangRDFXML.create(in, base, base, ErrorHandlerFactory.errorHandlerStd, sink) ;
+        else
+            parser = RiotReader.createParserTriples(tokenizer, lang, base, sink) ;
+        parser.parse() ;
+    }
+    
+    private static void processQuads(Sink<Quad> sink, String uri, TypedInputStream2 in, Lang2 hintLang, Context context)
+    {
+        ContentType ct = determineCT(uri, in.getContentType(), hintLang ) ;
+        if ( ct == null )
+            throw new RiotException("Failed to determine the quads content type: (URI="+uri+" : stream="+in.getContentType()+" : hint="+hintLang+")") ;
+        ReaderRIOT<Quad> reader = getReaderQuads(ct) ;
+        if ( reader == null )
+            throw new RiotException("No quads reader for content type: "+ct) ;
+        
+        reader.read(in.getInput(), uri, ct, sink, context) ;
+    }
+
+    private static ReaderRIOT<Quad> getReaderQuads(ContentType ct)
+    {
+        Lang2 lang = Langs.contentTypeToLang(ct) ;
+        ReaderRIOTFactory<Quad> r = Langs.getFactoryQuads(lang) ;
+        if ( r == null )
+            return null ;
+        return r.create(lang) ;
+    }
+    
+    // java.io.Readers are NOT preferred.
+    private static void processQuads(Sink<Quad> sink, String base, Reader in, Lang2 hintLang, Context context)
+    {
+        Tokenizer tokenizer = TokenizerFactory.makeTokenizer(in) ;
+        Lang lang = Langs.convert(hintLang) ;
+        LangRIOT parser = RiotReader.createParserQuads(tokenizer, lang, base, sink) ;
+        parser.parse() ;
+    }
+
+    private static ContentType determineCT(String target, String ctStr, Lang2 hintLang)
+    {
+        if ( ctStr != null )
+            ctStr = WebContent.contentTypeCanonical(ctStr) ;
+        
+        boolean isTextPlain = WebContent.contentTypeTextPlain.equals(ctStr) ;
+        ContentType ct = (ctStr==null) ? null : ContentType.parse(ctStr) ;
+        
+        // It's it's text plain, we ignore it because a lot of naive
+        // server setups return text/plain for any file type.
+        
+        if ( ct == null || isTextPlain )
+        {
+            if ( hintLang == null )
+                ct = Langs.guessContentType(target) ;
+            else
+            {
+                ct = hintLang.getContentType() ;
+//                if ( ct == null )
+//                {
+//                    // Is the hint a content type?
+//                    Lang2 lang = Langs.contentTypeToLang(hintLang) ;
+//                    if ( lang != null )
+//                        ct = lang.getContentType() ;
+//                }
+            }
+        }
+        return ct ;
+    }
+}
+